Source for file fpdf.php
Documentation is available at fpdf.php
/*******************************************************************************
* Author: Olivier PLATHEY *
* You may use, modify and redistribute this software as you wish. *
*******************************************************************************/
define('FPDF_VERSION','1.53');
var $page; //current page number
var $n; //current object number
var $buffer; //buffer holding in-memory PDF
var $pages; //array containing pages
var $state; //current document state
var $k; //scale factor (number of points in user unit)
var $fwPt,$fhPt; //dimensions of page format in points
var $fw,$fh; //dimensions of page format in user unit
var $wPt,$hPt; //current dimensions of page in points
var $w,$h; //current dimensions of page in user unit
var $x,$y; //current position in user unit for cell positioning
var $lasth; //height of last cell printed
var $fonts; //array of used fonts
var $diffs; //array of encoding differences
var $images; //array of used images
var $links; //array of internal links
var $FontSize; //current font size in user unit
var $ColorFlag; //indicates whether fill and text colors are different
var $InFooter; //flag set when processing footer
/*******************************************************************************
*******************************************************************************/
function FPDF($orientation=
'P',$unit=
'mm',$format=
'A4')
//Initialization of properties
$this->CoreFonts=
array('courier'=>
'Courier','courierB'=>
'Courier-Bold','courierI'=>
'Courier-Oblique','courierBI'=>
'Courier-BoldOblique',
'helvetica'=>
'Helvetica','helveticaB'=>
'Helvetica-Bold','helveticaI'=>
'Helvetica-Oblique','helveticaBI'=>
'Helvetica-BoldOblique',
'times'=>
'Times-Roman','timesB'=>
'Times-Bold','timesI'=>
'Times-Italic','timesBI'=>
'Times-BoldItalic',
'symbol'=>
'Symbol','zapfdingbats'=>
'ZapfDingbats');
$this->Error('Incorrect unit: '.
$unit);
$format=
array(841.89,1190.55);
$format=
array(595.28,841.89);
$format=
array(420.94,595.28);
elseif($format==
'letter')
$this->Error('Unknown page format: '.
$format);
$this->fwPt=
$format[0]*
$this->k;
$this->fhPt=
$format[1]*
$this->k;
if($orientation==
'p' ||
$orientation==
'portrait')
elseif($orientation==
'l' ||
$orientation==
'landscape')
$this->Error('Incorrect orientation: '.
$orientation);
$this->w=
$this->wPt/
$this->k;
$this->h=
$this->hPt/
$this->k;
//Interior cell margin (1 mm)
//Full width display mode
//Set default PDF version number
//Set left, top and right margins
if($this->page>
0 &&
$this->x<
$margin)
//Set auto page break mode and triggering margin
//Set display mode in viewer
if($zoom==
'fullpage' ||
$zoom==
'fullwidth' ||
$zoom==
'real' ||
$zoom==
'default' ||
!is_string($zoom))
$this->Error('Incorrect zoom display mode: '.
$zoom);
if($layout==
'single' ||
$layout==
'continuous' ||
$layout==
'two' ||
$layout==
'default')
$this->Error('Incorrect layout display mode: '.
$layout);
//Define an alias for total number of pages
die('<B>FPDF error: </B>'.
$msg);
//Set line cap style to square
$this->SetFont($family,$style,$size);
$this->SetFont($family,$style,$size);
//To be implemented in your own inherited class
//To be implemented in your own inherited class
//Get current page number
//Set color for all stroking operations
if(($r==
0 &&
$g==
0 &&
$b==
0) ||
$g==-
1)
//Set color for all filling operations
if(($r==
0 &&
$g==
0 &&
$b==
0) ||
$g==-
1)
if(($r==
0 &&
$g==
0 &&
$b==
0) ||
$g==-
1)
//Get width of a string in the current font
function Line($x1,$y1,$x2,$y2)
$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));
function Rect($x,$y,$w,$h,$style=
'')
elseif($style==
'FD' ||
$style==
'DF')
$this->_out(sprintf('%.2f %.2f %.2f %.2f re %s',$x*
$this->k,($this->h-
$y)*
$this->k,$w*
$this->k,-
$h*
$this->k,$op));
function AddFont($family,$style=
'',$file=
'')
//Add a TrueType or Type1 font
if(isset
($this->fonts[$fontkey]))
$this->Error('Font already added: '.
$family.
' '.
$style);
$this->Error('Could not include font definition file');
$this->fonts[$fontkey]=
array('i'=>
$i,'type'=>
$type,'name'=>
$name,'desc'=>
$desc,'up'=>
$up,'ut'=>
$ut,'cw'=>
$cw,'enc'=>
$enc,'file'=>
$file);
//Search existing encodings
if($this->diffs[$i]==
$diff)
$this->fonts[$fontkey]['diff']=
$d;
$this->FontFiles[$file]=
array('length1'=>
$originalsize);
$this->FontFiles[$file]=
array('length1'=>
$size1,'length2'=>
$size2);
function SetFont($family,$style=
'',$size=
0)
//Select a font; size given in points
elseif($family==
'symbol' ||
$family==
'zapfdingbats')
if(strpos($style,'U')!==
false)
//Test if font is already selected
//Test if used for the first time
if(!isset
($this->fonts[$fontkey]))
//Check if one of the standard fonts
if(!isset
($fpdf_charwidths[$fontkey]))
if($family==
'times' ||
$family==
'helvetica')
if(!isset
($fpdf_charwidths[$fontkey]))
$this->Error('Could not include font metric file');
$this->fonts[$fontkey]=
array('i'=>
$i,'type'=>
'core','name'=>
$this->CoreFonts[$fontkey],'up'=>-
100,'ut'=>
50,'cw'=>
$fpdf_charwidths[$fontkey]);
$this->Error('Undefined font: '.
$family.
' '.
$style);
//Set font size in points
//Create a new internal link
$this->links[$n]=
array(0,0);
function SetLink($link,$y=
0,$page=-
1)
//Set destination of internal link
$this->links[$link]=
array($page,$y);
function Link($x,$y,$w,$h,$link)
$this->PageLinks[$this->page][]=
array($x*
$this->k,$this->hPt-
$y*
$this->k,$w*
$this->k,$h*
$this->k,$link);
function Text($x,$y,$txt)
$s=
sprintf('BT %.2f %.2f Td (%s) Tj ET',$x*
$this->k,($this->h-
$y)*
$this->k,$this->_escape($txt));
//Accept automatic page break or not
function Cell($w,$h=
0,$txt=
'',$border=
0,$ln=
0,$align=
'',$fill=
0,$link=
'')
if($fill==
1 ||
$border==
1)
$op=
($border==
1) ?
'B' :
'f';
$s=
sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*
$k,($this->h-
$this->y)*
$k,$w*
$k,-
$h*
$k,$op);
if(strpos($border,'L')!==
false)
$s.=
sprintf('%.2f %.2f m %.2f %.2f l S ',$x*
$k,($this->h-
$y)*
$k,$x*
$k,($this->h-
($y+
$h))*
$k);
if(strpos($border,'T')!==
false)
$s.=
sprintf('%.2f %.2f m %.2f %.2f l S ',$x*
$k,($this->h-
$y)*
$k,($x+
$w)*
$k,($this->h-
$y)*
$k);
if(strpos($border,'R')!==
false)
$s.=
sprintf('%.2f %.2f m %.2f %.2f l S ',($x+
$w)*
$k,($this->h-
$y)*
$k,($x+
$w)*
$k,($this->h-
($y+
$h))*
$k);
if(strpos($border,'B')!==
false)
$s.=
sprintf('%.2f %.2f m %.2f %.2f l S ',$x*
$k,($this->h-
($y+
$h))*
$k,($x+
$w)*
$k,($this->h-
($y+
$h))*
$k);
$s.=
sprintf('BT %.2f %.2f Td (%s) Tj ET',($this->x+
$dx)*
$k,($this->h-
($this->y+
.5*
$h+
.3*
$this->FontSize))*
$k,$txt2);
function MultiCell($w,$h,$txt,$border=
0,$align=
'J',$fill=
0)
//Output text with automatic or explicit line breaks
if($nb>
0 &&
$s[$nb-
1]==
"\n")
if(strpos($border,'L')!==
false)
if(strpos($border,'R')!==
false)
$b=
(strpos($border,'T')!==
false) ?
$b2.
'T' :
$b2;
$this->Cell($w,$h,substr($s,$j,$i-
$j),$b,2,$align,$fill);
$this->Cell($w,$h,substr($s,$j,$i-
$j),$b,2,$align,$fill);
$this->ws=
($ns>
1) ?
($wmax-
$ls)/
1000*
$this->FontSize/
($ns-
1) :
0;
$this->Cell($w,$h,substr($s,$j,$sep-
$j),$b,2,$align,$fill);
if($border &&
strpos($border,'B')!==
false)
$this->Cell($w,$h,substr($s,$j,$i-
$j),$b,2,$align,$fill);
function Write($h,$txt,$link=
'')
//Output text in flowing mode
$this->Cell($w,$h,substr($s,$j,$i-
$j),0,2,'',0,$link);
$this->Cell($w,$h,substr($s,$j,$i-
$j),0,2,'',0,$link);
$this->Cell($w,$h,substr($s,$j,$sep-
$j),0,2,'',0,$link);
function Image($file,$x,$y,$w=
0,$h=
0,$type=
'',$link=
'')
//Put an image on the page
if(!isset
($this->images[$file]))
//First use of image, get info
$this->Error('Image file has no extension and no type was specified: '.
$file);
if($type==
'jpg' ||
$type==
'jpeg')
//Allow for additional formats
$this->Error('Unsupported image type: '.
$type);
$info=
$this->$mtd($file);
//Automatic width and height calculation if needed
$w=
$h*
$info['w']/
$info['h'];
$h=
$w*
$info['h']/
$info['w'];
$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']));
$this->Link($x,$y,$w,$h,$link);
//Line feed; default value is last cell height
//Set y position and reset x
function Output($name=
'',$dest=
'')
//Output PDF to some destination
//Finish document if necessary
//Send to standard output
$this->Error('Some data has already been output, can\'t send PDF file');
header('Content-Type: application/pdf');
$this->Error('Some data has already been output to browser, can\'t send PDF file');
header('Content-disposition: inline; filename="'.
$name.
'"');
$this->Error('Some data has already been output, can\'t send PDF file');
if(isset
($_SERVER['HTTP_USER_AGENT']) &&
strpos($_SERVER['HTTP_USER_AGENT'],'MSIE'))
header('Content-Type: application/force-download');
header('Content-Type: application/octet-stream');
$this->Error('Some data has already been output to browser, can\'t send PDF file');
header('Content-disposition: attachment; filename="'.
$name.
'"');
$this->Error('Unable to create output file: '.
$name);
$this->Error('Incorrect output destination: '.
$dest);
/*******************************************************************************
*******************************************************************************/
//Check for locale-related bug
$this->Error('Don\'t alter the locale before including class file');
//Check for decimal separator
return defined('FPDF_FONTPATH') ?
FPDF_FONTPATH :
'';
//Replace number of pages
$filter=
($this->compress) ?
'/Filter /FlateDecode ' :
'';
$this->_out('<</Type /Page');
$this->_out('/Parent 1 0 R');
$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$hPt,$wPt));
$this->_out('/Resources 2 0 R');
$rect=
sprintf('%.2f %.2f %.2f %.2f',$pl[0],$pl[1],$pl[0]+
$pl[2],$pl[1]-
$pl[3]);
$annots.=
'<</Type /Annot /Subtype /Link /Rect ['.
$rect.
'] /Border [0 0 0] ';
$annots.=
'/A <</S /URI /URI '.
$this->_textstring($pl[4]).
'>>>>';
$annots.=
sprintf('/Dest [%d 0 R /XYZ 0 %.2f null]>>',1+
2*
$l[0],$h-
$l[1]*
$this->k);
$this->_out($annots.
']');
$this->_out('/Contents '.
($this->n+
1).
' 0 R>>');
$this->_out('<<'.
$filter.
'/Length '.
strlen($p).
'>>');
$this->_out('<</Type /Pages');
$this->_out('/Count '.
$nb);
$this->_out(sprintf('/MediaBox [0 0 %.2f %.2f]',$wPt,$hPt));
foreach($this->diffs as $diff)
$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences ['.
$diff.
']>>');
$this->Error('Font file not found');
$compressed=
(substr($file,-
2)==
'.z');
if(!$compressed && isset
($info['length2']))
$header=
(ord($font{0})==
128);
//Strip first binary header
if($header &&
ord($font{$info['length1']})==
128)
//Strip second binary header
$font=
substr($font,0,$info['length1']).
substr($font,$info['length1']+
6);
$this->_out('/Filter /FlateDecode');
$this->_out('/Length1 '.
$info['length1']);
if(isset
($info['length2']))
$this->_out('/Length2 '.
$info['length2'].
' /Length3 0');
foreach($this->fonts as $k=>
$font)
$this->fonts[$k]['n']=
$this->n+
1;
$this->_out('<</Type /Font');
$this->_out('/BaseFont /'.
$name);
$this->_out('/Subtype /Type1');
if($name!=
'Symbol' &&
$name!=
'ZapfDingbats')
$this->_out('/Encoding /WinAnsiEncoding');
elseif($type==
'Type1' ||
$type==
'TrueType')
//Additional Type1 or TrueType font
$this->_out('<</Type /Font');
$this->_out('/BaseFont /'.
$name);
$this->_out('/Subtype /'.
$type);
$this->_out('/FirstChar 32 /LastChar 255');
$this->_out('/Widths '.
($this->n+
1).
' 0 R');
$this->_out('/FontDescriptor '.
($this->n+
2).
' 0 R');
$this->_out('/Encoding '.
($nf+
$font['diff']).
' 0 R');
$this->_out('/Encoding /WinAnsiEncoding');
$s=
'<</Type /FontDescriptor /FontName /'.
$name;
foreach($font['desc'] as $k=>
$v)
$s.=
' /FontFile'.
($type==
'Type1' ?
'' :
'2').
' '.
$this->FontFiles[$file]['n'].
' 0 R';
//Allow for additional types
$this->Error('Unsupported font type: '.
$type);
$filter=
($this->compress) ?
'/Filter /FlateDecode ' :
'';
$this->images[$file]['n']=
$this->n;
$this->_out('<</Type /XObject');
$this->_out('/Subtype /Image');
$this->_out('/Width '.
$info['w']);
$this->_out('/Height '.
$info['h']);
if($info['cs']==
'Indexed')
$this->_out('/ColorSpace [/Indexed /DeviceRGB '.
(strlen($info['pal'])/
3-
1).
' '.
($this->n+
1).
' 0 R]');
$this->_out('/ColorSpace /'.
$info['cs']);
if($info['cs']==
'DeviceCMYK')
$this->_out('/Decode [1 0 1 0 1 0 1 0]');
$this->_out('/BitsPerComponent '.
$info['bpc']);
$this->_out('/Filter /'.
$info['f']);
if(isset
($info['parms']))
$this->_out($info['parms']);
if(isset
($info['trns']) &&
is_array($info['trns']))
for($i=
0;$i<
count($info['trns']);$i++
)
$trns.=
$info['trns'][$i].
' '.
$info['trns'][$i].
' ';
$this->_out('/Mask ['.
$trns.
']');
$this->_out('/Length '.
strlen($info['data']).
'>>');
unset
($this->images[$file]['data']);
if($info['cs']==
'Indexed')
$this->_out('<<'.
$filter.
'/Length '.
strlen($pal).
'>>');
foreach($this->images as $image)
$this->_out('/I'.
$image['i'].
' '.
$image['n'].
' 0 R');
$this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
foreach($this->fonts as $font)
$this->_out('/F'.
$font['i'].
' '.
$font['n'].
' 0 R');
$this->_out('/XObject <<');
$this->_out('/Type /Catalog');
$this->_out('/Pages 1 0 R');
$this->_out('/OpenAction [3 0 R /Fit]');
$this->_out('/OpenAction [3 0 R /FitH null]');
$this->_out('/OpenAction [3 0 R /XYZ null null 1]');
$this->_out('/OpenAction [3 0 R /XYZ null null '.
($this->ZoomMode/
100).
']');
$this->_out('/PageLayout /SinglePage');
$this->_out('/PageLayout /OneColumn');
$this->_out('/PageLayout /TwoColumnLeft');
$this->_out('/Size '.
($this->n+
1));
$this->_out('/Root '.
$this->n.
' 0 R');
$this->_out('/Info '.
($this->n-
1).
' 0 R');
$this->_out('0 '.
($this->n+
1));
$this->_out('0000000000 65535 f ');
for($i=
1;$i<=
$this->n;$i++
)
$this->_out('startxref');
$this->_out($this->n.
' 0 obj');
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);
//Extract info from a JPEG file
$this->Error('Missing or incorrect image file: '.
$file);
$this->Error('Not a JPEG file: '.
$file);
if(!isset
($a['channels']) ||
$a['channels']==
3)
elseif($a['channels']==
4)
$bpc=isset
($a['bits']) ?
$a['bits'] :
8;
return array('w'=>
$a[0],'h'=>
$a[1],'cs'=>
$colspace,'bpc'=>
$bpc,'f'=>
'DCTDecode','data'=>
$data);
//Extract info from a PNG file
$this->Error('Can\'t open image file: '.
$file);
$this->Error('Not a PNG file: '.
$file);
$this->Error('Incorrect PNG file: '.
$file);
$this->Error('16-bit depth not supported: '.
$file);
$this->Error('Alpha channel not supported: '.
$file);
$this->Error('Unknown compression method: '.
$file);
$this->Error('Unknown filter method: '.
$file);
$this->Error('Interlacing not supported: '.
$file);
$parms=
'/DecodeParms <</Predictor 15 /Colors '.
($ct==
2 ?
3 :
1).
' /BitsPerComponent '.
$bpc.
' /Columns '.
$w.
'>>';
//Scan chunks looking for palette, transparency and image data
if($colspace==
'Indexed' &&
empty($pal))
$this->Error('Missing palette in '.
$file);
return array('w'=>
$w,'h'=>
$h,'cs'=>
$colspace,'bpc'=>
$bpc,'f'=>
'FlateDecode','parms'=>
$parms,'pal'=>
$pal,'trns'=>
$trns,'data'=>
$data);
//Read a 4-byte integer from file
//Add \ before \, ( and )
$this->_out('endstream');
//Add a line to the document
//Handle special IE contype request
if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype')
header('Content-Type: application/pdf');
Documentation generated on Thu, 08 Jan 2009 17:44:13 +0100 by phpDocumentor 1.4.0a2