Documentation TYPO3 par Ameos |
00001 <?php 00002 /* $Id: fpdf.php,v 2.1 2003/11/20 16:31:51 garvinhicking Exp $ */ 00003 // vim: expandtab sw=4 ts=4 sts=4: 00004 00005 /**************************************************************************** 00006 * Software : FPDF * 00007 * Version : 1.51 * 00008 * Date : 2002/08/03 * 00009 * Author : Olivier PLATHEY * 00010 * Website : http://www.fpdf.org * 00011 * Licence : Freeware * 00012 * * 00013 * You are entitled to modify this soft as you want to. * 00014 ****************************************************************************/ 00015 00016 00017 $FPDF_version = (string) '1.51'; 00018 00019 00023 class FPDF 00024 { 00028 var $page; // current page number 00029 var $n; // current object number 00030 var $offsets; // array of object offsets 00031 var $buffer; // buffer holding in-memory PDF 00032 var $pages; // array containing pages 00033 var $state; // current document state 00034 var $compress; // compression flag 00035 var $DefOrientation; // default orientation 00036 var $CurOrientation; // current orientation 00037 var $OrientationChanges; // array indicating orientation changes 00038 var $fwPt, $fhPt; // dimensions of page format in points 00039 var $fw, $fh; // dimensions of page format in user unit 00040 var $wPt, $hPt; // current dimensions of page in points 00041 var $k; // scale factor (number of points in user unit) 00042 var $w, $h; // current dimensions of page in user unit 00043 var $lMargin; // left margin 00044 var $tMargin; // top margin 00045 var $rMargin; // right margin 00046 var $bMargin; // page break margin 00047 var $cMargin; // cell margin 00048 var $x, $y; // current position in user unit for cell positionning 00049 var $lasth; // height of last cell printed 00050 var $LineWidth; // line width in user unit 00051 var $CoreFonts; // array of standard font names 00052 var $fonts; // array of used fonts 00053 var $FontFiles; // array of font files 00054 var $diffs; // array of encoding differences 00055 var $images; // array of used images 00056 var $PageLinks; // array of links in pages 00057 var $links; // array of internal links 00058 var $FontFamily; // current font family 00059 var $FontStyle; // current font style 00060 var $CurrentFont; // current font info 00061 var $FontSizePt; // current font size in points 00062 var $FontSize; // current font size in user unit 00063 var $DrawColor; // commands for drawing color 00064 var $FillColor; // commands for filling color 00065 var $TextColor; // commands for text color 00066 var $ColorFlag; // indicates whether fill and text colors are different 00067 var $ws; // word spacing 00068 var $underline; // whether underline is current state or not 00069 var $AutoPageBreak; // automatic page breaking 00070 var $PageBreakTrigger; // threshold used to trigger page breaks 00071 var $InFooter; // flag set when processing footer 00072 var $ZoomMode; // zoom display mode 00073 var $LayoutMode; // layout display mode 00074 var $title; // title 00075 var $subject; // subject 00076 var $author; // author 00077 var $keywords; // keywords 00078 var $creator; // creator 00079 var $AliasNbPages; // alias for total number of pages 00080 00081 00082 00083 /************************************************************************** 00084 * * 00085 * Public methods below are used by some private ones. Then they * 00086 * are placed at the top of the class. * 00087 * * 00088 **************************************************************************/ 00089 00099 function GetStringWidth($s) 00100 { 00101 $s = (string) $s; 00102 // loic1: PHP3 compatibility 00103 // $cw = &$this->CurrentFont['cw']; 00104 $w = 0; 00105 $l = strlen($s); 00106 for ($i = 0; $i < $l; $i++) { 00107 // $w += $cw[$s[$i]]; 00108 $w += $this->CurrentFont['cw'][$s[$i]]; 00109 } // end for 00110 00111 return $w * $this->FontSize / 1000; 00112 } // end of the "GetStringWidth()" method 00113 00114 00122 function Error($msg) 00123 { 00124 die('<b>FPDF error: </b>' . $msg); 00125 } // end of the "Error()" method 00126 00127 00128 00129 /************************************************************************** 00130 * * 00131 * Private methods * 00132 * * 00133 **************************************************************************/ 00134 00142 function _out($s) 00143 { 00144 if ($this->state == 2) { 00145 $this->pages[$this->page] .= $s . "\n"; 00146 } else { 00147 $this->buffer .= $s . "\n"; 00148 } 00149 } // end of the "_out()" method 00150 00151 00157 function _newobj() 00158 { 00159 $this->n++; 00160 $this->offsets[$this->n] = strlen($this->buffer); 00161 $this->_out($this->n . ' 0 obj'); 00162 } // end of the "_newobj()" method 00163 00164 00174 function _escape($s) 00175 { 00176 return str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $s))); 00177 } // end of the "_escape()" method 00178 00179 00191 function _textstring($s) 00192 { 00193 return '(' . $this->_escape($s) . ')'; 00194 } // end of the "_textstring()" method 00195 00196 00206 function _putstream($s) 00207 { 00208 $this->_out('stream'); 00209 $this->_out($s); 00210 $this->_out('endstream'); 00211 } // end of the "_putstream()" method 00212 00213 00219 function _begindoc() 00220 { 00221 $this->state = 1; 00222 $this->_out('%PDF-1.3'); 00223 } // end of the "_begindoc()" method 00224 00225 00231 function _putpages() 00232 { 00233 $nb = $this->page; 00234 00235 if (!empty($this->AliasNbPages)) { 00236 // Replaces number of pages 00237 for ($n = 1; $n <= $nb; $n++) { 00238 $this->pages[$n] = str_replace($this->AliasNbPages, $nb, $this->pages[$n]); 00239 } 00240 } 00241 if ($this->DefOrientation == 'P') { 00242 $wPt = $this->fwPt; 00243 $hPt = $this->fhPt; 00244 } else { 00245 $wPt = $this->fhPt; 00246 $hPt = $this->fwPt; 00247 } 00248 $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; 00249 00250 for ($n=1; $n <= $nb; $n++) { 00251 // Page 00252 $this->_newobj(); 00253 $this->_out('<</Type /Page'); 00254 $this->_out('/Parent 1 0 R'); 00255 if (isset($this->OrientationChanges[$n])) { 00256 $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $hPt, $wPt)); 00257 } 00258 $this->_out('/Resources 2 0 R'); 00259 if (isset($this->PageLinks[$n])) { 00260 // Links 00261 $annots = '/Annots ['; 00262 reset($this->PageLinks[$n]); 00263 while (list(, $pl) = each($this->PageLinks[$n])) { 00264 $rect = sprintf('%.2f %.2f %.2f %.2f', $pl[0], $pl[1], $pl[0] + $pl[2], $pl[1] - $pl[3]); 00265 $annots .= '<</Type /Annot /Subtype /Link /Rect [' . $rect . '] /Border [0 0 0] '; 00266 if (is_string($pl[4])) { 00267 $annots .= '/A <</S /URI /URI ' . $this->_textstring($pl[4]) . '>>>>'; 00268 } 00269 else { 00270 $l = $this->links[$pl[4]]; 00271 $h = isset($this->OrientationChanges[$l[0]]) ? $wPt : $hPt; 00272 $annots .= sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>', 1 + 2 * $l[0], $h - $l[1] * $this->k); 00273 } 00274 } // end while 00275 $this->_out($annots . ']'); 00276 } // end if 00277 $this->_out('/Contents ' . ($this->n+1).' 0 R>>'); 00278 $this->_out('endobj'); 00279 00280 // Page content 00281 $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; 00282 $this->_newobj(); 00283 $this->_out('<<' . $filter . '/Length ' . strlen($p) . '>>'); 00284 $this->_putstream($p); 00285 $this->_out('endobj'); 00286 } // end for 00287 00288 // Pages root 00289 $this->offsets[1]=strlen($this->buffer); 00290 $this->_out('1 0 obj'); 00291 $this->_out('<</Type /Pages'); 00292 $kids = '/Kids ['; 00293 for ($i = 0; $i < $nb; $i++) { 00294 $kids .= (3 + 2 * $i) . ' 0 R '; 00295 } 00296 $this->_out($kids . ']'); 00297 $this->_out('/Count ' . $nb); 00298 $this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]', $wPt, $hPt)); 00299 $this->_out('>>'); 00300 $this->_out('endobj'); 00301 } // end of the "_putpages()" method 00302 00303 00309 function _putfonts() 00310 { 00311 $nf = $this->n; 00312 00313 foreach($this->diffs AS $diff) { 00314 // Encodings 00315 $this->_newobj(); 00316 $this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>'); 00317 $this->_out('endobj'); 00318 } // end while 00319 00320 $mqr = get_magic_quotes_runtime(); 00321 set_magic_quotes_runtime(0); 00322 00323 foreach($this->FontFiles AS $file => $info) { 00324 // Font file embedding 00325 $this->_newobj(); 00326 $this->FontFiles[$file]['n'] = $this->n; 00327 if (isset($GLOBALS['FPDF_font_path'])) { 00328 $file = $GLOBALS['FPDF_font_path'] . $file; 00329 } 00330 $size = filesize($file); 00331 if (!$size) { 00332 $this->Error('Font file not found'); 00333 } 00334 $this->_out('<</Length ' . $size); 00335 if (substr($file, -2) == '.z') { 00336 $this->_out('/Filter /FlateDecode'); 00337 } 00338 $this->_out('/Length1 ' . $info['length1']); 00339 if (isset($info['length2'])) { 00340 $this->_out('/Length2 ' . $info['length2'] . ' /Length3 0'); 00341 } 00342 $this->_out('>>'); 00343 $f = fopen($file, 'rb'); 00344 $this->_putstream(fread($f, $size)); 00345 fclose($f); 00346 $this->_out('endobj'); 00347 } // end while 00348 set_magic_quotes_runtime($mqr); 00349 00350 foreach($this->fonts AS $k => $font) { 00351 // Font objects 00352 $this->_newobj(); 00353 $this->fonts[$k]['n'] = $this->n; 00354 $name = $font['name']; 00355 $this->_out('<</Type /Font'); 00356 $this->_out('/BaseFont /' . $name); 00357 if ($font['type'] == 'core') { 00358 // Standard font 00359 $this->_out('/Subtype /Type1'); 00360 if ($name != 'Symbol' && $name != 'ZapfDingbats') { 00361 $this->_out('/Encoding /WinAnsiEncoding'); 00362 } 00363 } 00364 else { 00365 // Additional font 00366 $this->_out('/Subtype /' . $font['type']); 00367 $this->_out('/FirstChar 32'); 00368 $this->_out('/LastChar 255'); 00369 $this->_out('/Widths ' . ($this->n + 1) . ' 0 R'); 00370 $this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R'); 00371 if ($font['enc']) { 00372 if (isset($font['diff'])) { 00373 $this->_out('/Encoding ' . ($nf + $font['diff']) . ' 0 R'); 00374 } else { 00375 $this->_out('/Encoding /WinAnsiEncoding'); 00376 } 00377 } 00378 } // end if... else... 00379 $this->_out('>>'); 00380 $this->_out('endobj'); 00381 if ($font['type'] != 'core') { 00382 // Widths 00383 $this->_newobj(); 00384 $s = '['; 00385 for ($i = 32; $i <= 255; $i++) { 00386 $s .= $font['cw'][chr($i)] . ' '; 00387 } 00388 $this->_out($s . ']'); 00389 $this->_out('endobj'); 00390 // Descriptor 00391 $this->_newobj(); 00392 $s = '<</Type /FontDescriptor /FontName /' . $name; 00393 foreach($font['desc'] AS $k => $v) { 00394 $s .= ' /' . $k . ' ' . $v; 00395 } 00396 $file = $font['file']; 00397 if ($file) { 00398 $s .= ' /FontFile' . ($font['type'] == 'Type1' ? '' : '2') . ' ' . $this->FontFiles[$file]['n'] . ' 0 R'; 00399 } 00400 $this->_out($s . '>>'); 00401 $this->_out('endobj'); 00402 } // end if 00403 } // end while 00404 } // end of the "_putfonts()" method 00405 00406 00412 function _putimages() 00413 { 00414 $filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; 00415 00416 foreach($this->images AS $file => $info) { 00417 $this->_newobj(); 00418 $this->images[$file]['n'] = $this->n; 00419 $this->_out('<</Type /XObject'); 00420 $this->_out('/Subtype /Image'); 00421 $this->_out('/Width ' . $info['w']); 00422 $this->_out('/Height ' . $info['h']); 00423 if ($info['cs'] == 'Indexed') { 00424 $this->_out('/ColorSpace [/Indexed /DeviceRGB ' . (strlen($info['pal'])/ 3 - 1) . ' ' . ($this->n + 1) . ' 0 R]'); 00425 } 00426 else { 00427 $this->_out('/ColorSpace /' . $info['cs']); 00428 if ($info['cs'] == 'DeviceCMYK') { 00429 $this->_out('/Decode [1 0 1 0 1 0 1 0]'); 00430 } 00431 } // end if... else... 00432 $this->_out('/BitsPerComponent ' . $info['bpc']); 00433 $this->_out('/Filter /' . $info['f']); 00434 if (isset($info['parms'])) { 00435 $this->_out($info['parms']); 00436 } 00437 if (isset($info['trns']) && is_array($info['trns'])) { 00438 $trns = ''; 00439 $trns_cnt = count($info['trns']); 00440 for ($i = 0; $i < $trns_cnt; $i++) { 00441 $trns .= $info['trns'][$i] . ' ' . $info['trns'][$i] . ' '; 00442 } 00443 $this->_out('/Mask [' . $trns . ']'); 00444 } // end if 00445 $this->_out('/Length ' . strlen($info['data']) . '>>'); 00446 $this->_putstream($info['data']); 00447 $this->_out('endobj'); 00448 00449 // Palette 00450 if ($info['cs'] == 'Indexed') { 00451 $this->_newobj(); 00452 $pal = ($this->compress) ? gzcompress($info['pal']) : $info['pal']; 00453 $this->_out('<<' . $filter . '/Length ' . strlen($pal) . '>>'); 00454 $this->_putstream($pal); 00455 $this->_out('endobj'); 00456 } // end if 00457 } // end while 00458 } // end of the "_putimages()" method 00459 00460 00466 function _putresources() 00467 { 00468 $this->_putfonts(); 00469 $this->_putimages(); 00470 // Resource dictionary 00471 $this->offsets[2] = strlen($this->buffer); 00472 $this->_out('2 0 obj'); 00473 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); 00474 $this->_out('/Font <<'); 00475 foreach($this->fonts AS $font) { 00476 $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); 00477 } 00478 $this->_out('>>'); 00479 if (count($this->images)) { 00480 $this->_out('/XObject <<'); 00481 foreach($this->images AS $image) { 00482 $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); 00483 } 00484 $this->_out('>>'); 00485 } 00486 $this->_out('>>'); 00487 $this->_out('endobj'); 00488 } // end of the "_putresources()" method 00489 00490 00496 function _putinfo() 00497 { 00498 // loic1: PHP3 compatibility 00499 // $this->_out('/Producer ' . $this->_textstring('FPDF ' . FPDF_VERSION)); 00500 $this->_out('/Producer ' . $this->_textstring('FPDF ' . $GLOBALS['FPDF_version'])); 00501 if (!empty($this->title)) { 00502 $this->_out('/Title ' . $this->_textstring($this->title)); 00503 } 00504 if (!empty($this->subject)) { 00505 $this->_out('/Subject ' . $this->_textstring($this->subject)); 00506 } 00507 if (!empty($this->author)) { 00508 $this->_out('/Author ' . $this->_textstring($this->author)); 00509 } 00510 if (!empty($this->keywords)) { 00511 $this->_out('/Keywords ' . $this->_textstring($this->keywords)); 00512 } 00513 if (!empty($this->creator)) { 00514 $this->_out('/Creator ' . $this->_textstring($this->creator)); 00515 } 00516 $this->_out('/CreationDate ' . $this->_textstring('D:' . date('YmdHis'))); 00517 } // end of the "_putinfo()" method 00518 00519 00525 function _putcatalog() 00526 { 00527 $this->_out('/Type /Catalog'); 00528 $this->_out('/Pages 1 0 R'); 00529 if ($this->ZoomMode == 'fullpage') { 00530 $this->_out('/OpenAction [3 0 R /Fit]'); 00531 } else if ($this->ZoomMode == 'fullwidth') { 00532 $this->_out('/OpenAction [3 0 R /FitH null]'); 00533 } else if ($this->ZoomMode == 'real') { 00534 $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); 00535 } else if (!is_string($this->ZoomMode)) { 00536 $this->_out('/OpenAction [3 0 R /XYZ null null ' . ($this->ZoomMode / 100) . ']'); 00537 } 00538 if ($this->LayoutMode == 'single') { 00539 $this->_out('/PageLayout /SinglePage'); 00540 } else if ($this->LayoutMode == 'continuous') { 00541 $this->_out('/PageLayout /OneColumn'); 00542 } else if ($this->LayoutMode == 'two') { 00543 $this->_out('/PageLayout /TwoColumnLeft'); 00544 } 00545 } // end of the "_putcatalog()" method 00546 00547 00553 function _puttrailer() 00554 { 00555 $this->_out('/Size ' . ($this->n + 1)); 00556 $this->_out('/Root ' . $this->n . ' 0 R'); 00557 $this->_out('/Info ' . ($this->n - 1) . ' 0 R'); 00558 } // end of the "_puttrailer()" method 00559 00560 00566 function _enddoc() 00567 { 00568 $this->_putpages(); 00569 $this->_putresources(); 00570 00571 // Info 00572 $this->_newobj(); 00573 $this->_out('<<'); 00574 $this->_putinfo(); 00575 $this->_out('>>'); 00576 $this->_out('endobj'); 00577 00578 // Catalog 00579 $this->_newobj(); 00580 $this->_out('<<'); 00581 $this->_putcatalog(); 00582 $this->_out('>>'); 00583 $this->_out('endobj'); 00584 00585 // Cross-ref 00586 $o = strlen($this->buffer); 00587 $this->_out('xref'); 00588 $this->_out('0 ' . ($this->n + 1)); 00589 $this->_out('0000000000 65535 f '); 00590 for ($i = 1; $i <= $this->n; $i++) { 00591 $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i])); 00592 } 00593 00594 // Trailer 00595 $this->_out('trailer'); 00596 $this->_out('<<'); 00597 $this->_puttrailer(); 00598 $this->_out('>>'); 00599 $this->_out('startxref'); 00600 $this->_out($o); 00601 $this->_out('%%EOF'); 00602 $this->state=3; 00603 } // end of the "_enddoc()" method 00604 00605 00613 function _beginpage($orientation) 00614 { 00615 $this->page++; 00616 $this->pages[$this->page] = ''; 00617 $this->state = 2; 00618 $this->x = $this->lMargin; 00619 $this->y = $this->tMargin; 00620 $this->lasth = 0; 00621 $this->FontFamily = ''; 00622 00623 // Page orientation 00624 if (!$orientation) { 00625 $orientation = $this->DefOrientation; 00626 } else { 00627 $orientation = strtoupper($orientation[0]); 00628 } 00629 if ($orientation != $this->DefOrientation) { 00630 $this->OrientationChanges[$this->page] = TRUE; 00631 } 00632 if ($orientation != $this->CurOrientation) { 00633 // Changes orientation 00634 if ($orientation == 'P') { 00635 $this->wPt = $this->fwPt; 00636 $this->hPt = $this->fhPt; 00637 $this->w = $this->fw; 00638 $this->h = $this->fh; 00639 } 00640 else { 00641 $this->wPt = $this->fhPt; 00642 $this->hPt = $this->fwPt; 00643 $this->w = $this->fh; 00644 $this->h = $this->fw; 00645 } 00646 $this->PageBreakTrigger = $this->h - $this->bMargin; 00647 $this->CurOrientation = $orientation; 00648 } // end if 00649 } // end of the "_beginpage()" method 00650 00651 00657 function _endpage() 00658 { 00659 $this->state=1; 00660 } // end of the "_endpage()" method 00661 00662 00674 function _dounderline($x,$y,$txt) 00675 { 00676 $up = $this->CurrentFont['up']; 00677 $ut = $this->CurrentFont['ut']; 00678 $w = $this->GetStringWidth($txt) + $this->ws * substr_count($txt, ' '); 00679 00680 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); 00681 } // end of the "_dounderline()" method 00682 00683 00693 function _parsejpg($file) 00694 { 00695 $a = GetImageSize($file); 00696 if (!$a) { 00697 $this->Error('Missing or incorrect image file: ' . $file); 00698 } 00699 if ($a[2] != 2) { 00700 $this->Error('Not a JPEG file: ' . $file); 00701 } 00702 if (!isset($a['channels']) || $a['channels'] == 3) { 00703 $colspace = 'DeviceRGB'; 00704 } 00705 else if($a['channels'] == 4) { 00706 $colspace = 'DeviceCMYK'; 00707 } 00708 else { 00709 $colspace = 'DeviceGray'; 00710 } 00711 $bpc = isset($a['bits']) ? $a['bits'] : 8; 00712 00713 // Reads whole file 00714 $f = fopen($file, 'rb'); 00715 $data = fread($f, filesize($file)); 00716 fclose($f); 00717 00718 return array('w' => $a[0], 00719 'h' => $a[1], 00720 'cs' => $colspace, 00721 'bpc' => $bpc, 00722 'f' => 'DCTDecode', 00723 'data' => $data); 00724 } // end of the "_parsejpg()" method 00725 00726 00738 function _freadint($f) 00739 { 00740 $i = ord(fread($f, 1)) << 24; 00741 $i += ord(fread($f, 1)) << 16; 00742 $i += ord(fread($f, 1)) << 8; 00743 $i += ord(fread($f, 1)); 00744 00745 return $i; 00746 } // end of the "_freadint()" method 00747 00748 00760 function _parsepng($file) 00761 { 00762 $f = fopen($file, 'rb'); 00763 if (!$f) { 00764 $this->Error('Can\'t open image file: ' . $file); 00765 } 00766 00767 // Checks signature 00768 if (fread($f, 8) != chr(137) . 'PNG' . chr(13) . chr(10) . chr(26) . chr(10)) { 00769 $this->Error('Not a PNG file: ' . $file); 00770 } 00771 00772 // Reads header chunk 00773 fread($f,4); 00774 if (fread($f, 4) != 'IHDR') { 00775 $this->Error('Incorrect PNG file: ' . $file); 00776 } 00777 $w = $this->_freadint($f); 00778 $h = $this->_freadint($f); 00779 $bpc = ord(fread($f,1)); 00780 if ($bpc > 8) { 00781 $this->Error('16-bit depth not supported: ' . $file); 00782 } 00783 $ct = ord(fread($f, 1)); 00784 if ($ct == 0) { 00785 $colspace = 'DeviceGray'; 00786 } 00787 else if ($ct == 2) { 00788 $colspace = 'DeviceRGB'; 00789 } 00790 else if ($ct == 3) { 00791 $colspace = 'Indexed'; 00792 } 00793 else { 00794 $this->Error('Alpha channel not supported: ' . $file); 00795 } 00796 if (ord(fread($f, 1)) != 0) { 00797 $this->Error('Unknown compression method: ' . $file); 00798 } 00799 if (ord(fread($f, 1)) != 0) { 00800 $this->Error('Unknown filter method: ' . $file); 00801 } 00802 if (ord(fread($f, 1)) != 0) { 00803 $this->Error('Interlacing not supported: ' . $file); 00804 } 00805 fread($f, 4); 00806 $parms = '/DecodeParms <</Predictor 15 /Colors ' . ($ct == 2 ? 3 : 1) 00807 . ' /BitsPerComponent ' . $bpc 00808 . ' /Columns ' . $w . '>>'; 00809 00810 // Scans chunks looking for palette, transparency and image data 00811 $pal = ''; 00812 $trns = ''; 00813 $data = ''; 00814 do { 00815 $n = $this->_freadint($f); 00816 $type = fread($f, 4); 00817 if ($type == 'PLTE') { 00818 // Reads palette 00819 $pal = fread($f, $n); 00820 fread($f, 4); 00821 } 00822 else if ($type == 'tRNS') { 00823 // Reads transparency info 00824 $t = fread($f, $n); 00825 if ($ct == 0) { 00826 $trns = array(ord(substr($t, 1, 1))); 00827 } 00828 else if ($ct == 2) { 00829 $trns = array(ord(substr($t, 1, 1)), ord(substr($t, 3, 1)), ord(substr($t, 5, 1))); 00830 } 00831 else { 00832 $pos = strpos(' ' . $t, chr(0)); 00833 if ($pos) { 00834 $trns = array($pos - 1); 00835 } 00836 fread($f,4); 00837 } // end if... else if... else 00838 } 00839 else if ($type == 'IDAT') { 00840 // Reads image data block 00841 $data .= fread($f, $n); 00842 fread($f, 4); 00843 } 00844 else if ($type == 'IEND') { 00845 break; 00846 } 00847 else { 00848 fread($f, $n + 4); 00849 } // end if... else if... else 00850 } while($n); // end do 00851 00852 if ($colspace == 'Indexed' && empty($pal)) { 00853 $this->Error('Missing palette in ' . $file); 00854 } 00855 fclose($f); 00856 00857 return array('w' => $w, 00858 'h' => $h, 00859 'cs' => $colspace, 00860 'bpc' => $bpc, 00861 'f' => 'FlateDecode', 00862 'parms' => $parms, 00863 'pal' => $pal, 00864 'trns' => $trns, 00865 'data' => $data); 00866 } // end of the "_parsepng()" method 00867 00868 00869 00870 /************************************************************************** 00871 * * 00872 * Public methods * 00873 * * 00874 **************************************************************************/ 00875 00885 function SetAutoPageBreak($auto, $margin = 0) 00886 { 00887 $this->AutoPageBreak = $auto; 00888 $this->bMargin = $margin; 00889 $this->PageBreakTrigger = $this->h - $margin; 00890 } // end of the "SetAutoPageBreak()" method 00891 00892 00902 function SetDisplayMode($zoom = 'default', $layout = 'continuous') 00903 { 00904 if (is_string($zoom)) { 00905 $zoom = strtolower($zoom); 00906 } 00907 $layout = strtolower($layout); 00908 00909 // Zoom mode 00910 if ($zoom == 'fullpage' || $zoom == 'fullwidth' || $zoom == 'real' || $zoom == 'default' 00911 || !is_string($zoom)) { 00912 $this->ZoomMode = $zoom; 00913 } else if ($zoom == 'zoom') { 00914 $this->ZoomMode = $layout; 00915 } else { 00916 $this->Error('Incorrect zoom display mode: ' . $zoom); 00917 } // end if... else if... else... 00918 00919 // Layout mode 00920 if ($layout == 'single' || $layout == 'continuous' || $layout=='two' || $layout=='default') { 00921 $this->LayoutMode = $layout; 00922 } else if ($zoom != 'zoom') { 00923 $this->Error('Incorrect layout display mode: ' . $layout); 00924 } // end if... else if... 00925 } // end of the "SetDisplayMode()" method 00926 00927 00935 function SetCompression($compress) 00936 { 00937 if (function_exists('gzcompress')) { 00938 $this->compress = $compress; 00939 } else { 00940 $this->compress = FALSE; 00941 } // end if... else... 00942 } // end of the "SetCompression()" method 00943 00944 00954 function SetMargins($left, $top, $right = -1) 00955 { 00956 $this->lMargin = $left; 00957 $this->tMargin = $top; 00958 if ($right == -1) { 00959 $right = $left; 00960 } 00961 $this->rMargin = $right; 00962 } // end of the "SetMargins()" method 00963 00964 00975 function FPDF($orientation = 'P', $unit = 'mm', $format = 'A4') 00976 { 00977 // Check for PHP locale-related bug 00978 if (1.1 == 1) { 00979 $this->Error('Don\'t call setlocale() before including class file'); 00980 } 00981 00982 // Initialization of properties 00983 $this->page = 0; 00984 $this->n = 2; 00985 $this->buffer = ''; 00986 $this->pages = array(); 00987 $this->OrientationChanges = array(); 00988 $this->state = 0; 00989 $this->fonts = array(); 00990 $this->FontFiles = array(); 00991 $this->diffs = array(); 00992 $this->images = array(); 00993 $this->links = array(); 00994 $this->InFooter = FALSE; 00995 $this->FontFamily = ''; 00996 $this->FontStyle = ''; 00997 $this->FontSizePt = 12; 00998 $this->underline = FALSE; 00999 $this->DrawColor = '0 G'; 01000 $this->FillColor = '0 g'; 01001 $this->TextColor = '0 g'; 01002 $this->ColorFlag = FALSE; 01003 $this->ws = 0; 01004 01005 // Standard fonts 01006 $this->CoreFonts['courier'] = 'Courier'; 01007 $this->CoreFonts['courierB'] = 'Courier-Bold'; 01008 $this->CoreFonts['courierI'] = 'Courier-Oblique'; 01009 $this->CoreFonts['courierBI'] = 'Courier-BoldOblique'; 01010 $this->CoreFonts['helvetica'] = 'Helvetica'; 01011 $this->CoreFonts['helveticaB'] = 'Helvetica-Bold'; 01012 $this->CoreFonts['helveticaI'] = 'Helvetica-Oblique'; 01013 $this->CoreFonts['helveticaBI'] = 'Helvetica-BoldOblique'; 01014 $this->CoreFonts['times'] = 'Times-Roman'; 01015 $this->CoreFonts['timesB'] = 'Times-Bold'; 01016 $this->CoreFonts['timesI'] = 'Times-Italic'; 01017 $this->CoreFonts['timesBI'] = 'Times-BoldItalic'; 01018 $this->CoreFonts['symbol'] = 'Symbol'; 01019 $this->CoreFonts['zapfdingbats'] = 'ZapfDingbats'; 01020 01021 // Scale factor 01022 if ($unit == 'pt') { 01023 $this->k = 1; 01024 } else if ($unit == 'mm') { 01025 $this->k = 72/25.4; 01026 } else if ($unit == 'cm') { 01027 $this->k = 72/2.54; 01028 } else if ($unit == 'in') { 01029 $this->k = 72; 01030 } else { 01031 $this->Error('Incorrect unit: ' . $unit); 01032 } // end if... else if... else... 01033 01034 // Page format 01035 if (is_string($format)) { 01036 // 2002-07-24 - Nicola Asuni (info@tecnick.com) 01037 // Added new page formats (45 standard ISO paper formats and 4 01038 // american common formats). 01039 // Paper cordinates are calculated in this way: 01040 // (inches * 72) where (1 inch = 2.54 cm) 01041 switch (strtoupper($format)) { 01042 case '4A0': 01043 $format = array(4767.87, 6740.79); 01044 break; 01045 case '2A0': 01046 $format = array(3370.39, 4767.87); 01047 break; 01048 case 'A0': 01049 $format = array(2383.94, 3370.39); 01050 break; 01051 case 'A1': 01052 $format = array(1683.78, 2383.94); 01053 break; 01054 case 'A2': 01055 $format = array(1190.55, 1683.78); 01056 break; 01057 case 'A3': 01058 $format = array(841.89, 1190.55); 01059 break; 01060 case 'A4': 01061 $format = array(595.28, 841.89); 01062 break; 01063 case 'A5': 01064 $format = array(419.53, 595.28); 01065 break; 01066 case 'A6': 01067 $format = array(297.64, 419.53); 01068 break; 01069 case 'A7': 01070 $format = array(209.76, 297.64); 01071 break; 01072 case 'A8': 01073 $format = array(147.40, 209.76); 01074 break; 01075 case 'A9': 01076 $format = array(104.88, 147.40); 01077 break; 01078 case 'A10': 01079 $format = array(73.70, 104.88); 01080 break; 01081 case 'B0': 01082 $format = array(2834.65, 4008.19); 01083 break; 01084 case 'B1': 01085 $format = array(2004.09, 2834.65); 01086 break; 01087 case 'B2': 01088 $format = array(1417.32, 2004.09); 01089 break; 01090 case 'B3': 01091 $format = array(1000.63, 1417.32); 01092 break; 01093 case 'B4': 01094 $format = array(708.66, 1000.63); 01095 break; 01096 case 'B5': 01097 $format = array(498.90, 708.66); 01098 break; 01099 case 'B6': 01100 $format = array(354.33, 498.90); 01101 break; 01102 case 'B7': 01103 $format = array(249.45, 354.33); 01104 break; 01105 case 'B8': 01106 $format = array(175.75, 249.45); 01107 break; 01108 case 'B9': 01109 $format = array(124.72, 175.75); 01110 break; 01111 case 'B10': 01112 $format = array(87.87, 124.72); 01113 break; 01114 case 'C0': 01115 $format = array(2599.37, 3676.54); 01116 break; 01117 case 'C1': 01118 $format = array(1836.85, 2599.37); 01119 break; 01120 case 'C2': 01121 $format = array(1298.27, 1836.85); 01122 break; 01123 case 'C3': 01124 $format = array(918.43, 1298.27); 01125 break; 01126 case 'C4': 01127 $format = array(649.13, 918.43); 01128 break; 01129 case 'C5': 01130 $format = array(459.21, 649.13); 01131 break; 01132 case 'C6': 01133 $format = array(323.15, 459.21); 01134 break; 01135 case 'C7': 01136 $format = array(229.61, 323.15); 01137 break; 01138 case 'C8': 01139 $format = array(161.57, 229.61); 01140 break; 01141 case 'C9': 01142 $format = array(113.39, 161.57); 01143 break; 01144 case 'C10': 01145 $format = array(79.37, 113.39); 01146 break; 01147 case 'RA0': 01148 $format = array(2437.80, 3458.27); 01149 break; 01150 case 'RA1': 01151 $format = array(1729.13, 2437.80); 01152 break; 01153 case 'RA2': 01154 $format = array(1218.90, 1729.13); 01155 break; 01156 case 'RA3': 01157 $format = array(864.57, 1218.90); 01158 break; 01159 case 'RA4': 01160 $format = array(609.45, 864.57); 01161 break; 01162 case 'SRA0': 01163 $format = array(2551.18, 3628.35); 01164 break; 01165 case 'SRA1': 01166 $format = array(1814.17, 2551.18); 01167 break; 01168 case 'SRA2': 01169 $format = array(1275.59, 1814.17); 01170 break; 01171 case 'SRA3': 01172 $format = array(907.09, 1275.59); 01173 break; 01174 case 'SRA4': 01175 $format = array(637.80, 907.09); 01176 break; 01177 case 'LETTER': 01178 $format = array(612.00, 792.00); 01179 break; 01180 case 'LEGAL': 01181 $format = array(612.00, 1008.00); 01182 break; 01183 case 'EXECUTIVE': 01184 $format = array(521.86, 756.00); 01185 break; 01186 case 'FOLIO': 01187 $format = array(612.00, 936.00); 01188 break; 01189 default: 01190 $this->Error('Unknown page format: ' . $format); 01191 break; 01192 } // end switch 01193 $this->fwPt = $format[0]; 01194 $this->fhPt = $format[1]; 01195 } 01196 else { 01197 $this->fwPt = $format[0] * $this->k; 01198 $this->fhPt = $format[1] * $this->k; 01199 } // end if... else... 01200 $this->fw = $this->fwPt / $this->k; 01201 $this->fh = $this->fhPt / $this->k; 01202 01203 // Page orientation 01204 $orientation = strtolower($orientation); 01205 if ($orientation == 'p' || $orientation == 'portrait') { 01206 $this->DefOrientation = 'P'; 01207 $this->wPt = $this->fwPt; 01208 $this->hPt = $this->fhPt; 01209 } 01210 else if ($orientation == 'l' || $orientation == 'landscape') { 01211 $this->DefOrientation = 'L'; 01212 $this->wPt = $this->fhPt; 01213 $this->hPt = $this->fwPt; 01214 } 01215 else { 01216 $this->Error('Incorrect orientation: ' . $orientation); 01217 } // end if... else if... else... 01218 $this->CurOrientation = $this->DefOrientation; 01219 $this->w = $this->wPt / $this->k; 01220 $this->h = $this->hPt / $this->k; 01221 01222 // Page margins (1 cm) 01223 $margin = 28.35 / $this->k; 01224 $this->SetMargins($margin, $margin); 01225 01226 // Interior cell margin (1 mm) 01227 $this->cMargin = $margin / 10; 01228 01229 // Line width (0.2 mm) 01230 $this->LineWidth = .567 / $this->k; 01231 01232 // Automatic page break 01233 $this->SetAutoPageBreak(TRUE, 2 * $margin); 01234 01235 // Full width display mode 01236 $this->SetDisplayMode('fullwidth'); 01237 01238 // Compression 01239 $this->SetCompression(TRUE); 01240 } // end of the "FPDF()" constructor 01241 01242 01250 function SetLeftMargin($margin) 01251 { 01252 $this->lMargin = $margin; 01253 if ($this->page > 0 && $this->x < $margin) { 01254 $this->x = $margin; 01255 } 01256 } // end of the "SetLeftMargin()" method 01257 01258 01266 function SetTopMargin($margin) 01267 { 01268 $this->tMargin = $margin; 01269 } // end of the "SetTopMargin()" method 01270 01271 01279 function SetRightMargin($margin) 01280 { 01281 $this->rMargin = $margin; 01282 } // end of the "SetRightMargin()" method 01283 01284 01292 function SetTitle($title) 01293 { 01294 $this->title = $title; 01295 } // end of the "SetTitle()" method 01296 01297 01305 function SetSubject($subject) 01306 { 01307 $this->subject = $subject; 01308 } // end of the "SetSubject()" method 01309 01310 01318 function SetAuthor($author) 01319 { 01320 $this->author = $author; 01321 } // end of the "SetAuthor()" method 01322 01323 01331 function SetKeywords($keywords) 01332 { 01333 $this->keywords = $keywords; 01334 } // end of the "SetKeywords()" method 01335 01336 01344 function SetCreator($creator) 01345 { 01346 $this->creator = $creator; 01347 } // end of the "SetCreator()" method 01348 01349 01357 function AliasNbPages($alias = '{nb}') 01358 { 01359 $this->AliasNbPages = $alias; 01360 } // end of the "AliasNbPages()" method 01361 01362 01374 function SetFont($family, $style = '', $size = 0) 01375 { 01376 global $fpdf_charwidths; 01377 01378 $family = strtolower($family); 01379 if ($family == '') { 01380 $family = $this->FontFamily; 01381 } 01382 if ($family == 'arial') { 01383 $family = 'helvetica'; 01384 } 01385 else if ($family == 'symbol' || $family == 'zapfdingbats') { 01386 $style = ''; 01387 } 01388 $style = strtoupper($style); 01389 01390 if (strpos(' ' . $style, 'U')) { 01391 $this->underline = TRUE; 01392 $style = str_replace('U', '', $style); 01393 } else { 01394 $this->underline = FALSE; 01395 } 01396 if ($style == 'IB') { 01397 $style = 'BI'; 01398 } 01399 if ($size == 0) { 01400 $size = $this->FontSizePt; 01401 } 01402 01403 // Tests if the font is already selected 01404 if ($this->FontFamily == $family && $this->FontStyle == $style && $this->FontSizePt == $size) { 01405 return; 01406 } 01407 01408 // Tests if used for the first time 01409 $fontkey = $family . $style; 01410 if (!isset($this->fonts[$fontkey])) { 01411 // Checks if one of the standard fonts 01412 if (isset($this->CoreFonts[$fontkey])) { 01413 if (!isset($fpdf_charwidths[$fontkey])) { 01414 // Loads metric file 01415 $file = $family; 01416 if ($family == 'times' || $family == 'helvetica') { 01417 $file .= strtolower($style); 01418 } 01419 $file .= '.php'; 01420 if (isset($GLOBALS['FPDF_font_path'])) { 01421 $file = $GLOBALS['FPDF_font_path'] . $file; 01422 } 01423 include($file); 01424 if (!isset($fpdf_charwidths[$fontkey])) { 01425 $this->Error('Could not include font metric file'); 01426 } 01427 } // end if 01428 $i = count($this->fonts) + 1; 01429 $this->fonts[$fontkey] = array('i' => $i, 01430 'type' => 'core', 01431 'name' => $this->CoreFonts[$fontkey], 01432 'up' => -100, 01433 'ut' => 50, 01434 'cw' => $fpdf_charwidths[$fontkey]); 01435 } 01436 else { 01437 $this->Error('Undefined font: ' . $family . ' ' . $style); 01438 } // end if... else... 01439 } // end if 01440 01441 // Selects it 01442 $this->FontFamily = $family; 01443 $this->FontStyle = $style; 01444 $this->FontSizePt = $size; 01445 $this->FontSize = $size / $this->k; 01446 $this->CurrentFont = &$this->fonts[$fontkey]; 01447 if ($this->page > 0) { 01448 $this->_out(sprintf('BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 01449 } 01450 } // end of the "SetFont()" method 01451 01452 01460 function Header() 01461 { 01462 // void 01463 } // end of the "Header()" method 01464 01465 01473 function Footer() 01474 { 01475 // void 01476 } // end of the "Footer()" method 01477 01478 01484 function Open() 01485 { 01486 $this->_begindoc(); 01487 } // end of the "Open()" method 01488 01489 01497 function AddPage($orientation = '') 01498 { 01499 // Backups some core variables 01500 $family = $this->FontFamily; 01501 $style = $this->FontStyle . ($this->underline ? 'U' : ''); 01502 $size = $this->FontSizePt; 01503 $lw = $this->LineWidth; 01504 $dc = $this->DrawColor; 01505 $fc = $this->FillColor; 01506 $tc = $this->TextColor; 01507 $cf = $this->ColorFlag; 01508 01509 // If a page is already defined close it before starting the new one 01510 if ($this->page > 0) { 01511 // Page footer 01512 $this->InFooter = TRUE; 01513 $this->Footer(); 01514 $this->InFooter = FALSE; 01515 // Close page 01516 $this->_endpage(); 01517 } 01518 01519 // Do start the new page 01520 $this->_beginpage($orientation); 01521 // Sets line cap style to square 01522 $this->_out('2 J'); 01523 // Sets line width 01524 $this->LineWidth = $lw; 01525 $this->_out(sprintf('%.2f w', $lw * $this->k)); 01526 // Sets font 01527 if ($family) { 01528 $this->SetFont($family, $style, $size); 01529 } 01530 // Sets colors 01531 $this->DrawColor = $dc; 01532 if ($dc != '0 G') { 01533 $this->_out($dc); 01534 } 01535 $this->FillColor = $fc; 01536 if ($fc != '0 g') { 01537 $this->_out($fc); 01538 } 01539 $this->TextColor = $tc; 01540 $this->ColorFlag = $cf; 01541 // Sets Page header 01542 $this->Header(); 01543 // Restores line width 01544 if ($this->LineWidth != $lw) { 01545 $this->LineWidth = $lw; 01546 $this->_out(sprintf('%.2f w', $lw * $this->k)); 01547 } 01548 // Restores font 01549 if ($family) { 01550 $this->SetFont($family, $style, $size); 01551 } 01552 // Restores colors 01553 if ($this->DrawColor!=$dc) { 01554 $this->DrawColor = $dc; 01555 $this->_out($dc); 01556 } 01557 if ($this->FillColor!=$fc) { 01558 $this->FillColor = $fc; 01559 $this->_out($fc); 01560 } 01561 $this->TextColor = $tc; 01562 $this->ColorFlag = $cf; 01563 } // end of the "AddPage()" method 01564 01565 01571 function Close() 01572 { 01573 // Terminates document 01574 if ($this->page == 0) { 01575 $this->AddPage(); 01576 } 01577 01578 // Displays the page footer 01579 $this->InFooter = TRUE; 01580 $this->Footer(); 01581 $this->InFooter = FALSE; 01582 01583 // Closes page and document 01584 $this->_endpage(); 01585 $this->_enddoc(); 01586 } // end of the "Close()" method 01587 01588 01596 function PageNo() 01597 { 01598 return $this->page; 01599 } // end of the "PageNo()" method 01600 01601 01611 function SetDrawColor($r, $g = -1, $b = -1) 01612 { 01613 if (($r == 0 && $g == 0 && $b == 0) || $g == -1) { 01614 $this->DrawColor = sprintf('%.3f G', $r / 255); 01615 } else { 01616 $this->DrawColor = sprintf('%.3f %.3f %.3f RG', $r / 255, $g / 255, $b / 255); 01617 } // end if... else... 01618 01619 // If a page is defined, applies this property 01620 if ($this->page > 0) { 01621 $this->_out($this->DrawColor); 01622 } 01623 } // end of the "SetDrawColor()" method 01624 01625 01635 function SetFillColor($r, $g = -1, $b =-1) 01636 { 01637 if (($r == 0 && $g == 0 && $b == 0) || $g == -1) { 01638 $this->FillColor = sprintf('%.3f g', $r / 255); 01639 } else { 01640 $this->FillColor = sprintf('%.3f %.3f %.3f rg', $r / 255, $g / 255, $b / 255); 01641 } // end if... else... 01642 01643 $this->ColorFlag = ($this->FillColor != $this->TextColor); 01644 01645 // If a page is defined, applies this property 01646 if ($this->page > 0) { 01647 $this->_out($this->FillColor); 01648 } 01649 } // end of the "SetDrawColor()" method 01650 01651 01661 function SetTextColor($r, $g = -1, $b =-1) 01662 { 01663 if (($r == 0 && $g == 0 && $b == 0) || $g == -1) { 01664 $this->TextColor = sprintf('%.3f g', $r / 255); 01665 } else { 01666 $this->TextColor = sprintf('%.3f %.3f %.3f rg', $r / 255, $g / 255, $b / 255); 01667 } // end if... else... 01668 01669 $this->ColorFlag = ($this->FillColor != $this->TextColor); 01670 } // end of the "SetTextColor()" method 01671 01672 01680 function SetLineWidth($width) 01681 { 01682 $this->LineWidth = $width; 01683 01684 // If a page is defined, applies this property 01685 if ($this->page > 0) { 01686 $this->_out(sprintf('%.2f w', $width * $this->k)); 01687 } 01688 } // end of the "SetLineWidth()" method 01689 01690 01701 function Line($x1, $y1, $x2, $y2) 01702 { 01703 $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)); 01704 } // end of the "Line()" method 01705 01706 01718 function Rect($x, $y, $w, $h, $style = '') 01719 { 01720 if ($style == 'F') { 01721 $op = 'f'; 01722 } else if ($style == 'FD' || $style=='DF') { 01723 $op = 'B'; 01724 } else { 01725 $op = 'S'; 01726 } // end if... else if... else 01727 01728 $this->_out(sprintf('%.2f %.2f %.2f %.2f re %s', $x * $this->k, ($this->h - $y) * $this->k, $w * $this->k, -$h * $this->k, $op)); 01729 } // end of the "Rect()" method 01730 01731 01741 function AddFont($family, $style = '', $file = '') 01742 { 01743 $family = strtolower($family); 01744 if ($family == 'arial') { 01745 $family = 'helvetica'; 01746 } 01747 01748 $style = strtoupper($style); 01749 if ($style == 'IB') { 01750 $style = 'BI'; 01751 } 01752 if (isset($this->fonts[$family . $style])) { 01753 $this->Error('Font already added: ' . $family . ' ' . $style); 01754 } 01755 if ($file == '') { 01756 $file = str_replace(' ', '', $family) . strtolower($style) . '.php'; 01757 } 01758 if (isset($GLOBALS['FPDF_font_path'])) { 01759 $file = $GLOBALS['FPDF_font_path'] . $file; 01760 } 01761 include($file); 01762 if (!isset($name)) { 01763 $this->Error('Could not include font definition file'); 01764 } 01765 01766 $i = count($this->fonts) + 1; 01767 $this->fonts[$family . $style] = array('i' => $i, 01768 'type' => $type, 01769 'name' => $name, 01770 'desc' => $desc, 01771 'up' => $up, 01772 'ut' => $ut, 01773 'cw' => $cw, 01774 'enc' => $enc, 01775 'file' => $file); 01776 // Searches existing encodings 01777 if ($diff) { 01778 $d = 0; 01779 $nb = count($this->diffs); 01780 for ($i = 1; $i <= $nb; $i++) { 01781 if ($this->diffs[$i] == $diff) { 01782 $d = $i; 01783 break; 01784 } // end if 01785 } // end for 01786 if ($d == 0) { 01787 $d = $nb + 1; 01788 $this->diffs[$d] = $diff; 01789 } // end if 01790 $this->fonts[$family . $style]['diff'] = $d; 01791 } // end if 01792 01793 if ($file) { 01794 if ($type == 'TrueType') { 01795 $this->FontFiles[$file] = array('length1' => $originalsize); 01796 } else { 01797 $this->FontFiles[$file] = array('length1' => $size1, 'length2' => $size2); 01798 } 01799 } // end if 01800 } // end of the "AddFont()" method 01801 01802 01810 function SetFontSize($size) 01811 { 01812 if ($this->FontSizePt == $size) { 01813 return; 01814 } 01815 $this->FontSizePt = $size; 01816 $this->FontSize = $size / $this->k; 01817 if ($this->page > 0) { 01818 $this->_out(sprintf('BT /F%d %.2f Tf ET', $this->CurrentFont['i'], $this->FontSizePt)); 01819 } 01820 } // end of the "SetFontSize()" method 01821 01822 01830 function AddLink() 01831 { 01832 $n = count($this->links) + 1; 01833 $this->links[$n] = array(0, 0); 01834 return $n; 01835 } // end of the "AddLink()" method 01836 01837 01847 function SetLink($link, $y = 0, $page = -1) 01848 { 01849 if ($y == -1) { 01850 $y = $this->y; 01851 } 01852 if ($page == -1) { 01853 $page = $this->page; 01854 } 01855 $this->links[$link] = array($page, $y); 01856 } // end of the "SetLink()" method 01857 01858 01870 function Link($x, $y, $w, $h, $link) 01871 { 01872 $this->PageLinks[$this->page][] = array($x * $this->k, 01873 $this->hPt - $y * $this->k, 01874 $w * $this->k, 01875 $h * $this->k, 01876 $link); 01877 } // end of the "Link()" method 01878 01879 01889 function Text($x, $y, $txt) 01890 { 01891 $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt))); 01892 $s = sprintf('BT %.2f %.2f Td (%s) Tj ET', $x * $this->k, ($this->h - $y) * $this->k, $txt); 01893 if ($this->underline && $txt != '') { 01894 $s .= ' ' . $this->_dounderline($x, $y, $txt); 01895 } 01896 if ($this->ColorFlag) { 01897 $s = 'q ' . $this->TextColor . ' ' . $s . ' Q'; 01898 } 01899 $this->_out($s); 01900 } // end of the "Text()" method 01901 01902 01910 function AcceptPageBreak() 01911 { 01912 return $this->AutoPageBreak; 01913 } // end of the "AcceptPageBreak()" method 01914 01915 01930 function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '') 01931 { 01932 $k = $this->k; 01933 01934 if ($this->y + $h > $this->PageBreakTrigger 01935 && !$this->InFooter 01936 && $this->AcceptPageBreak()) { 01937 $x = $this->x; 01938 $ws = $this->ws; 01939 if ($ws > 0) { 01940 $this->ws = 0; 01941 $this->_out('0 Tw'); 01942 } 01943 $this->AddPage($this->CurOrientation); 01944 $this->x = $x; 01945 if ($ws > 0) { 01946 $this->ws = $ws; 01947 $this->_out(sprintf('%.3f Tw', $ws * $k)); 01948 } 01949 } // end if 01950 01951 if ($w == 0) { 01952 $w = $this->w - $this->rMargin - $this->x; 01953 } 01954 01955 $s = ''; 01956 if ($fill == 1 || $border == 1) { 01957 if ($fill == 1) { 01958 $op = ($border == 1) ? 'B' : 'f'; 01959 } else { 01960 $op = 'S'; 01961 } 01962 $s = sprintf('%.2f %.2f %.2f %.2f re %s ', $this->x * $k, ($this->h - $this->y) * $k, $w * $k, -$h * $k, $op); 01963 } // end if 01964 01965 if (is_string($border)) { 01966 $x = $this->x; 01967 $y = $this->y; 01968 if (strpos(' ' . $border, 'L')) { 01969 $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, $x * $k, ($this->h - ($y+$h)) * $k); 01970 } 01971 if (strpos(' ' . $border, 'T')) { 01972 $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - $y) * $k); 01973 } 01974 if (strpos(' ' . $border, 'R')) { 01975 $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', ($x + $w) * $k, ($this->h - $y) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k); 01976 } 01977 if (strpos(' ' . $border, 'B')) { 01978 $s .= sprintf('%.2f %.2f m %.2f %.2f l S ', $x * $k, ($this->h - ($y + $h)) * $k, ($x + $w) * $k, ($this->h - ($y + $h)) * $k); 01979 } 01980 } // end if 01981 01982 if ($txt != '') { 01983 if ($align == 'R') { 01984 $dx = $w - $this->cMargin - $this->GetStringWidth($txt); 01985 } 01986 else if ($align == 'C') { 01987 $dx = ($w - $this->GetStringWidth($txt)) / 2; 01988 } 01989 else { 01990 $dx = $this->cMargin; 01991 } 01992 $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt))); 01993 if ($this->ColorFlag) { 01994 $s .= 'q ' . $this->TextColor . ' '; 01995 } 01996 $s .= sprintf('BT %.2f %.2f Td (%s) Tj ET', ($this->x + $dx) * $k, ($this->h - ($this->y + .5 * $h + .3 * $this->FontSize)) * $k, $txt); 01997 if ($this->underline) { 01998 $s .= ' ' . $this->_dounderline($this->x+$dx, $this->y + .5 * $h + .3 * $this->FontSize, $txt); 01999 } 02000 if ($this->ColorFlag) { 02001 $s .= ' Q'; 02002 } 02003 if ($link) { 02004 $this->Link($this->x + $dx, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link); 02005 } 02006 } // end if 02007 02008 if ($s) { 02009 $this->_out($s); 02010 } 02011 $this->lasth = $h; 02012 02013 if ($ln > 0) { 02014 // Go to next line 02015 $this->y += $h; 02016 if ($ln == 1) { 02017 $this->x = $this->lMargin; 02018 } 02019 } else { 02020 $this->x += $w; 02021 } 02022 } // end of the "Cell()" method 02023 02024 02037 function MultiCell($w, $h, $txt, $border = 0, $align = 'J', $fill = 0) 02038 { 02039 // loic1: PHP3 compatibility 02040 // $cw = &$this->CurrentFont['cw']; 02041 if ($w == 0) { 02042 $w = $this->w - $this->lMargin - $this->x; 02043 } 02044 $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize; 02045 $s = str_replace("\r", '', $txt); 02046 $nb = strlen($s); 02047 if ($nb>0 && $s[$nb - 1] == "\n") { 02048 $nb--; 02049 } 02050 02051 $b = 0; 02052 if ($border) { 02053 if ($border == 1) { 02054 $border = 'LTRB'; 02055 $b = 'LRT'; 02056 $b2 = 'LR'; 02057 } 02058 else { 02059 $b2 = ''; 02060 if (strpos(' ' . $border, 'L')) { 02061 $b2 .= 'L'; 02062 } 02063 if (strpos(' ' . $border, 'R')) { 02064 $b2 .= 'R'; 02065 } 02066 $b = (strpos(' ' . $border, 'T')) ? $b2 . 'T' : $b2; 02067 } // end if... else... 02068 } // end if 02069 02070 $sep = -1; 02071 $i = 0; 02072 $j = 0; 02073 $l = 0; 02074 $ns = 0; 02075 $nl = 1; 02076 while ($i < $nb) { 02077 // Gets next character 02078 $c = $s[$i]; 02079 02080 // Explicit line break 02081 if ($c == "\n") { 02082 if ($this->ws > 0) { 02083 $this->ws = 0; 02084 $this->_out('0 Tw'); 02085 } 02086 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill); 02087 $i++; 02088 $sep = -1; 02089 $j = $i; 02090 $l = 0; 02091 $ns = 0; 02092 $nl++; 02093 if ($border && $nl == 2) { 02094 $b = $b2; 02095 } 02096 continue; 02097 } // end if 02098 02099 // Space character 02100 if ($c == ' ') { 02101 $sep = $i; 02102 $ls = $l; 02103 $ns++; 02104 } // end if 02105 02106 $l += $this->CurrentFont['cw'][$c]; 02107 if ($l > $wmax) { 02108 // Automatic line break 02109 if ($sep == -1) { 02110 if ($i == $j) { 02111 $i++; 02112 } 02113 if ($this->ws > 0) { 02114 $this->ws = 0; 02115 $this->_out('0 Tw'); 02116 } 02117 $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill); 02118 } 02119 else { 02120 if ($align == 'J') { 02121 $this->ws = ($ns > 1) 02122 ? ($wmax - $ls) / 1000 * $this->FontSize / ($ns - 1) 02123 : 0; 02124 $this->_out(sprintf('%.3f Tw', $this->ws * $this->k)); 02125 } 02126 $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill); 02127 $i = $sep + 1; 02128 } // end if... else... 02129 02130 $sep = -1; 02131 $j = $i; 02132 $l = 0; 02133 $ns = 0; 02134 $nl++; 02135 if ($border && $nl == 2) { 02136 $b = $b2; 02137 } 02138 } 02139 else { 02140 $i++; 02141 } // end if... else 02142 } // end while 02143 02144 // Last chunk 02145 if ($this->ws > 0) { 02146 $this->ws = 0; 02147 $this->_out('0 Tw'); 02148 } 02149 02150 if ($border && strpos(' ' . $border, 'B')) { 02151 $b .= 'B'; 02152 } 02153 $this->Cell($w, $h, substr($s, $j, $i), $b, 2, $align, $fill); 02154 $this->x = $this->lMargin; 02155 } // end of the "MultiCell()" method 02156 02157 02167 function Write($h, $txt, $link = '') 02168 { 02169 $w = $this->w - $this->rMargin - $this->x; 02170 $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize; 02171 $s = str_replace("\r", '', $txt); 02172 $nb = strlen($s); 02173 $sep = -1; 02174 $i = 0; 02175 $j = 0; 02176 $l = 0; 02177 $nl = 1; 02178 02179 while ($i < $nb) { 02180 // Gets next character 02181 $c = $s[$i]; 02182 02183 // Explicit line break 02184 if ($c == "\n") { 02185 $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link); 02186 $i++; 02187 $sep = -1; 02188 $j = $i; 02189 $l = 0; 02190 if ($nl == 1) { 02191 $this->x = $this->lMargin; 02192 $w = $this->w - $this->rMargin - $this->x; 02193 $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize; 02194 } 02195 $nl++; 02196 continue; 02197 } 02198 02199 // Space character 02200 if ($c == ' ') { 02201 $sep = $i; 02202 $ls = $l; 02203 } // end if 02204 02205 $l += $this->CurrentFont['cw'][$c]; 02206 if ($l > $wmax) { 02207 // Automatic line break 02208 if ($sep == -1) { 02209 if($this->x > $this->lMargin) { 02210 // Move to next line 02211 $this->x =$this->lMargin; 02212 $this->y +=$h; 02213 $w = $this->w - $this->rMargin - $this->x; 02214 $wmax =($w - 2 * $this->cMargin) * 1000 / $this->FontSize; 02215 $i++; 02216 $nl++; 02217 continue; 02218 } 02219 if ($i == $j) { 02220 $i++; 02221 } 02222 $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link); 02223 } 02224 else { 02225 $this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link); 02226 $i = $sep + 1; 02227 } // end if... else... 02228 02229 $sep = -1; 02230 $j = $i; 02231 $l = 0; 02232 if ($nl == 1) { 02233 $this->x = $this->lMargin; 02234 $w = $this->w - $this->rMargin - $this->x; 02235 $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize; 02236 } 02237 $nl++; 02238 } 02239 else { 02240 $i++; 02241 } // end if... else... 02242 } // end while 02243 02244 // Last chunk 02245 if ($i != $j) { 02246 $this->Cell($l / 1000 * $this->FontSize, $h, substr($s, $j, $i), 0, 0, '', 0, $link); 02247 } 02248 } // end of the "Write()" method 02249 02250 02264 function Image($file, $x, $y, $w, $h = 0, $type = '', $link = '') 02265 { 02266 if (!isset($this->images[$file])) { 02267 // First use of image, get info 02268 if ($type == '') { 02269 $pos = strrpos($file, '.'); 02270 if (!$pos) { 02271 $this->Error('Image file has no extension and no type was specified: ' . $file); 02272 } 02273 $type = substr($file, $pos + 1); 02274 } // end if 02275 02276 $type = strtolower($type); 02277 $mqr = get_magic_quotes_runtime(); 02278 set_magic_quotes_runtime(0); 02279 if ($type == 'jpg' || $type == 'jpeg') { 02280 $info = $this->_parsejpg($file); 02281 } 02282 else if ($type == 'png') { 02283 $info = $this->_parsepng($file); 02284 } 02285 else { 02286 $this->Error('Unsupported image file type: ' . $type); 02287 } 02288 set_magic_quotes_runtime($mqr); 02289 $info['i'] = count($this->images) + 1; 02290 $this->images[$file] = $info; 02291 } 02292 else { 02293 $info = $this->images[$file]; 02294 } // end if... else... 02295 02296 // Automatic width or height calculation 02297 if ($w == 0) { 02298 $w = $h * $info['w'] / $info['h']; 02299 } 02300 if ($h == 0) { 02301 $h = $w * $info['h'] / $info['w']; 02302 } 02303 $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'])); 02304 02305 if ($link) { 02306 $this->Link($x, $y, $w, $h, $link); 02307 } 02308 } // end of the "Image()" method 02309 02310 02318 function Ln($h = '') 02319 { 02320 $this->x = $this->lMargin; 02321 // Sets default line height to last cell height 02322 if (is_string($h)) { 02323 $this->y += $this->lasth; 02324 } 02325 else { 02326 $this->y += $h; 02327 } 02328 } // end of the "Ln()" method 02329 02330 02338 function GetX() 02339 { 02340 return $this->x; 02341 } // end of the "GetX()" method 02342 02343 02351 function SetX($x) 02352 { 02353 if ($x >= 0) { 02354 $this->x = $x; 02355 } else { 02356 $this->x = $this->w + $x; 02357 } 02358 } // end of the "SetX()" method 02359 02360 02368 function GetY() 02369 { 02370 return $this->y; 02371 } // end of the "GetY()" method 02372 02373 02381 function SetY($y) 02382 { 02383 $this->x = $this->lMargin; 02384 if ($y >= 0) { 02385 $this->y = $y; 02386 } else { 02387 $this->y = $this->h + $y; 02388 } 02389 } // end of the "SetY()" method 02390 02391 02400 function SetXY($x,$y) 02401 { 02402 $this->SetY($y); 02403 $this->SetX($x); 02404 } // end of the "SetXY()" method 02405 02406 02419 function Output($file = '', $download = FALSE) 02420 { 02421 global $HTTP_USER_AGENT; 02422 02423 if ($this->state < 3) { 02424 $this->Close(); 02425 } 02426 02427 // Send to browser 02428 if ($file == '') { 02429 header('Content-Type: application/pdf'); 02430 if (headers_sent()) { 02431 $this->Error('Some data has already been output to browser, can\'t send PDF file'); 02432 } 02433 header('Content-Length: ' . strlen($this->buffer)); 02434 header('Content-Disposition: inline; filename=doc.pdf'); 02435 echo $this->buffer; 02436 } 02437 // Download file 02438 else if ($download) { 02439 if (!empty($HTTP_USER_AGENT) 02440 && (strpos($HTTP_USER_AGENT, 'MSIE 5.5') || strpos($HTTP_USER_AGENT, 'Opera'))) { 02441 header('Content-Type: application/dummy'); 02442 } 02443 // fix for Gecko-based browsers < 1.1 02444 else if (!empty($HTTP_USER_AGENT) 02445 && (strpos($HTTP_USER_AGENT, 'Gecko') && 02446 (strpos($HTTP_USER_AGENT, 'rv:0.') || strpos($HTTP_USER_AGENT, 'rv:1.0') || strpos($HTTP_USER_AGENT, 'rv:1.1')))) { 02447 header('Content-Type: application/'); 02448 } 02449 else { 02450 header('Content-Type: application/pdf'); 02451 } 02452 if (headers_sent()) { 02453 $this->Error('Some data has already been output to browser, can\'t send PDF file'); 02454 } 02455 header('Content-Length: ' . strlen($this->buffer)); 02456 header('Content-Disposition: attachment; filename=' . $file); 02457 echo $this->buffer; 02458 } 02459 // Save file locally 02460 else { 02461 $f = fopen($file, 'wb'); 02462 if (!$f) { 02463 $this->Error('Unable to create output file: ' . $file); 02464 } 02465 fwrite($f, $this->buffer, strlen($this->buffer)); 02466 fclose($f); 02467 } // end if... else if... else 02468 } // end of the "Output()" method 02469 02470 } // End of the "FPDF" class 02471 02472 02473 02477 if (!empty($_ENV) && isset($_ENV['HTTP_USER_AGENT'])) { 02478 $HTTP_USER_AGENT = $_ENV['HTTP_USER_AGENT']; 02479 } 02480 else if (!empty($_SERVER) && isset($_SERVER['HTTP_USER_AGENT'])) { 02481 $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT']; 02482 } 02483 else if (@getenv('HTTP_USER_AGENT')) { 02484 $HTTP_USER_AGENT = getenv('HTTP_USER_AGENT'); 02485 } 02486 02487 if ($HTTP_USER_AGENT == 'contype') { 02488 header('Content-Type: application/pdf'); 02489 exit(); 02490 } 02491 ?>