1: <?php
2: 3: 4: 5: 6: 7: 8:
9:
10: define('FPDF_VERSION','1.7');
11:
12: class FPDF
13: {
14: public $page;
15: public $n;
16: public $offsets;
17: public $buffer;
18: public $pages;
19: public $state;
20: public $compress;
21: public $k;
22: public $DefOrientation;
23: public $CurOrientation;
24: public $StdPageSizes;
25: public $DefPageSize;
26: public $CurPageSize;
27: public $PageSizes;
28: public $wPt, $hPt;
29: public $w, $h;
30: public $lMargin;
31: public $tMargin;
32: public $rMargin;
33: public $bMargin;
34: public $cMargin;
35: public $x, $y;
36: public $lasth;
37: public $LineWidth;
38: public $fontpath;
39: public $CoreFonts;
40: public $fonts;
41: public $FontFiles;
42: public $diffs;
43: public $FontFamily;
44: public $FontStyle;
45: public $underline;
46: public $CurrentFont;
47: public $FontSizePt;
48: public $FontSize;
49: public $DrawColor;
50: public $FillColor;
51: public $TextColor;
52: public $ColorFlag;
53: public $ws;
54: public $images;
55: public $PageLinks;
56: public $links;
57: public $AutoPageBreak;
58: public $PageBreakTrigger;
59: public ;
60: public ;
61: public $ZoomMode;
62: public $LayoutMode;
63: public $title;
64: public $subject;
65: public $author;
66: public $keywords;
67: public $creator;
68: public $AliasNbPages;
69: public $PDFVersion;
70:
71: 72: 73: 74: 75:
76: function FPDF($orientation='P', $unit='mm', $size='A4')
77: {
78:
79: $this->_dochecks();
80:
81: $this->page = 0;
82: $this->n = 2;
83: $this->buffer = '';
84: $this->pages = array();
85: $this->PageSizes = array();
86: $this->state = 0;
87: $this->fonts = array();
88: $this->FontFiles = array();
89: $this->diffs = array();
90: $this->images = array();
91: $this->links = array();
92: $this->InHeader = false;
93: $this->InFooter = false;
94: $this->lasth = 0;
95: $this->FontFamily = '';
96: $this->FontStyle = '';
97: $this->FontSizePt = 12;
98: $this->underline = false;
99: $this->DrawColor = '0 G';
100: $this->FillColor = '0 g';
101: $this->TextColor = '0 g';
102: $this->ColorFlag = false;
103: $this->ws = 0;
104:
105: if(defined('FPDF_FONTPATH'))
106: {
107: $this->fontpath = FPDF_FONTPATH;
108: if(substr($this->fontpath,-1)!='/' && substr($this->fontpath,-1)!='\\')
109: $this->fontpath .= '/';
110: }
111: elseif(is_dir(dirname(__FILE__).'/font'))
112: $this->fontpath = dirname(__FILE__).'/font/';
113: else
114: $this->fontpath = '';
115:
116: $this->CoreFonts = array('courier', 'helvetica', 'times', 'symbol', 'zapfdingbats');
117:
118: if($unit=='pt')
119: $this->k = 1;
120: elseif($unit=='mm')
121: $this->k = 72/25.4;
122: elseif($unit=='cm')
123: $this->k = 72/2.54;
124: elseif($unit=='in')
125: $this->k = 72;
126: else
127: $this->Error('Incorrect unit: '.$unit);
128:
129: $this->StdPageSizes = array('a3'=>array(841.89,1190.55), 'a4'=>array(595.28,841.89), 'a5'=>array(420.94,595.28),
130: 'letter'=>array(612,792), 'legal'=>array(612,1008));
131: $size = $this->_getpagesize($size);
132: $this->DefPageSize = $size;
133: $this->CurPageSize = $size;
134:
135: $orientation = strtolower($orientation);
136: if($orientation=='p' || $orientation=='portrait')
137: {
138: $this->DefOrientation = 'P';
139: $this->w = $size[0];
140: $this->h = $size[1];
141: }
142: elseif($orientation=='l' || $orientation=='landscape')
143: {
144: $this->DefOrientation = 'L';
145: $this->w = $size[1];
146: $this->h = $size[0];
147: }
148: else
149: $this->Error('Incorrect orientation: '.$orientation);
150: $this->CurOrientation = $this->DefOrientation;
151: $this->wPt = $this->w*$this->k;
152: $this->hPt = $this->h*$this->k;
153:
154: $margin = 28.35/$this->k;
155: $this->SetMargins($margin,$margin);
156:
157: $this->cMargin = $margin/10;
158:
159: $this->LineWidth = .567/$this->k;
160:
161: $this->SetAutoPageBreak(true,2*$margin);
162:
163: $this->SetDisplayMode('default');
164:
165: $this->SetCompression(true);
166:
167: $this->PDFVersion = '1.3';
168: }
169:
170: function SetMargins($left, $top, $right=null)
171: {
172:
173: $this->lMargin = $left;
174: $this->tMargin = $top;
175: if($right===null)
176: $right = $left;
177: $this->rMargin = $right;
178: }
179:
180: function SetLeftMargin($margin)
181: {
182:
183: $this->lMargin = $margin;
184: if($this->page>0 && $this->x<$margin)
185: $this->x = $margin;
186: }
187:
188: function SetTopMargin($margin)
189: {
190:
191: $this->tMargin = $margin;
192: }
193:
194: function SetRightMargin($margin)
195: {
196:
197: $this->rMargin = $margin;
198: }
199:
200: function SetAutoPageBreak($auto, $margin=0)
201: {
202:
203: $this->AutoPageBreak = $auto;
204: $this->bMargin = $margin;
205: $this->PageBreakTrigger = $this->h-$margin;
206: }
207:
208: function SetDisplayMode($zoom, $layout='default')
209: {
210:
211: if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom))
212: $this->ZoomMode = $zoom;
213: else
214: $this->Error('Incorrect zoom display mode: '.$zoom);
215: if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default')
216: $this->LayoutMode = $layout;
217: else
218: $this->Error('Incorrect layout display mode: '.$layout);
219: }
220:
221: function SetCompression($compress)
222: {
223:
224: if(function_exists('gzcompress'))
225: $this->compress = $compress;
226: else
227: $this->compress = false;
228: }
229:
230: function SetTitle($title, $isUTF8=false)
231: {
232:
233: if($isUTF8)
234: $title = $this->_UTF8toUTF16($title);
235: $this->title = $title;
236: }
237:
238: function SetSubject($subject, $isUTF8=false)
239: {
240:
241: if($isUTF8)
242: $subject = $this->_UTF8toUTF16($subject);
243: $this->subject = $subject;
244: }
245:
246: function SetAuthor($author, $isUTF8=false)
247: {
248:
249: if($isUTF8)
250: $author = $this->_UTF8toUTF16($author);
251: $this->author = $author;
252: }
253:
254: function SetKeywords($keywords, $isUTF8=false)
255: {
256:
257: if($isUTF8)
258: $keywords = $this->_UTF8toUTF16($keywords);
259: $this->keywords = $keywords;
260: }
261:
262: function SetCreator($creator, $isUTF8=false)
263: {
264:
265: if($isUTF8)
266: $creator = $this->_UTF8toUTF16($creator);
267: $this->creator = $creator;
268: }
269:
270: function AliasNbPages($alias='{nb}')
271: {
272:
273: $this->AliasNbPages = $alias;
274: }
275:
276: function Error($msg)
277: {
278:
279: die('<b>FPDF error:</b> '.$msg);
280: }
281:
282: function Open()
283: {
284:
285: $this->state = 1;
286: }
287:
288: function Close()
289: {
290:
291: if($this->state==3)
292: return;
293: if($this->page==0)
294: $this->AddPage();
295:
296: $this->InFooter = true;
297: $this->Footer();
298: $this->InFooter = false;
299:
300: $this->_endpage();
301:
302: $this->_enddoc();
303: }
304:
305: function AddPage($orientation='', $size='')
306: {
307:
308: if($this->state==0)
309: $this->Open();
310: $family = $this->FontFamily;
311: $style = $this->FontStyle.($this->underline ? 'U' : '');
312: $fontsize = $this->FontSizePt;
313: $lw = $this->LineWidth;
314: $dc = $this->DrawColor;
315: $fc = $this->FillColor;
316: $tc = $this->TextColor;
317: $cf = $this->ColorFlag;
318: if($this->page>0)
319: {
320:
321: $this->InFooter = true;
322: $this->Footer();
323: $this->InFooter = false;
324:
325: $this->_endpage();
326: }
327:
328: $this->_beginpage($orientation,$size);
329:
330: $this->_out('2 J');
331:
332: $this->LineWidth = $lw;
333: $this->_out(sprintf('%.2F w',$lw*$this->k));
334:
335: if($family)
336: $this->SetFont($family,$style,$fontsize);
337:
338: $this->DrawColor = $dc;
339: if($dc!='0 G')
340: $this->_out($dc);
341: $this->FillColor = $fc;
342: if($fc!='0 g')
343: $this->_out($fc);
344: $this->TextColor = $tc;
345: $this->ColorFlag = $cf;
346:
347: $this->InHeader = true;
348: $this->Header();
349: $this->InHeader = false;
350:
351: if($this->LineWidth!=$lw)
352: {
353: $this->LineWidth = $lw;
354: $this->_out(sprintf('%.2F w',$lw*$this->k));
355: }
356:
357: if($family)
358: $this->SetFont($family,$style,$fontsize);
359:
360: if($this->DrawColor!=$dc)
361: {
362: $this->DrawColor = $dc;
363: $this->_out($dc);
364: }
365: if($this->FillColor!=$fc)
366: {
367: $this->FillColor = $fc;
368: $this->_out($fc);
369: }
370: $this->TextColor = $tc;
371: $this->ColorFlag = $cf;
372: }
373:
374: function Header()
375: {
376:
377: }
378:
379: function ()
380: {
381:
382: }
383:
384: function PageNo()
385: {
386:
387: return $this->page;
388: }
389:
390: function SetDrawColor($r, $g=null, $b=null)
391: {
392:
393: if(($r==0 && $g==0 && $b==0) || $g===null)
394: $this->DrawColor = sprintf('%.3F G',$r/255);
395: else
396: $this->DrawColor = sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255);
397: if($this->page>0)
398: $this->_out($this->DrawColor);
399: }
400:
401: function SetFillColor($r, $g=null, $b=null)
402: {
403:
404: if(($r==0 && $g==0 && $b==0) || $g===null)
405: $this->FillColor = sprintf('%.3F g',$r/255);
406: else
407: $this->FillColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
408: $this->ColorFlag = ($this->FillColor!=$this->TextColor);
409: if($this->page>0)
410: $this->_out($this->FillColor);
411: }
412:
413: function SetTextColor($r, $g=null, $b=null)
414: {
415:
416: if(($r==0 && $g==0 && $b==0) || $g===null)
417: $this->TextColor = sprintf('%.3F g',$r/255);
418: else
419: $this->TextColor = sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255);
420: $this->ColorFlag = ($this->FillColor!=$this->TextColor);
421: }
422:
423: function GetStringWidth($s)
424: {
425:
426: $s = (string)$s;
427: $cw = &$this->CurrentFont['cw'];
428: $w = 0;
429: $l = strlen($s);
430: for($i=0;$i<$l;$i++)
431: $w += $cw[$s[$i]];
432: return $w*$this->FontSize/1000;
433: }
434:
435: function SetLineWidth($width)
436: {
437:
438: $this->LineWidth = $width;
439: if($this->page>0)
440: $this->_out(sprintf('%.2F w',$width*$this->k));
441: }
442:
443: function Line($x1, $y1, $x2, $y2)
444: {
445:
446: $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));
447: }
448:
449: function Rect($x, $y, $w, $h, $style='')
450: {
451:
452: if($style=='F')
453: $op = 'f';
454: elseif($style=='FD' || $style=='DF')
455: $op = 'B';
456: else
457: $op = 'S';
458: $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op));
459: }
460:
461: function AddFont($family, $style='', $file='')
462: {
463:
464: $family = strtolower($family);
465: if($file=='')
466: $file = str_replace(' ','',$family).strtolower($style).'.php';
467: $style = strtoupper($style);
468: if($style=='IB')
469: $style = 'BI';
470: $fontkey = $family.$style;
471: if(isset($this->fonts[$fontkey]))
472: return;
473: $info = $this->_loadfont($file);
474: $info['i'] = count($this->fonts)+1;
475: if(!empty($info['diff']))
476: {
477:
478: $n = array_search($info['diff'],$this->diffs);
479: if(!$n)
480: {
481: $n = count($this->diffs)+1;
482: $this->diffs[$n] = $info['diff'];
483: }
484: $info['diffn'] = $n;
485: }
486: if(!empty($info['file']))
487: {
488:
489: if($info['type']=='TrueType')
490: $this->FontFiles[$info['file']] = array('length1'=>$info['originalsize']);
491: else
492: $this->FontFiles[$info['file']] = array('length1'=>$info['size1'], 'length2'=>$info['size2']);
493: }
494: $this->fonts[$fontkey] = $info;
495: }
496:
497: function SetFont($family, $style='', $size=0)
498: {
499:
500: if($family=='')
501: $family = $this->FontFamily;
502: else
503: $family = strtolower($family);
504: $style = strtoupper($style);
505: if(strpos($style,'U')!==false)
506: {
507: $this->underline = true;
508: $style = str_replace('U','',$style);
509: }
510: else
511: $this->underline = false;
512: if($style=='IB')
513: $style = 'BI';
514: if($size==0)
515: $size = $this->FontSizePt;
516:
517: if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size)
518: return;
519:
520: $fontkey = $family.$style;
521: if(!isset($this->fonts[$fontkey]))
522: {
523:
524: if($family=='arial')
525: $family = 'helvetica';
526: if(in_array($family,$this->CoreFonts))
527: {
528: if($family=='symbol' || $family=='zapfdingbats')
529: $style = '';
530: $fontkey = $family.$style;
531: if(!isset($this->fonts[$fontkey]))
532: $this->AddFont($family,$style);
533: }
534: else
535: $this->Error('Undefined font: '.$family.' '.$style);
536: }
537:
538: $this->FontFamily = $family;
539: $this->FontStyle = $style;
540: $this->FontSizePt = $size;
541: $this->FontSize = $size/$this->k;
542: $this->CurrentFont = &$this->fonts[$fontkey];
543: if($this->page>0)
544: $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
545: }
546:
547: function SetFontSize($size)
548: {
549:
550: if($this->FontSizePt==$size)
551: return;
552: $this->FontSizePt = $size;
553: $this->FontSize = $size/$this->k;
554: if($this->page>0)
555: $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt));
556: }
557:
558: function AddLink()
559: {
560:
561: $n = count($this->links)+1;
562: $this->links[$n] = array(0, 0);
563: return $n;
564: }
565:
566: function SetLink($link, $y=0, $page=-1)
567: {
568:
569: if($y==-1)
570: $y = $this->y;
571: if($page==-1)
572: $page = $this->page;
573: $this->links[$link] = array($page, $y);
574: }
575:
576: function Link($x, $y, $w, $h, $link)
577: {
578:
579: $this->PageLinks[$this->page][] = array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link);
580: }
581:
582: function Text($x, $y, $txt)
583: {
584:
585: $s = sprintf('BT %.2F %.2F Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt));
586: if($this->underline && $txt!='')
587: $s .= ' '.$this->_dounderline($x,$y,$txt);
588: if($this->ColorFlag)
589: $s = 'q '.$this->TextColor.' '.$s.' Q';
590: $this->_out($s);
591: }
592:
593: function AcceptPageBreak()
594: {
595:
596: return $this->AutoPageBreak;
597: }
598:
599: function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='')
600: {
601:
602: $k = $this->k;
603: if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
604: {
605:
606: $x = $this->x;
607: $ws = $this->ws;
608: if($ws>0)
609: {
610: $this->ws = 0;
611: $this->_out('0 Tw');
612: }
613: $this->AddPage($this->CurOrientation,$this->CurPageSize);
614: $this->x = $x;
615: if($ws>0)
616: {
617: $this->ws = $ws;
618: $this->_out(sprintf('%.3F Tw',$ws*$k));
619: }
620: }
621: if($w==0)
622: $w = $this->w-$this->rMargin-$this->x;
623: $s = '';
624: if($fill || $border==1)
625: {
626: if($fill)
627: $op = ($border==1) ? 'B' : 'f';
628: else
629: $op = 'S';
630: $s = sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
631: }
632: if(is_string($border))
633: {
634: $x = $this->x;
635: $y = $this->y;
636: if(strpos($border,'L')!==false)
637: $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
638: if(strpos($border,'T')!==false)
639: $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
640: if(strpos($border,'R')!==false)
641: $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
642: if(strpos($border,'B')!==false)
643: $s .= sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
644: }
645: if($txt!=='')
646: {
647: if($align=='R')
648: $dx = $w-$this->cMargin-$this->GetStringWidth($txt);
649: elseif($align=='C')
650: $dx = ($w-$this->GetStringWidth($txt))/2;
651: else
652: $dx = $this->cMargin;
653: if($this->ColorFlag)
654: $s .= 'q '.$this->TextColor.' ';
655: $txt2 = str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
656: $s .= sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2);
657: if($this->underline)
658: $s .= ' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt);
659: if($this->ColorFlag)
660: $s .= ' Q';
661: if($link)
662: $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link);
663: }
664: if($s)
665: $this->_out($s);
666: $this->lasth = $h;
667: if($ln>0)
668: {
669:
670: $this->y += $h;
671: if($ln==1)
672: $this->x = $this->lMargin;
673: }
674: else
675: $this->x += $w;
676: }
677:
678: function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false)
679: {
680:
681: $cw = &$this->CurrentFont['cw'];
682: if($w==0)
683: $w = $this->w-$this->rMargin-$this->x;
684: $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
685: $s = str_replace("\r",'',$txt);
686: $nb = strlen($s);
687: if($nb>0 && $s[$nb-1]=="\n")
688: $nb--;
689: $b = 0;
690: if($border)
691: {
692: if($border==1)
693: {
694: $border = 'LTRB';
695: $b = 'LRT';
696: $b2 = 'LR';
697: }
698: else
699: {
700: $b2 = '';
701: if(strpos($border,'L')!==false)
702: $b2 .= 'L';
703: if(strpos($border,'R')!==false)
704: $b2 .= 'R';
705: $b = (strpos($border,'T')!==false) ? $b2.'T' : $b2;
706: }
707: }
708: $sep = -1;
709: $i = 0;
710: $j = 0;
711: $l = 0;
712: $ns = 0;
713: $nl = 1;
714: while($i<$nb)
715: {
716:
717: $c = $s[$i];
718: if($c=="\n")
719: {
720:
721: if($this->ws>0)
722: {
723: $this->ws = 0;
724: $this->_out('0 Tw');
725: }
726: $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
727: $i++;
728: $sep = -1;
729: $j = $i;
730: $l = 0;
731: $ns = 0;
732: $nl++;
733: if($border && $nl==2)
734: $b = $b2;
735: continue;
736: }
737: if($c==' ')
738: {
739: $sep = $i;
740: $ls = $l;
741: $ns++;
742: }
743: $l += $cw[$c];
744: if($l>$wmax)
745: {
746:
747: if($sep==-1)
748: {
749: if($i==$j)
750: $i++;
751: if($this->ws>0)
752: {
753: $this->ws = 0;
754: $this->_out('0 Tw');
755: }
756: $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
757: }
758: else
759: {
760: if($align=='J')
761: {
762: $this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
763: $this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
764: }
765: $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
766: $i = $sep+1;
767: }
768: $sep = -1;
769: $j = $i;
770: $l = 0;
771: $ns = 0;
772: $nl++;
773: if($border && $nl==2)
774: $b = $b2;
775: }
776: else
777: $i++;
778: }
779:
780: if($this->ws>0)
781: {
782: $this->ws = 0;
783: $this->_out('0 Tw');
784: }
785: if($border && strpos($border,'B')!==false)
786: $b .= 'B';
787: $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
788: $this->x = $this->lMargin;
789: }
790:
791: function Write($h, $txt, $link='')
792: {
793:
794: $cw = &$this->CurrentFont['cw'];
795: $w = $this->w-$this->rMargin-$this->x;
796: $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
797: $s = str_replace("\r",'',$txt);
798: $nb = strlen($s);
799: $sep = -1;
800: $i = 0;
801: $j = 0;
802: $l = 0;
803: $nl = 1;
804: while($i<$nb)
805: {
806:
807: $c = $s[$i];
808: if($c=="\n")
809: {
810:
811: $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
812: $i++;
813: $sep = -1;
814: $j = $i;
815: $l = 0;
816: if($nl==1)
817: {
818: $this->x = $this->lMargin;
819: $w = $this->w-$this->rMargin-$this->x;
820: $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
821: }
822: $nl++;
823: continue;
824: }
825: if($c==' ')
826: $sep = $i;
827: $l += $cw[$c];
828: if($l>$wmax)
829: {
830:
831: if($sep==-1)
832: {
833: if($this->x>$this->lMargin)
834: {
835:
836: $this->x = $this->lMargin;
837: $this->y += $h;
838: $w = $this->w-$this->rMargin-$this->x;
839: $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
840: $i++;
841: $nl++;
842: continue;
843: }
844: if($i==$j)
845: $i++;
846: $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
847: }
848: else
849: {
850: $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
851: $i = $sep+1;
852: }
853: $sep = -1;
854: $j = $i;
855: $l = 0;
856: if($nl==1)
857: {
858: $this->x = $this->lMargin;
859: $w = $this->w-$this->rMargin-$this->x;
860: $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
861: }
862: $nl++;
863: }
864: else
865: $i++;
866: }
867:
868: if($i!=$j)
869: $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link);
870: }
871:
872: function Ln($h=null)
873: {
874:
875: $this->x = $this->lMargin;
876: if($h===null)
877: $this->y += $this->lasth;
878: else
879: $this->y += $h;
880: }
881:
882: function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='')
883: {
884:
885: if(!isset($this->images[$file]))
886: {
887:
888: if($type=='')
889: {
890: $pos = strrpos($file,'.');
891: if(!$pos)
892: $this->Error('Image file has no extension and no type was specified: '.$file);
893: $type = substr($file,$pos+1);
894: }
895: $type = strtolower($type);
896: if($type=='jpeg')
897: $type = 'jpg';
898: $mtd = '_parse'.$type;
899: if(!method_exists($this,$mtd))
900: $this->Error('Unsupported image type: '.$type);
901: $info = $this->$mtd($file);
902: $info['i'] = count($this->images)+1;
903: $this->images[$file] = $info;
904: }
905: else
906: $info = $this->images[$file];
907:
908:
909: if($w==0 && $h==0)
910: {
911:
912: $w = -96;
913: $h = -96;
914: }
915: if($w<0)
916: $w = -$info['w']*72/$w/$this->k;
917: if($h<0)
918: $h = -$info['h']*72/$h/$this->k;
919: if($w==0)
920: $w = $h*$info['w']/$info['h'];
921: if($h==0)
922: $h = $w*$info['h']/$info['w'];
923:
924:
925: if($y===null)
926: {
927: if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak())
928: {
929:
930: $x2 = $this->x;
931: $this->AddPage($this->CurOrientation,$this->CurPageSize);
932: $this->x = $x2;
933: }
934: $y = $this->y;
935: $this->y += $h;
936: }
937:
938: if($x===null)
939: $x = $this->x;
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 GetX()
946: {
947:
948: return $this->x;
949: }
950:
951: function SetX($x)
952: {
953:
954: if($x>=0)
955: $this->x = $x;
956: else
957: $this->x = $this->w+$x;
958: }
959:
960: function GetY()
961: {
962:
963: return $this->y;
964: }
965:
966: function SetY($y)
967: {
968:
969: $this->x = $this->lMargin;
970: if($y>=0)
971: $this->y = $y;
972: else
973: $this->y = $this->h+$y;
974: }
975:
976: function SetXY($x, $y)
977: {
978:
979: $this->SetY($y);
980: $this->SetX($x);
981: }
982:
983: function Output($name='', $dest='')
984: {
985:
986: if($this->state<3)
987: $this->Close();
988: $dest = strtoupper($dest);
989: if($dest=='')
990: {
991: if($name=='')
992: {
993: $name = 'doc.pdf';
994: $dest = 'I';
995: }
996: else
997: $dest = 'F';
998: }
999: switch($dest)
1000: {
1001: case 'I':
1002:
1003: $this->_checkoutput();
1004: if(PHP_SAPI!='cli')
1005: {
1006:
1007: header('Content-Type: application/pdf');
1008: header('Content-Disposition: inline; filename="'.$name.'"');
1009: header('Cache-Control: private, max-age=0, must-revalidate');
1010: header('Pragma: public');
1011: }
1012: echo $this->buffer;
1013: break;
1014: case 'D':
1015:
1016: $this->_checkoutput();
1017: header('Content-Type: application/x-download');
1018: header('Content-Disposition: attachment; filename="'.$name.'"');
1019: header('Cache-Control: private, max-age=0, must-revalidate');
1020: header('Pragma: public');
1021: echo $this->buffer;
1022: break;
1023: case 'F':
1024:
1025: $f = fopen($name,'wb');
1026: if(!$f)
1027: $this->Error('Unable to create output file: '.$name);
1028: fwrite($f,$this->buffer,strlen($this->buffer));
1029: fclose($f);
1030: break;
1031: case 'S':
1032:
1033: return $this->buffer;
1034: default:
1035: $this->Error('Incorrect output destination: '.$dest);
1036: }
1037: return '';
1038: }
1039:
1040: 1041: 1042: 1043: 1044:
1045: function _dochecks()
1046: {
1047:
1048: if(sprintf('%.1F',1.0)!='1.0')
1049: $this->Error('This version of PHP is not supported');
1050:
1051: if(ini_get('mbstring.func_overload') & 2)
1052: $this->Error('mbstring overloading must be disabled');
1053:
1054: if(get_magic_quotes_runtime())
1055: @set_magic_quotes_runtime(0);
1056: }
1057:
1058: function _checkoutput()
1059: {
1060: if(PHP_SAPI!='cli')
1061: {
1062: if(headers_sent($file,$line))
1063: $this->Error("Some data has already been output, can't send PDF file (output started at $file:$line)");
1064: }
1065: if(ob_get_length())
1066: {
1067:
1068: if(preg_match('/^(\xEF\xBB\xBF)?\s*$/',ob_get_contents()))
1069: {
1070:
1071: ob_clean();
1072: }
1073: else
1074: $this->Error("Some data has already been output, can't send PDF file");
1075: }
1076: }
1077:
1078: function _getpagesize($size)
1079: {
1080: if(is_string($size))
1081: {
1082: $size = strtolower($size);
1083: if(!isset($this->StdPageSizes[$size]))
1084: $this->Error('Unknown page size: '.$size);
1085: $a = $this->StdPageSizes[$size];
1086: return array($a[0]/$this->k, $a[1]/$this->k);
1087: }
1088: else
1089: {
1090: if($size[0]>$size[1])
1091: return array($size[1], $size[0]);
1092: else
1093: return $size;
1094: }
1095: }
1096:
1097: function _beginpage($orientation, $size)
1098: {
1099: $this->page++;
1100: $this->pages[$this->page] = '';
1101: $this->state = 2;
1102: $this->x = $this->lMargin;
1103: $this->y = $this->tMargin;
1104: $this->FontFamily = '';
1105:
1106: if($orientation=='')
1107: $orientation = $this->DefOrientation;
1108: else
1109: $orientation = strtoupper($orientation[0]);
1110: if($size=='')
1111: $size = $this->DefPageSize;
1112: else
1113: $size = $this->_getpagesize($size);
1114: if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1])
1115: {
1116:
1117: if($orientation=='P')
1118: {
1119: $this->w = $size[0];
1120: $this->h = $size[1];
1121: }
1122: else
1123: {
1124: $this->w = $size[1];
1125: $this->h = $size[0];
1126: }
1127: $this->wPt = $this->w*$this->k;
1128: $this->hPt = $this->h*$this->k;
1129: $this->PageBreakTrigger = $this->h-$this->bMargin;
1130: $this->CurOrientation = $orientation;
1131: $this->CurPageSize = $size;
1132: }
1133: if($orientation!=$this->DefOrientation || $size[0]!=$this->DefPageSize[0] || $size[1]!=$this->DefPageSize[1])
1134: $this->PageSizes[$this->page] = array($this->wPt, $this->hPt);
1135: }
1136:
1137: function _endpage()
1138: {
1139: $this->state = 1;
1140: }
1141:
1142: function _loadfont($font)
1143: {
1144:
1145: include($this->fontpath.$font);
1146: $a = get_defined_vars();
1147: if(!isset($a['name']))
1148: $this->Error('Could not include font definition file');
1149: return $a;
1150: }
1151:
1152: function _escape($s)
1153: {
1154:
1155: $s = str_replace('\\','\\\\',$s);
1156: $s = str_replace('(','\\(',$s);
1157: $s = str_replace(')','\\)',$s);
1158: $s = str_replace("\r",'\\r',$s);
1159: return $s;
1160: }
1161:
1162: function _textstring($s)
1163: {
1164:
1165: return '('.$this->_escape($s).')';
1166: }
1167:
1168: function _UTF8toUTF16($s, $with_boom = true)
1169: {
1170: $res = "";
1171:
1172: if ($with_boom === true) {
1173: $res = "\xFE\xFF";
1174: }
1175: $nb = strlen($s);
1176: $i = 0;
1177: while($i<$nb)
1178: {
1179: $c1 = ord($s[$i++]);
1180: if($c1>=224)
1181: {
1182:
1183: $c2 = ord($s[$i++]);
1184: $c3 = ord($s[$i++]);
1185: $res .= chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2));
1186: $res .= chr((($c2 & 0x03)<<6) + ($c3 & 0x3F));
1187: }
1188: elseif($c1>=192)
1189: {
1190:
1191: $c2 = ord($s[$i++]);
1192: $res .= chr(($c1 & 0x1C)>>2);
1193: $res .= chr((($c1 & 0x03)<<6) + ($c2 & 0x3F));
1194: }
1195: else
1196: {
1197:
1198: $res .= "\0".chr($c1);
1199: }
1200: }
1201: return $res;
1202: }
1203:
1204: function _dounderline($x, $y, $txt)
1205: {
1206:
1207: $up = $this->CurrentFont['up'];
1208: $ut = $this->CurrentFont['ut'];
1209: $w = $this->GetStringWidth($txt)+$this->ws*substr_count($txt,' ');
1210: 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);
1211: }
1212:
1213: function _parsejpg($file)
1214: {
1215:
1216: $a = getimagesize($file);
1217: if(!$a)
1218: $this->Error('Missing or incorrect image file: '.$file);
1219: if($a[2]!=2)
1220: $this->Error('Not a JPEG file: '.$file);
1221: if(!isset($a['channels']) || $a['channels']==3)
1222: $colspace = 'DeviceRGB';
1223: elseif($a['channels']==4)
1224: $colspace = 'DeviceCMYK';
1225: else
1226: $colspace = 'DeviceGray';
1227: $bpc = isset($a['bits']) ? $a['bits'] : 8;
1228: $data = file_get_contents($file);
1229: return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data);
1230: }
1231:
1232: function _parsepng($file)
1233: {
1234:
1235: $f = fopen($file,'rb');
1236: if(!$f)
1237: $this->Error('Can\'t open image file: '.$file);
1238: $info = $this->_parsepngstream($f,$file);
1239: fclose($f);
1240: return $info;
1241: }
1242:
1243: function _parsepngstream($f, $file)
1244: {
1245:
1246: if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
1247: $this->Error('Not a PNG file: '.$file);
1248:
1249:
1250: $this->_readstream($f,4);
1251: if($this->_readstream($f,4)!='IHDR')
1252: $this->Error('Incorrect PNG file: '.$file);
1253: $w = $this->_readint($f);
1254: $h = $this->_readint($f);
1255: $bpc = ord($this->_readstream($f,1));
1256: if($bpc>8)
1257: $this->Error('16-bit depth not supported: '.$file);
1258: $ct = ord($this->_readstream($f,1));
1259: if($ct==0 || $ct==4)
1260: $colspace = 'DeviceGray';
1261: elseif($ct==2 || $ct==6)
1262: $colspace = 'DeviceRGB';
1263: elseif($ct==3)
1264: $colspace = 'Indexed';
1265: else
1266: $this->Error('Unknown color type: '.$file);
1267: if(ord($this->_readstream($f,1))!=0)
1268: $this->Error('Unknown compression method: '.$file);
1269: if(ord($this->_readstream($f,1))!=0)
1270: $this->Error('Unknown filter method: '.$file);
1271: if(ord($this->_readstream($f,1))!=0)
1272: $this->Error('Interlacing not supported: '.$file);
1273: $this->_readstream($f,4);
1274: $dp = '/Predictor 15 /Colors '.($colspace=='DeviceRGB' ? 3 : 1).' /BitsPerComponent '.$bpc.' /Columns '.$w;
1275:
1276:
1277: $pal = '';
1278: $trns = '';
1279: $data = '';
1280: do
1281: {
1282: $n = $this->_readint($f);
1283: $type = $this->_readstream($f,4);
1284: if($type=='PLTE')
1285: {
1286:
1287: $pal = $this->_readstream($f,$n);
1288: $this->_readstream($f,4);
1289: }
1290: elseif($type=='tRNS')
1291: {
1292:
1293: $t = $this->_readstream($f,$n);
1294: if($ct==0)
1295: $trns = array(ord(substr($t,1,1)));
1296: elseif($ct==2)
1297: $trns = array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1)));
1298: else
1299: {
1300: $pos = strpos($t,chr(0));
1301: if($pos!==false)
1302: $trns = array($pos);
1303: }
1304: $this->_readstream($f,4);
1305: }
1306: elseif($type=='IDAT')
1307: {
1308:
1309: $data .= $this->_readstream($f,$n);
1310: $this->_readstream($f,4);
1311: }
1312: elseif($type=='IEND')
1313: break;
1314: else
1315: $this->_readstream($f,$n+4);
1316: }
1317: while($n);
1318:
1319: if($colspace=='Indexed' && empty($pal))
1320: $this->Error('Missing palette in '.$file);
1321: $info = array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'dp'=>$dp, 'pal'=>$pal, 'trns'=>$trns);
1322: if($ct>=4)
1323: {
1324:
1325: if(!function_exists('gzuncompress'))
1326: $this->Error('Zlib not available, can\'t handle alpha channel: '.$file);
1327: $data = gzuncompress($data);
1328: $color = '';
1329: $alpha = '';
1330: if($ct==4)
1331: {
1332:
1333: $len = 2*$w;
1334: for($i=0;$i<$h;$i++)
1335: {
1336: $pos = (1+$len)*$i;
1337: $color .= $data[$pos];
1338: $alpha .= $data[$pos];
1339: $line = substr($data,$pos+1,$len);
1340: $color .= preg_replace('/(.)./s','$1',$line);
1341: $alpha .= preg_replace('/.(.)/s','$1',$line);
1342: }
1343: }
1344: else
1345: {
1346:
1347: $len = 4*$w;
1348: for($i=0;$i<$h;$i++)
1349: {
1350: $pos = (1+$len)*$i;
1351: $color .= $data[$pos];
1352: $alpha .= $data[$pos];
1353: $line = substr($data,$pos+1,$len);
1354: $color .= preg_replace('/(.{3})./s','$1',$line);
1355: $alpha .= preg_replace('/.{3}(.)/s','$1',$line);
1356: }
1357: }
1358: unset($data);
1359: $data = gzcompress($color);
1360: $info['smask'] = gzcompress($alpha);
1361: if($this->PDFVersion<'1.4')
1362: $this->PDFVersion = '1.4';
1363: }
1364: $info['data'] = $data;
1365: return $info;
1366: }
1367:
1368: function _readstream($f, $n)
1369: {
1370:
1371: $res = '';
1372: while($n>0 && !feof($f))
1373: {
1374: $s = fread($f,$n);
1375: if($s===false)
1376: $this->Error('Error while reading stream');
1377: $n -= strlen($s);
1378: $res .= $s;
1379: }
1380: if($n>0)
1381: $this->Error('Unexpected end of stream');
1382: return $res;
1383: }
1384:
1385: function _readint($f)
1386: {
1387:
1388: $a = unpack('Ni',$this->_readstream($f,4));
1389: return $a['i'];
1390: }
1391:
1392: function _parsegif($file)
1393: {
1394:
1395: if(!function_exists('imagepng'))
1396: $this->Error('GD extension is required for GIF support');
1397: if(!function_exists('imagecreatefromgif'))
1398: $this->Error('GD has no GIF read support');
1399: $im = imagecreatefromgif($file);
1400: if(!$im)
1401: $this->Error('Missing or incorrect image file: '.$file);
1402: imageinterlace($im,0);
1403: $f = @fopen('php://temp','rb+');
1404: if($f)
1405: {
1406:
1407: ob_start();
1408: imagepng($im);
1409: $data = ob_get_clean();
1410: imagedestroy($im);
1411: fwrite($f,$data);
1412: rewind($f);
1413: $info = $this->_parsepngstream($f,$file);
1414: fclose($f);
1415: }
1416: else
1417: {
1418:
1419: $tmp = tempnam('.','gif');
1420: if(!$tmp)
1421: $this->Error('Unable to create a temporary file');
1422: if(!imagepng($im,$tmp))
1423: $this->Error('Error while saving to temporary file');
1424: imagedestroy($im);
1425: $info = $this->_parsepng($tmp);
1426: unlink($tmp);
1427: }
1428: return $info;
1429: }
1430:
1431: function _newobj()
1432: {
1433:
1434: $this->n++;
1435: $this->offsets[$this->n] = strlen($this->buffer);
1436: $this->_out($this->n.' 0 obj');
1437: }
1438:
1439: function _putstream($s)
1440: {
1441: $this->_out('stream');
1442: $this->_out($s);
1443: $this->_out('endstream');
1444: }
1445:
1446: function _out($s)
1447: {
1448:
1449: if($this->state==2)
1450: $this->pages[$this->page] .= $s."\n";
1451: else
1452: $this->buffer .= $s."\n";
1453: }
1454:
1455: function _putpages()
1456: {
1457: $nb = $this->page;
1458: if(!empty($this->AliasNbPages))
1459: {
1460:
1461: for($n=1;$n<=$nb;$n++)
1462: $this->pages[$n] = str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
1463: }
1464: if($this->DefOrientation=='P')
1465: {
1466: $wPt = $this->DefPageSize[0]*$this->k;
1467: $hPt = $this->DefPageSize[1]*$this->k;
1468: }
1469: else
1470: {
1471: $wPt = $this->DefPageSize[1]*$this->k;
1472: $hPt = $this->DefPageSize[0]*$this->k;
1473: }
1474: $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1475: for($n=1;$n<=$nb;$n++)
1476: {
1477:
1478: $this->_newobj();
1479: $this->_out('<</Type /Page');
1480: $this->_out('/Parent 1 0 R');
1481: if(isset($this->PageSizes[$n]))
1482: $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1]));
1483: $this->_out('/Resources 2 0 R');
1484: if(isset($this->PageLinks[$n]))
1485: {
1486:
1487: $annots = '/Annots [';
1488: foreach($this->PageLinks[$n] as $pl)
1489: {
1490: $rect = sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]);
1491: $annots .= '<</Type /Annot /Subtype /Link /Rect ['.$rect.'] /Border [0 0 0] ';
1492: if(is_string($pl[4]))
1493: $annots .= '/A <</S /URI /URI '.$this->_textstring($pl[4]).'>>>>';
1494: else
1495: {
1496: $l = $this->links[$pl[4]];
1497: $h = isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt;
1498: $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k);
1499: }
1500: }
1501: $this->_out($annots.']');
1502: }
1503: if($this->PDFVersion>'1.3')
1504: $this->_out('/Group <</Type /Group /S /Transparency /CS /DeviceRGB>>');
1505: $this->_out('/Contents '.($this->n+1).' 0 R>>');
1506: $this->_out('endobj');
1507:
1508: $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
1509: $this->_newobj();
1510: $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
1511: $this->_putstream($p);
1512: $this->_out('endobj');
1513: }
1514:
1515: $this->offsets[1] = strlen($this->buffer);
1516: $this->_out('1 0 obj');
1517: $this->_out('<</Type /Pages');
1518: $kids = '/Kids [';
1519: for($i=0;$i<$nb;$i++)
1520: $kids .= (3+2*$i).' 0 R ';
1521: $this->_out($kids.']');
1522: $this->_out('/Count '.$nb);
1523: $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt));
1524: $this->_out('>>');
1525: $this->_out('endobj');
1526: }
1527:
1528: function _putfonts()
1529: {
1530: $nf = $this->n;
1531: foreach($this->diffs as $diff)
1532: {
1533:
1534: $this->_newobj();
1535: $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.$diff.']>>');
1536: $this->_out('endobj');
1537: }
1538: foreach($this->FontFiles as $file=>$info)
1539: {
1540:
1541: $this->_newobj();
1542: $this->FontFiles[$file]['n'] = $this->n;
1543: $font = file_get_contents($this->fontpath.$file,true);
1544: if(!$font)
1545: $this->Error('Font file not found: '.$file);
1546: $compressed = (substr($file,-2)=='.z');
1547: if(!$compressed && isset($info['length2']))
1548: $font = substr($font,6,$info['length1']).substr($font,6+$info['length1']+6,$info['length2']);
1549: $this->_out('<</Length '.strlen($font));
1550: if($compressed)
1551: $this->_out('/Filter /FlateDecode');
1552: $this->_out('/Length1 '.$info['length1']);
1553: if(isset($info['length2']))
1554: $this->_out('/Length2 '.$info['length2'].' /Length3 0');
1555: $this->_out('>>');
1556: $this->_putstream($font);
1557: $this->_out('endobj');
1558: }
1559: foreach($this->fonts as $k=>$font)
1560: {
1561:
1562: $this->fonts[$k]['n'] = $this->n+1;
1563: $type = $font['type'];
1564: $name = $font['name'];
1565: if($type=='Core')
1566: {
1567:
1568: $this->_newobj();
1569: $this->_out('<</Type /Font');
1570: $this->_out('/BaseFont /'.$name);
1571: $this->_out('/Subtype /Type1');
1572: if($name!='Symbol' && $name!='ZapfDingbats')
1573: $this->_out('/Encoding /WinAnsiEncoding');
1574: $this->_out('>>');
1575: $this->_out('endobj');
1576: }
1577: elseif($type=='Type1' || $type=='TrueType')
1578: {
1579:
1580: $this->_newobj();
1581: $this->_out('<</Type /Font');
1582: $this->_out('/BaseFont /'.$name);
1583: $this->_out('/Subtype /'.$type);
1584: $this->_out('/FirstChar 32 /LastChar 255');
1585: $this->_out('/Widths '.($this->n+1).' 0 R');
1586: $this->_out('/FontDescriptor '.($this->n+2).' 0 R');
1587: if(isset($font['diffn']))
1588: $this->_out('/Encoding '.($nf+$font['diffn']).' 0 R');
1589: else
1590: $this->_out('/Encoding /WinAnsiEncoding');
1591: $this->_out('>>');
1592: $this->_out('endobj');
1593:
1594: $this->_newobj();
1595: $cw = &$font['cw'];
1596: $s = '[';
1597: for($i=32;$i<=255;$i++)
1598: $s .= $cw[chr($i)].' ';
1599: $this->_out($s.']');
1600: $this->_out('endobj');
1601:
1602: $this->_newobj();
1603: $s = '<</Type /FontDescriptor /FontName /'.$name;
1604: foreach($font['desc'] as $l=>$v)
1605: $s .= ' /'.$l.' '.$v;
1606: if(!empty($font['file']))
1607: $s .= ' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$font['file']]['n'].' 0 R';
1608: $this->_out($s.'>>');
1609: $this->_out('endobj');
1610: }
1611: else
1612: {
1613:
1614: $mtd = '_put'.strtolower($type);
1615: if(!method_exists($this,$mtd))
1616: $this->Error('Unsupported font type: '.$type);
1617: $this->$mtd($font);
1618: }
1619: }
1620: }
1621:
1622: function _putimages()
1623: {
1624: foreach(array_keys($this->images) as $file)
1625: {
1626: $this->_putimage($this->images[$file]);
1627: unset($this->images[$file]['data']);
1628: unset($this->images[$file]['smask']);
1629: }
1630: }
1631:
1632: function _putimage(&$info)
1633: {
1634: $this->_newobj();
1635: $info['n'] = $this->n;
1636: $this->_out('<</Type /XObject');
1637: $this->_out('/Subtype /Image');
1638: $this->_out('/Width '.$info['w']);
1639: $this->_out('/Height '.$info['h']);
1640: if($info['cs']=='Indexed')
1641: $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]');
1642: else
1643: {
1644: $this->_out('/ColorSpace /'.$info['cs']);
1645: if($info['cs']=='DeviceCMYK')
1646: $this->_out('/Decode [1 0 1 0 1 0 1 0]');
1647: }
1648: $this->_out('/BitsPerComponent '.$info['bpc']);
1649: if(isset($info['f']))
1650: $this->_out('/Filter /'.$info['f']);
1651: if(isset($info['dp']))
1652: $this->_out('/DecodeParms <<'.$info['dp'].'>>');
1653: if(isset($info['trns']) && is_array($info['trns']))
1654: {
1655: $trns = '';
1656: for($i=0;$i<count($info['trns']);$i++)
1657: $trns .= $info['trns'][$i].' '.$info['trns'][$i].' ';
1658: $this->_out('/Mask ['.$trns.']');
1659: }
1660: if(isset($info['smask']))
1661: $this->_out('/SMask '.($this->n+1).' 0 R');
1662: $this->_out('/Length '.strlen($info['data']).'>>');
1663: $this->_putstream($info['data']);
1664: $this->_out('endobj');
1665:
1666: if(isset($info['smask']))
1667: {
1668: $dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns '.$info['w'];
1669: $smask = array('w'=>$info['w'], 'h'=>$info['h'], 'cs'=>'DeviceGray', 'bpc'=>8, 'f'=>$info['f'], 'dp'=>$dp, 'data'=>$info['smask']);
1670: $this->_putimage($smask);
1671: }
1672:
1673: if($info['cs']=='Indexed')
1674: {
1675: $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
1676: $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal'];
1677: $this->_newobj();
1678: $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>');
1679: $this->_putstream($pal);
1680: $this->_out('endobj');
1681: }
1682: }
1683:
1684: function _putxobjectdict()
1685: {
1686: foreach($this->images as $image)
1687: $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R');
1688: }
1689:
1690: function _putresourcedict()
1691: {
1692: $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
1693: $this->_out('/Font <<');
1694: foreach($this->fonts as $font)
1695: $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R');
1696: $this->_out('>>');
1697: $this->_out('/XObject <<');
1698: $this->_putxobjectdict();
1699: $this->_out('>>');
1700: }
1701:
1702: function _putresources()
1703: {
1704: $this->_putfonts();
1705: $this->_putimages();
1706:
1707: $this->offsets[2] = strlen($this->buffer);
1708: $this->_out('2 0 obj');
1709: $this->_out('<<');
1710: $this->_putresourcedict();
1711: $this->_out('>>');
1712: $this->_out('endobj');
1713: }
1714:
1715: function _putinfo()
1716: {
1717: $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION));
1718: if(!empty($this->title))
1719: $this->_out('/Title '.$this->_textstring($this->title));
1720: if(!empty($this->subject))
1721: $this->_out('/Subject '.$this->_textstring($this->subject));
1722: if(!empty($this->author))
1723: $this->_out('/Author '.$this->_textstring($this->author));
1724: if(!empty($this->keywords))
1725: $this->_out('/Keywords '.$this->_textstring($this->keywords));
1726: if(!empty($this->creator))
1727: $this->_out('/Creator '.$this->_textstring($this->creator));
1728: $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis')));
1729: }
1730:
1731: function _putcatalog()
1732: {
1733: $this->_out('/Type /Catalog');
1734: $this->_out('/Pages 1 0 R');
1735: if($this->ZoomMode=='fullpage')
1736: $this->_out('/OpenAction [3 0 R /Fit]');
1737: elseif($this->ZoomMode=='fullwidth')
1738: $this->_out('/OpenAction [3 0 R /FitH null]');
1739: elseif($this->ZoomMode=='real')
1740: $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
1741: elseif(!is_string($this->ZoomMode))
1742: $this->_out('/OpenAction [3 0 R /XYZ null null '.sprintf('%.2F',$this->ZoomMode/100).']');
1743: if($this->LayoutMode=='single')
1744: $this->_out('/PageLayout /SinglePage');
1745: elseif($this->LayoutMode=='continuous')
1746: $this->_out('/PageLayout /OneColumn');
1747: elseif($this->LayoutMode=='two')
1748: $this->_out('/PageLayout /TwoColumnLeft');
1749: }
1750:
1751: function ()
1752: {
1753: $this->_out('%PDF-'.$this->PDFVersion);
1754: }
1755:
1756: function _puttrailer()
1757: {
1758: $this->_out('/Size '.($this->n+1));
1759: $this->_out('/Root '.$this->n.' 0 R');
1760: $this->_out('/Info '.($this->n-1).' 0 R');
1761: }
1762:
1763: function _enddoc()
1764: {
1765: $this->_putheader();
1766: $this->_putpages();
1767: $this->_putresources();
1768:
1769: $this->_newobj();
1770: $this->_out('<<');
1771: $this->_putinfo();
1772: $this->_out('>>');
1773: $this->_out('endobj');
1774:
1775: $this->_newobj();
1776: $this->_out('<<');
1777: $this->_putcatalog();
1778: $this->_out('>>');
1779: $this->_out('endobj');
1780:
1781: $o = strlen($this->buffer);
1782: $this->_out('xref');
1783: $this->_out('0 '.($this->n+1));
1784: $this->_out('0000000000 65535 f ');
1785: for($i=1;$i<=$this->n;$i++)
1786: $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
1787:
1788: $this->_out('trailer');
1789: $this->_out('<<');
1790: $this->_puttrailer();
1791: $this->_out('>>');
1792: $this->_out('startxref');
1793: $this->_out($o);
1794: $this->_out('%%EOF');
1795: $this->state = 3;
1796: }
1797:
1798: }
1799:
1800:
1801: if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype')
1802: {
1803: header('Content-Type: application/pdf');
1804: exit;
1805: }
1806: