diff --git a/ChangeLog b/ChangeLog
index c1a9d0df9..6c065eeba 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,13 @@ phpMyAdmin - Changelog
$Id$
$Source$
+2002-05-28 Loïc Chapeaux
+ * db_details_structure.php3, lines 440-441; Documentation.html;
+ pdf_schema.php3; libraries/fpdf/*:
+ - updated the FPDF library to the 1.5 revision;
+ - rewrote it to make it PHP3 and xhtml compliant;
+ - coding standards.
+
2002-06-01 Alexander M. Turek
* lang/indonesian.inc.php3: Updates, thanks to Rachim Tamsjadi.
* lang/italian.inc.php3: Updates, thanks again to
diff --git a/Documentation.html b/Documentation.html
index 9a039b64b..a39339adc 100755
--- a/Documentation.html
+++ b/Documentation.html
@@ -1394,10 +1394,21 @@ $cfg['PmaAbsoluteUri'] = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://'
systems, too.
If you encounter this bug together with another OS and/or MySQL version or
you know how to work around it, please post a message into
-
+
our bug tracker at SourceForge.
+
+ I can't run the "display relations" feature because the script seems
+ not to know the font face I'm using!
+
+ The "FPDF" library we're using for this feature requires some
+ special files to use font faces.
+ Please refers to the
+ FPDF manual to build
+ these files.
+
+
[Configuration]
@@ -1912,7 +1923,7 @@ $cfg['PmaAbsoluteUri'] = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://'
put the modified files (tar'ed and gzip'ed) inside the patch tracker of
the
- phpMyAdmin SourceForge account .
+ phpMyAdmin SourceForge account .
@@ -2115,7 +2126,8 @@ code since version 2.1.0:
- Mike Beck <mike.beck at ibmiller.de> for his work on the Relation table
feature: automatic joint in QBE, links column in printview, Relation view.
- Maxime Delorme <delorme.maxime at free.fr> for the PDF schema output;
- thanks also to Olivier Plathey for the fpdf library (www.fpdf.org).
+ thanks also to Olivier Plathey for the "FPDF" library
+ (see http://www.fpdf.org/).
And also to the following people who have contributed minor changes,
diff --git a/db_details_structure.php3 b/db_details_structure.php3
index ba655fb1d..2b2ee7482 100644
--- a/db_details_structure.php3
+++ b/db_details_structure.php3
@@ -437,8 +437,7 @@ echo ' ' . ' ' . "\n";
= 40000
- && (!empty($cfg['Server']['table_coords']))
+if (!empty($cfg['Server']['table_coords'])
&& $num_tables > 0) {
?>
diff --git a/libraries/fpdf/README b/libraries/fpdf/README
index b862c11a8..fcf9526b1 100644
--- a/libraries/fpdf/README
+++ b/libraries/fpdf/README
@@ -1,3 +1,3 @@
-The official site for fdpf is http://www.fpdf.org
+The official site for fdpf is http://www.fpdf.org/
-This directory contains some files from the fpdf 1.41 distribution.
+This directory contains some files from the fpdf 1.5 distribution.
diff --git a/libraries/fpdf/fpdf.css b/libraries/fpdf/fpdf.css
deleted file mode 100644
index a9a789e96..000000000
--- a/libraries/fpdf/fpdf.css
+++ /dev/null
@@ -1,6 +0,0 @@
-H2 {color: #4000A0}
-.st {font-weight: bold; color: #A02020}
-A.demo {text-decoration: none; font-weight: bold; color: #0000CC}
-A.demo:link {text-decoration: none; font-weight: bold; color: #0000CC}
-A.demo:hover {text-decoration: none; font-weight: bold; color: #0000FF}
-A.demo:active {text-decoration: none; font-weight: bold; color: #0000FF}
diff --git a/libraries/fpdf/fpdf.php3 b/libraries/fpdf/fpdf.php3
index a8e86b78e..6cffc328e 100644
--- a/libraries/fpdf/fpdf.php3
+++ b/libraries/fpdf/fpdf.php3
@@ -1,1223 +1,2281 @@
page=0;
- $this->n=2;
- $this->buffer='';
- $this->pages=array();
- $this->OrientationChanges=array();
- $this->state=0;
- $this->fonts=array();
- $this->images=array();
- $this->InFooter=false;
- $this->FontFamily='';
- $this->FontStyle='';
- $this->FontSizePt=12;
- $this->DrawColor='0 G';
- $this->FillColor='0 g';
- $this->TextColor='0 g';
- $this->ColorFlag=false;
- $this->ws=0;
- //Font names
- $this->fontnames['courier']='Courier';
- $this->fontnames['courierB']='Courier-Bold';
- $this->fontnames['courierI']='Courier-Oblique';
- $this->fontnames['courierBI']='Courier-BoldOblique';
- $this->fontnames['helvetica']='Helvetica';
- $this->fontnames['helveticaB']='Helvetica-Bold';
- $this->fontnames['helveticaI']='Helvetica-Oblique';
- $this->fontnames['helveticaBI']='Helvetica-BoldOblique';
- $this->fontnames['times']='Times-Roman';
- $this->fontnames['timesB']='Times-Bold';
- $this->fontnames['timesI']='Times-Italic';
- $this->fontnames['timesBI']='Times-BoldItalic';
- $this->fontnames['symbol']='Symbol';
- $this->fontnames['zapfdingbats']='ZapfDingbats';
- //Scale factor
- if($unit=='pt')
- $this->k=1;
- elseif($unit=='mm')
- $this->k=72/25.4;
- elseif($unit=='cm')
- $this->k=72/2.54;
- elseif($unit=='in')
- $this->k=72;
- else
- $this->Error('Incorrect unit: '.$unit);
- //Page format
- if(is_string($format))
- {
- $format=strtolower($format);
- if($format=='a3')
- $format=array(841.89,1190.55);
- elseif($format=='a4')
- $format=array(595.28,841.89);
- elseif($format=='a5')
- $format=array(420.94,595.28);
- elseif($format=='letter')
- $format=array(612,792);
- elseif($format=='legal')
- $format=array(612,1008);
- else
- $this->Error('Unknown page format: '.$format);
- $this->fwPt=$format[0];
- $this->fhPt=$format[1];
- }
- else
- {
- $this->fwPt=round($format[0]*$this->k,2);
- $this->fhPt=round($format[1]*$this->k,2);
- }
- $this->fw=round($this->fwPt/$this->k,2);
- $this->fh=round($this->fhPt/$this->k,2);
- //Page orientation
- $orientation=strtolower($orientation);
- if($orientation=='p' or $orientation=='portrait')
- {
- $this->DefOrientation='P';
- $this->wPt=$this->fwPt;
- $this->hPt=$this->fhPt;
- }
- elseif($orientation=='l' or $orientation=='landscape')
- {
- $this->DefOrientation='L';
- $this->wPt=$this->fhPt;
- $this->hPt=$this->fwPt;
- }
- else
- $this->Error('Incorrect orientation: '.$orientation);
- $this->CurOrientation=$this->DefOrientation;
- $this->w=round($this->wPt/$this->k,2);
- $this->h=round($this->hPt/$this->k,2);
- //Page margins (1 cm)
- $margin=round(28.35/$this->k,2);
- $this->SetMargins($margin,$margin);
- //Interior cell margin (1 mm)
- $this->cMargin=$margin/10;
- //Line width (0.2 mm)
- $this->LineWidth=round(.567/$this->k,3);
- //Automatic page break
- $this->SetAutoPageBreak(true,2*$margin);
- //Full width display mode
- $this->SetDisplayMode('fullwidth');
- //Compression
- $this->SetCompression(true);
-}
-function SetMargins($left,$top)
-{
- //Set left and top margins
- $this->lMargin=$left;
- $this->tMargin=$top;
-}
-function SetLeftMargin($margin)
-{
- //Set left margin
- $this->lMargin=$margin;
-}
+ /**************************************************************************
+ * *
+ * Public methods below are used by some private ones. Then they *
+ * are placed at the top of the class. *
+ * *
+ **************************************************************************/
-function SetAutoPageBreak($auto,$margin=0)
-{
- //Set auto page break mode and triggering margin
- $this->AutoPageBreak=$auto;
- $this->bMargin=$margin;
- $this->PageBreakTrigger=$this->h-$margin;
-}
+ /**
+ * Gets the width of a string in the current font
+ *
+ * @param string The string to check
+ *
+ * @return double The string width
+ *
+ * @access public
+ */
+ function GetStringWidth($s)
+ {
+ $s = (string) $s;
+ // loic1: PHP3 compatibility
+ // $cw = &$this->CurrentFont['cw'];
+ $w = 0;
+ $l = strlen($s);
+ for ($i = 0; $i < $l; $i++) {
+ // $w += $cw[$s[$i]];
+ $w += $this->CurrentFont['cw'][$s[$i]];
+ } // end for
-function SetDisplayMode($mode,$z=100)
-{
- //Set display mode in viewer
- if($mode=='fullpage' or $mode=='fullwidth' or $mode=='real' or $mode=='default')
- $this->DisplayMode=$mode;
- elseif($mode=='zoom')
- $this->DisplayMode=$z;
- else
- $this->Error('Incorrect display mode: '.$mode);
-}
+ return $w * $this->FontSize / 1000;
+ } // end of the "GetStringWidth()" method
-function SetCompression($compress)
-{
- //Set page compression
- if(function_exists('gzcompress'))
- $this->compress=$compress;
- else
- $this->compress=false;
-}
-function SetTitle($title)
-{
- //Title of document
- $this->title=$title;
-}
+ /**
+ * Displays an error message then exists
+ *
+ * @param string The error message
+ *
+ * @access public
+ */
+ function Error($msg)
+ {
+ die('FPDF error: ' . $msg);
+ } // end of the "Error()" method
-function SetSubject($subject)
-{
- //Subject of document
- $this->subject=$subject;
-}
-function SetAuthor($author)
-{
- //Author of document
- $this->author=$author;
-}
-function SetKeywords($keywords)
-{
- //Keywords of document
- $this->keywords=$keywords;
-}
+ /**************************************************************************
+ * *
+ * Private methods *
+ * *
+ **************************************************************************/
-function SetCreator($creator)
-{
- //Creator of document
- $this->creator=$creator;
-}
+ /**
+ * Emulates the round function used with the "precision" argument under
+ * PHP3, just call the "round()" function else
+ *
+ * @param double The number to be rounded
+ * @param integer The precision (number of digits after the decimal)
+ *
+ * @return double The rounded number
+ *
+ * @access private
+ */
+ function _FPDF_round($val, $precision = 0)
+ {
+ return ($GLOBALS['FPDF_is_php4'])
+ ? round($val, $precision)
+ : (double) sprintf('%.' . $precision . 'f', $val);
+ } // end of the "_FPDF_round()" method
-function AliasNbPages($alias='{nb}')
-{
- //Define an alias for total number of pages
- $this->AliasNbPages=$alias;
-}
-function Error($msg)
-{
- //Fatal error
- die('FPDF error: '.$msg);
-}
+ /**
+ * Adds a line to the document
+ *
+ * @param string The string to add
+ *
+ * @access private
+ */
+ function _out($s)
+ {
+ if ($this->state == 2) {
+ $this->pages[$this->page] .= $s . "\n";
+ } else {
+ $this->buffer .= $s . "\n";
+ }
+ } // end of the "_out()" method
-function Open()
-{
- //Begin document
- $this->_begindoc();
-}
-function Close()
-{
- //Terminate document
- if($page=$this->page==0)
- $this->Error('Document contains no page');
- //Page footer
- $this->InFooter=true;
- $this->Footer();
- $this->InFooter=false;
- //Close page
- $this->_endpage();
- //Close document
- $this->_enddoc();
-}
+ /**
+ * Starts a new object
+ *
+ * @access private
+ */
+ function _newobj()
+ {
+ $this->n++;
+ $this->offsets[$this->n] = strlen($this->buffer);
+ $this->_out($this->n . ' 0 obj');
+ } // end of the "_newobj()" method
-function AddPage($orientation='')
-{
- //Start a new page
- $family=$this->FontFamily;
- $style=$this->FontStyle;
- $size=$this->FontSizePt;
- $lw=$this->LineWidth;
- $dc=$this->DrawColor;
- $fc=$this->FillColor;
- $tc=$this->TextColor;
- $cf=$this->ColorFlag;
- if($this->page>0)
- {
- //Page footer
- $this->InFooter=true;
- $this->Footer();
- $this->InFooter=false;
- //Close page
- $this->_endpage();
- }
- //Start new page
- $this->_beginpage($orientation);
- //Set line cap style to square
- $this->_out('2 J');
- //Set line width
- $this->_out($lw.' w');
- //Set font
- if($family)
- $this->SetFont($family,$style,$size);
- //Set colors
- if($dc!='0 G')
- $this->_out($dc);
- if($fc!='0 g')
- $this->_out($fc);
- $this->TextColor=$tc;
- $this->ColorFlag=$cf;
- //Page header
- $this->Header();
- //Restore line width
- if($this->LineWidth!=$lw)
- {
- $this->LineWidth=$lw;
- $this->_out($lw.' w');
- }
- //Restore font
- if($family)
- $this->SetFont($family,$style,$size);
- //Restore colors
- if($this->DrawColor!=$dc)
- {
- $this->DrawColor=$dc;
- $this->_out($dc);
- }
- if($this->FillColor!=$fc)
- {
- $this->FillColor=$fc;
- $this->_out($fc);
- }
- $this->TextColor=$tc;
- $this->ColorFlag=$cf;
-}
-function Header()
-{
- //To be implemented in your own inherited class
-}
+ /**
+ * Adds a "\" before "\", "(" and ")" characters
+ *
+ * @param string The string to slash
+ *
+ * @return integer The slashed string
+ *
+ * @access private
+ */
+ function _escape($s)
+ {
+ return str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $s)));
+ } // end of the "_escape()" method
-function Footer()
-{
- //To be implemented in your own inherited class
-}
-function PageNo()
-{
- //Get current page number
- return $this->page;
-}
+ /**
+ * Starts document
+ *
+ * @access private
+ */
+ function _begindoc()
+ {
+ $this->state = 1;
+ $this->_out('%PDF-1.3');
+ } // end of the "_begindoc()" method
-function SetDrawColor($r,$g=-1,$b=-1)
-{
- //Set color for all stroking operations
- if(($r==0 and $g==0 and $b==0) or $g==-1)
- $this->DrawColor=substr($r/255,0,5).' G';
- else
- $this->DrawColor=substr($r/255,0,5).' '.substr($g/255,0,5).' '.substr($b/255,0,5).' RG';
- if($this->page>0)
- $this->_out($this->DrawColor);
-}
+ /**
+ * Terminates document
+ *
+ * @access private
+ */
+ function _enddoc()
+ {
+ $nb = $this->page;
+ // Replace number of pages
+ if (!empty($this->AliasNbPages)) {
+ for ($n = 1; $n <= $nb; $n++) {
+ $this->pages[$n] = str_replace($this->AliasNbPages, $nb, $this->pages[$n]);
+ }
+ } // end if
-function SetFillColor($r,$g=-1,$b=-1)
-{
- //Set color for all filling operations
- if(($r==0 and $g==0 and $b==0) or $g==-1)
- $this->FillColor=substr($r/255,0,5).' g';
- else
- $this->FillColor=substr($r/255,0,5).' '.substr($g/255,0,5).' '.substr($b/255,0,5).' rg';
- $this->ColorFlag=($this->FillColor!=$this->TextColor);
- if($this->page>0)
- $this->_out($this->FillColor);
-}
+ if ($this->DefOrientation == 'P') {
+ $wPt = $this->fwPt;
+ $hPt = $this->fhPt;
+ }
+ else {
+ $wPt = $this->fhPt;
+ $hPt = $this->fwPt;
+ }
-function SetTextColor($r,$g=-1,$b=-1)
-{
- //Set color for text
- if(($r==0 and $g==0 and $b==0) or $g==-1)
- $this->TextColor=substr($r/255,0,5).' g';
- else
- $this->TextColor=substr($r/255,0,5).' '.substr($g/255,0,5).' '.substr($b/255,0,5).' rg';
- $this->ColorFlag=($this->FillColor!=$this->TextColor);
-}
+ $filter = ($this->compress) ? '/Filter /FlateDecode ' : '';
+ // Page
+ for ($n = 1; $n <= $nb; $n++) {
+ $this->_newobj();
+ $this->_out('<_out('/Parent 1 0 R');
+ if (isset($this->OrientationChanges[$n])) {
+ $this->_out('/MediaBox [0 0 ' . $hPt . ' ' . $wPt .']');
+ }
+ $this->_out('/Resources 2 0 R');
+ if (isset($this->PageLinks[$n])) {
+ $annots = '/Annots [';
+ reset($this->PageLinks[$n]);
+ while (list(, $pl) = each($this->PageLinks[$n])) {
+ $rect = $this->_FPDF_round($pl[0], 2) . ' '
+ . $this->_FPDF_round($pl[1], 2) . ' '
+ . $this->_FPDF_round($pl[0] + $pl[2], 2) . ' '
+ . $this->_FPDF_round($pl[1] - $pl[3], 2);
+ $annots .= '<>>>';
+ } else {
+ $l = $this->links[$pl[4]];
+ $annots .= '/Dest [' . ( 1 + 2 * $l[0]) . ' 0 R /XYZ 0 ' . $l[1] . ' null]>>';
+ }
+ } // end while
+ $this->_out($annots . ']');
+ } // end if
+ $this->_out('/Contents ' . ($this->n + 1) . ' 0 R>>');
+ $this->_out('endobj');
+ // Page content
+ $p = ($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
+ $this->_newobj();
+ $this->_out('<<' . $filter . '/Length ' . strlen($p) . '>>');
+ $this->_out('stream');
+ $this->_out($p . 'endstream');
+ $this->_out('endobj');
+ } // end for
-function GetStringWidth($s)
-{
- //Get width of a string in the current font
- global $fpdf_charwidths;
+ // Fonts
+ $nf = $this->n;
+ // Encodings
+ reset($this->diffs);
+ while (list(, $diff) = each($this->diffs)) {
+ $this->_newobj();
+ $this->_out('<>');
+ $this->_out('endobj');
+ } // end while
+ // Font file embedding
+ reset($this->FontFiles);
+ while (list($file, $info) = each($this->FontFiles)) {
+ $this->_newobj();
+ $this->FontFiles[$file]['n'] = $this->n;
+ // loic1: PHP3 compatibility
+ // if (defined('FPDF_FONTPATH')) {
+ // $file = FPDF_FONTPATH . $file;
+ // }
+ if (isset($GLOBALS['FPDF_font_path'])) {
+ $file = $GLOBALS['FPDF_font_path'] . $file;
+ }
+ $size = filesize($file);
+ if (!$size) {
+ $this->Error('Font file not found');
+ }
+ $this->_out('<_out('/Filter /FlateDecode');
+ }
+ $this->_out('/Length1 ' . $info['originalsize']);
+ $this->_out('>>');
+ $this->_out('stream');
+ $f = fopen($file, 'rb');
+ $this->_out(fread($f, $size));
+ fclose($f);
+ $this->_out('endstream');
+ $this->_out('endobj');
+ } // end while
+ // Font objects
+ reset($this->fonts);
+ while (list($k, $font) = each($this->fonts)) {
+ $this->_newobj();
+ $this->fonts[$k]['n'] = $this->n;
+ $name = $font['name'];
+ $this->_out('<_out('/BaseFont /' . $name);
+ // Standard font
+ if ($font['type'] == 'core') {
+ $this->_out('/Subtype /Type1');
+ if ($name != 'Symbol' && $name != 'ZapfDingbats') {
+ $this->_out('/Encoding /WinAnsiEncoding');
+ }
+ }
+ // TrueType
+ else {
+ $this->_out('/Subtype /TrueType');
+ $this->_out('/FirstChar 32');
+ $this->_out('/LastChar 255');
+ $this->_out('/Widths ' . ($this->n + 1) . ' 0 R');
+ $this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R');
+ if ($font['enc']) {
+ if (isset($font['diff'])) {
+ $this->_out('/Encoding ' . ($nf+$font['diff']) . ' 0 R');
+ } else {
+ $this->_out('/Encoding /WinAnsiEncoding');
+ }
+ }
+ } //end if... else...
+ $this->_out('>>');
+ $this->_out('endobj');
+ // Widths
+ if ($font['type'] != 'core') {
+ $this->_newobj();
+ // loic1: PHP3 compatibility
+ // $cw = &$font['cw'];
+ $s = '[';
+ for ($i = 32; $i <= 255; $i++) {
+ // $s .= $cw[chr($i)] . ' ';
+ $s .= $font['cw'][chr($i)] . ' ';
+ }
+ $this->_out($s.']');
+ $this->_out('endobj');
+ // Descriptor
+ $this->_newobj();
+ $s = '<FontFiles[$file]['n'] . ' 0 R';
+ }
+ $this->_out($s . '>>');
+ $this->_out('endobj');
+ } // end if
+ } // end while
- $cw=&$fpdf_charwidths[$this->FontFamily.$this->FontStyle];
- $w=0;
- $l=strlen($s);
- for($i=0;$i<$l;$i++)
- $w+=$cw[$s[$i]];
- return $w*$this->FontSize/1000;
-}
+ // Images
+ $ni = $this->n;
+ reset($this->images);
+ while (list($file, $info) = each($this->images)) {
+ $this->_newobj();
+ $this->_out('<_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]');
+ } else {
+ $this->_out('/ColorSpace /' . $info['cs']);
+ }
+ $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'])) {
+ $trns = '';
+ for ($i = 0; $i < count($info['trns']); $i++) {
+ $trns .= $info['trns'][$i] . ' ' . $info['trns'][$i] . ' ';
+ }
+ $this->_out('/Mask [' . $trns . ']');
+ } // end if
+ $this->_out('/Length ' . strlen($info['data']) . '>>');
+ $this->_out('stream');
+ $this->_out($info['data']);
+ $this->_out('endstream');
+ $this->_out('endobj');
+ // Palette
+ if ($info['cs'] == 'Indexed') {
+ $this->_newobj();
+ $this->_out('<>');
+ $this->_out('stream');
+ $this->_out($info['pal']);
+ $this->_out('endstream');
+ $this->_out('endobj');
+ } // end if
+ } // end while
-function SetLineWidth($width)
-{
- //Set line width
- $this->LineWidth=$width;
- if($this->page>0)
- $this->_out($width.' w');
-}
+ // Pages root
+ $this->offsets[1] = strlen($this->buffer);
+ $this->_out('1 0 obj');
+ $this->_out('<page; $i++) {
+ $kids .= (3+2*$i).' 0 R ';
+ }
+ $this->_out($kids . ']');
+ $this->_out('/Count ' . $this->page);
+ $this->_out('/MediaBox [0 0 ' . $wPt . ' ' . $hPt . ']');
+ $this->_out('>>');
+ $this->_out('endobj');
-function Line($x1,$y1,$x2,$y2)
-{
- //Draw a line
- $this->_out($x1.' -'.$y1.' m '.$x2.' -'.$y2.' l S');
-}
+ // Resources
+ $this->offsets[2] = strlen($this->buffer);
+ $this->_out('2 0 obj');
+ $this->_out('<_out('/Font <<');
+ reset($this->fonts);
+ while (list(, $font) = each($this->fonts)) {
+ $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R');
+ }
+ $this->_out('>>');
+ if (count($this->images)) {
+ $this->_out('/XObject <<');
+ $nbpal = 0;
+ reset($this->images);
+ while (list(, $info) = each($this->images)) {
+ $this->_out('/I' . $info['n'] . ' ' . ($ni + $info['n'] + $nbpal) . ' 0 R');
+ if ($info['cs'] == 'Indexed') {
+ $nbpal++;
+ }
+ } // end while
+ $this->_out('>>');
+ } // end if
+ $this->_out('>>');
+ $this->_out('endobj');
-function Rect($x,$y,$w,$h,$style='')
-{
- //Draw a rectangle
- if($style=='F')
- $op='f';
- elseif($style=='FD' or $style=='DF')
- $op='B';
- else
- $op='S';
- $this->_out($x.' -'.$y.' '.$w.' -'.$h.' re '.$op);
-}
+ // Info
+ $this->_newobj();
+ $this->_out('<title)) {
+ $this->_out('/Title (' . $this->_escape($this->title) . ')');
+ }
+ if (!empty($this->subject)) {
+ $this->_out('/Subject (' . $this->_escape($this->subject) . ')');
+ }
+ if (!empty($this->author)) {
+ $this->_out('/Author (' . $this->_escape($this->author) . ')');
+ }
+ if (!empty($this->keywords)) {
+ $this->_out('/Keywords (' . $this->_escape($this->keywords) . ')');
+ }
+ if (!empty($this->creator)) {
+ $this->_out('/Creator (' . $this->_escape($this->creator) . ')');
+ }
+ $this->_out('/CreationDate (D:' . date('YmdHis') . ')>>');
+ $this->_out('endobj');
-function SetFont($family,$style='',$size=0)
-{
- //Select a font; size given in points
- if(!$this->_setfont($family,$style,$size))
- $this->Error('Incorrect font family or style: '.$family.' '.$style);
-}
+ // Catalog
+ $this->_newobj();
+ $this->_out('<ZoomMode == 'fullpage') {
+ $this->_out('/OpenAction [3 0 R /Fit]');
+ }
+ else if ($this->ZoomMode == 'fullwidth') {
+ $this->_out('/OpenAction [3 0 R /FitH null]');
+ }
+ else if ($this->ZoomMode == 'real') {
+ $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
+ }
+ else if (!is_string($this->ZoomMode)) {
+ $this->_out('/OpenAction [3 0 R /XYZ null null ' . ($this->ZoomMode / 100) . ']');
+ }
+ if ($this->LayoutMode == 'single') {
+ $this->_out('/PageLayout /SinglePage');
+ }
+ else if ($this->LayoutMode == 'continuous') {
+ $this->_out('/PageLayout /OneColumn');
+ }
+ else if ($this->LayoutMode == 'two') {
+ $this->_out('/PageLayout /TwoColumnLeft');
+ }
+ $this->_out('/Pages 1 0 R>>');
+ $this->_out('endobj');
-function SetFontSize($size)
-{
- //Set font size in points
- $this->_setfontsize($size);
-}
+ // Cross-ref
+ $o = strlen($this->buffer);
+ $this->_out('xref');
+ $this->_out('0 ' . ($this->n + 1));
+ $this->_out('0000000000 65535 f ');
+ for ($i = 1; $i <= $this->n; $i++) {
+ $this->_out(sprintf('%010d 00000 n ', $this->offsets[$i]));
+ }
-function Text($x,$y,$txt)
-{
- //Output a string
- $txt=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
- $s='BT '.$x.' -'.$y.' Td ('.$txt.') Tj ET';
- if($this->ColorFlag)
- $s='q '.$this->TextColor.' '.$s.' Q';
- $this->_out($s);
-}
+ // Trailer
+ $this->_out('trailer');
+ $this->_out('<n + 1));
+ $this->_out('/Root ' . $this->n . ' 0 R');
+ $this->_out('/Info ' . ($this->n - 1) . ' 0 R>>');
+ $this->_out('startxref');
+ $this->_out($o);
+ $this->_out('%%EOF');
+ $this->state = 3;
+ } // end of the "_enddoc()" method
-function AcceptPageBreak()
-{
- //Accept automatic page break or not
- return $this->AutoPageBreak;
-}
-function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0)
-{
- //Output a cell
- if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
- {
- $x=$this->x;
- $ws=$this->ws;
- if($ws>0)
- $this->_out('0 Tw');
- $this->AddPage($this->CurOrientation);
- $this->x=$x;
- if($ws>0)
- $this->_out($ws.' Tw');
- }
- if($w==0)
- $w=$this->w-$this->lMargin-$this->x;
- $s='';
- if($fill==1 or $border==1)
- {
- $s.=$this->x.' -'.$this->y.' '.$w.' -'.$h.' re ';
- if($fill==1)
- $s.=($border==1) ? 'B ' : 'f ';
- else
- $s.='S ';
- }
- if(is_string($border))
- {
- $x=$this->x;
- $y=$this->y;
- if(is_int(strpos($border,'L')))
- $s.=$x.' -'.$y.' m '.$x.' -'.($y+$h).' l S ';
- if(is_int(strpos($border,'T')))
- $s.=$x.' -'.$y.' m '.($x+$w).' -'.$y.' l S ';
- if(is_int(strpos($border,'R')))
- $s.=($x+$w).' -'.$y.' m '.($x+$w).' -'.($y+$h).' l S ';
- if(is_int(strpos($border,'B')))
- $s.=$x.' -'.($y+$h).' m '.($x+$w).' -'.($y+$h).' l S ';
- }
- if($txt!='')
- {
- if($align=='R')
- $dx=$w-$this->cMargin-$this->GetStringWidth($txt);
- elseif($align=='C')
- $dx=($w-$this->GetStringWidth($txt))/2;
- else
- $dx=$this->cMargin;
- $txt=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt)));
- if($this->ColorFlag)
- $s.='q '.$this->TextColor.' ';
- $s.='BT '.($this->x+$dx).' -'.($this->y+.5*$h+.3*$this->FontSize).' Td ('.$txt.') Tj ET';
- if($this->ColorFlag)
- $s.=' Q';
- }
- if($s)
- $this->_out($s);
- $this->lasth=$h;
- if($ln>0)
- {
- //Go to next line
- $this->y+=$h;
- if($ln==1)
- $this->x=$this->lMargin;
- }
- else
- $this->x+=$w;
-}
+ /**
+ * Starts a new page
+ *
+ * @param string The page orientation
+ *
+ * @access private
+ */
+ function _beginpage($orientation)
+ {
+ $this->page++;
+ $this->pages[$this->page] = '';
+ $this->state = 2;
+ $this->x = $this->lMargin;
+ $this->y = $this->tMargin;
+ $this->lasth = 0;
+ $this->FontFamily = '';
-function MultiCell($w,$h,$txt,$border=0,$align='J',$fill=0)
-{
- //Output text with automatic or explicit line breaks
- global $fpdf_charwidths;
+ // Page orientation
+ if (!$orientation) {
+ $orientation = $this->DefOrientation;
+ } else {
+ $orientation = strtoupper($orientation[0]);
+ }
+ if ($orientation != $this->DefOrientation) {
+ $this->OrientationChanges[$this->page] = TRUE;
+ }
+ if ($orientation != $this->CurOrientation) {
+ // Changes orientation
+ if ($orientation == 'P') {
+ $this->wPt = $this->fwPt;
+ $this->hPt = $this->fhPt;
+ $this->w = $this->fw;
+ $this->h = $this->fh;
+ }
+ else {
+ $this->wPt = $this->fhPt;
+ $this->hPt = $this->fwPt;
+ $this->w = $this->fh;
+ $this->h = $this->fw;
+ }
+ $this->PageBreakTrigger = $this->h - $this->bMargin;
+ $this->CurOrientation = $orientation;
+ } // end if
- $cw=&$fpdf_charwidths[$this->FontFamily.$this->FontStyle];
- if($w==0)
- $w=$this->w-$this->lMargin-$this->x;
- $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
- $s=str_replace("\r",'',$txt);
- $nb=strlen($s);
- if($nb>0 and $s[$nb-1]=="\n")
- $nb--;
- $sep=-1;
- $i=0;
- $j=0;
- $l=0;
- $ns=0;
- $nl=1;
- while($i<$nb)
- {
- //Get next character
- $c=$s[$i];
- if($c=="\n")
- {
- //Explicit line break
- if($align=='J')
- {
- $this->ws=0;
- $this->_out('0 Tw');
- }
- $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,$align,$fill);
- $i++;
- $sep=-1;
- $j=$i;
- $l=0;
- $ns=0;
- if($border)
- {
- $x=$this->x;
- $y=$this->y-$h;
- if($nl==1)
- $this->_out($x.' -'.$y.' m '.($x+$w).' -'.$y.' l');
- $this->_out($x.' -'.$y.' m '.$x.' -'.$this->y.' l '.($x+$w).' -'.$y.' m '.($x+$w).' -'.$this->y.' l S');
- }
- $nl++;
- continue;
- }
- if($c==' ')
- {
- $sep=$i;
- $ls=$l;
- $ns++;
- }
- $l+=$cw[$c];
- if($l>$wmax)
- {
- //Automatic line break
- if($sep==-1)
- {
- if($i==$j)
- $i++;
- if($align=='J')
- {
- $this->ws=0;
- $this->_out('0 Tw');
- }
- $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,$align,$fill);
- }
- else
- {
- if($align=='J')
- {
- $this->ws=($ns>1) ? round(($wmax-$ls)/1000*$this->FontSize/($ns-1),3) : 0;
- $this->_out($this->ws.' Tw');
- }
- $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,$align,$fill);
- $i=$sep+1;
- }
- $sep=-1;
- $j=$i;
- $l=0;
- $ns=0;
- if($border)
- {
- $x=$this->x;
- $y=$this->y-$h;
- if($nl==1)
- $this->_out($x.' -'.$y.' m '.($x+$w).' -'.$y.' l');
- $this->_out($x.' -'.$y.' m '.$x.' -'.$this->y.' l '.($x+$w).' -'.$y.' m '.($x+$w).' -'.$this->y.' l S');
- }
- $nl++;
- }
- else
- $i++;
- }
- //Last chunk
- if($align=='J')
- {
- $this->ws=0;
- $this->_out('0 Tw');
- }
- $this->Cell($w,$h,substr($s,$j,$i),0,2,$align,$fill);
- if($border)
- {
- $x=$this->x;
- $y=$this->y-$h;
- if($nl==1)
- $this->_out($x.' -'.$y.' m '.($x+$w).' -'.$y.' l');
- $this->_out($x.' -'.$y.' m '.$x.' -'.$this->y.' l '.($x+$w).' -'.$this->y.' l '.($x+$w).' -'.$y.' l S');
- }
- $this->x=$this->lMargin;
-}
+ // Sets transformation matrix
+ $this->_out($this->_FPDF_round($this->k, 6) . ' 0 0 ' . $this->_FPDF_round($this->k, 6) . ' 0 ' . $this->hPt . ' cm');
+ } // end of the "_beginpage()" method
-function Image($file,$x,$y,$w,$h=0,$type='')
-{
- //Put an image on the page
- if(!isset($this->images[$file]))
- {
- //First use of image, get info
- if($type=='')
- {
- $pos=strrpos($file,'.');
- if(!$pos)
- $this->Error('Image file has no extension and no type was specified: '.$file);
- $type=substr($file,$pos+1);
- }
- $type=strtolower($type);
- $mqr=get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- if($type=='jpg' or $type=='jpeg')
- $info=$this->_parsejpg($file);
- elseif($type=='png')
- $info=$this->_parsepng($file);
- else
- $this->Error('Unsupported image file type: '.$type);
- set_magic_quotes_runtime($mqr);
- $info['n']=count($this->images)+1;
- $this->images[$file]=$info;
- }
- else
- $info=$this->images[$file];
- //Automatic width or height calculus
- if($w==0)
- $w=round($h*$info['w']/$info['h'],2);
- if($h==0)
- $h=round($w*$info['h']/$info['w'],2);
- $this->_out('q '.$w.' 0 0 '.$h.' '.$x.' -'.($y+$h).' cm /I'.$info['n'].' Do Q');
-}
-function Ln($h='')
-{
- //Line feed; default value is last cell height
- $this->x=$this->lMargin;
- if(is_string($h))
- $this->y+=$this->lasth;
- else
- $this->y+=$h;
-}
+ /**
+ * Ends page contents
+ *
+ * @access private
+ */
+ function _endpage()
+ {
+ $this->state=1;
+ } // end of the "_endpage()" method
-function GetX()
-{
- //Get x position
- return $this->x;
-}
-function SetX($x)
-{
- //Set x position
- if($x>=0)
- $this->x=$x;
- else
- $this->x=$this->w+$x;
-}
+ /**
+ * Underlines text
+ *
+ * @param double The x position
+ * @param double The y position
+ * @param string The text
+ *
+ * @return string The underlined text
+ *
+ * @access private
+ */
+ function _dounderline($x,$y,$txt)
+ {
+ $up = $this->CurrentFont['up'];
+ $ut = $this->CurrentFont['ut'];
+ $w = $this->GetStringWidth($txt) + $this->ws * substr_count($txt, ' ');
-function GetY()
-{
- //Get y position
- return $this->y;
-}
+ return $x . ' -' . ($y - $up / 1000 * $this->FontSize) . ' '
+ . $w . ' -' . ($ut / 1000 * $this->FontSize) . ' re f';
+ } // end of the "_dounderline()" method
-function SetY($y)
-{
- //Set y position and reset x
- $this->x=$this->lMargin;
- if($y>=0)
- $this->y=$y;
- else
- $this->y=$this->h+$y;
-}
-function SetXY($x,$y)
-{
- //Set x and y positions
- $this->SetY($y);
- $this->SetX($x);
-}
+ /**
+ * Extracts info from a JPEG file
+ *
+ * @param string The file name and path
+ *
+ * @return array The images informations
+ *
+ * @access private
+ */
+ function _parsejpg($file)
+ {
+ $a = GetImageSize($file);
+ if (!$a) {
+ $this->Error('Missing or incorrect image file: ' . $file);
+ }
+ if ($a[2] != 2) {
+ $this->Error('Not a JPEG file: ' . $file);
+ }
+ if (!isset($a['channels']) || $a['channels'] == 3) {
+ $colspace = 'DeviceRGB';
+ }
+ else if($a['channels'] == 4) {
+ $colspace = 'DeviceCMYK';
+ }
+ else {
+ $colspace = 'DeviceGray';
+ }
+ $bpc = isset($a['bits']) ? $a['bits'] : 8;
-function Output($file='',$download=false)
-{
- //Output PDF to file or browser
- global $HTTP_ENV_VARS;
+ // Reads whole file
+ $f = fopen($file, 'rb');
+ $data = fread($f, filesize($file));
+ fclose($f);
- if($this->state<3)
- $this->Close();
- if($file=='')
- {
- //Send to browser
- Header('Content-Type: application/pdf');
- if(headers_sent())
- $this->Error('Some data has already been output to browser, can\'t send PDF file');
- Header('Content-Length: '.strlen($this->buffer));
- Header('Content-disposition: inline; filename=doc.pdf');
- echo $this->buffer;
- }
- else
- {
- if($download)
- {
- //Download file
- if(isset($HTTP_ENV_VARS['HTTP_USER_AGENT']) and strpos($HTTP_ENV_VARS['HTTP_USER_AGENT'],'MSIE 5.5'))
- Header('Content-Type: application/dummy');
- else
- Header('Content-Type: application/octet-stream');
- if(headers_sent())
- $this->Error('Some data has already been output to browser, can\'t send PDF file');
- Header('Content-Length: '.strlen($this->buffer));
- Header('Content-disposition: attachment; filename='.$file);
- echo $this->buffer;
- }
- else
- {
- //Save file locally
- $f=fopen($file,'wb');
- if(!$f)
- $this->Error('Unable to create output file: '.$file);
- fwrite($f,$this->buffer,strlen($this->buffer));
- fclose($f);
- }
- }
-}
+ return array('w' => $a[0],
+ 'h' => $a[1],
+ 'cs' => $colspace,
+ 'bpc' => $bpc,
+ 'f' => 'DCTDecode',
+ 'data' => $data);
+ } // end of the "_parsejpg()" method
-/****************************************************************************
-* *
-* Private methods *
-* *
-****************************************************************************/
-function _begindoc()
-{
- //Start document
- $this->state=1;
- $this->_out('%PDF-1.3');
-}
-function _enddoc()
-{
- //Terminate document
- $nb=$this->page;
- if(!empty($this->AliasNbPages))
- {
- //Replace number of pages
- for($n=1;$n<=$nb;$n++)
- $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]);
- }
- if($this->DefOrientation=='P')
- {
- $wPt=$this->fwPt;
- $hPt=$this->fhPt;
- }
- else
- {
- $wPt=$this->fhPt;
- $hPt=$this->fwPt;
- }
- $filter=($this->compress) ? '/Filter /FlateDecode ' : '';
- for($n=1;$n<=$nb;$n++)
- {
- //Page
- $this->_newobj();
- $this->_out('<_out('/Parent 1 0 R');
- if(isset($this->OrientationChanges[$n]))
- $this->_out('/MediaBox [0 0 '.$hPt.' '.$wPt.']');
- $this->_out('/Resources 2 0 R');
- $this->_out('/Contents '.($this->n+1).' 0 R>>');
- $this->_out('endobj');
- //Page content
- $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n];
- $this->_newobj();
- $this->_out('<<'.$filter.'/Length '.strlen($p).'>>');
- $this->_out('stream');
- $this->_out($p.'endstream');
- $this->_out('endobj');
- }
- //Fonts
- $nf=$this->n;
- reset($this->fonts);
- while(list($name)=each($this->fonts))
- {
- $this->_newobj();
- $this->_out('<_out('/Subtype /Type1');
- $this->_out('/BaseFont /'.$name);
- if($name!='Symbol' and $name!='ZapfDingbats')
- $this->_out('/Encoding /WinAnsiEncoding');
- $this->_out('>>');
- $this->_out('endobj');
- }
- //Images
- $ni=$this->n;
- reset($this->images);
- while(list($file,$info)=each($this->images))
- {
- $this->_newobj();
- $this->_out('<_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]');
- else
- $this->_out('/ColorSpace /'.$info['cs']);
- $this->_out('/BitsPerComponent '.$info['bpc']);
- $this->_out('/Filter /'.$info['f']);
- if(isset($info['parms']))
- $this->_out($info['parms']);
- if(isset($info['trns']) and is_array($info['trns']))
- {
- $trns='';
- for($i=0;$i_out('/Mask ['.$trns.']');
- }
- $this->_out('/Length '.strlen($info['data']).'>>');
- $this->_out('stream');
- $this->_out($info['data']);
- $this->_out('endstream');
- $this->_out('endobj');
- //Palette
- if($info['cs']=='Indexed')
- {
- $this->_newobj();
- $this->_out('<>');
- $this->_out('stream');
- $this->_out($info['pal']);
- $this->_out('endstream');
- $this->_out('endobj');
- }
- }
- //Pages root
- $this->offsets[1]=strlen($this->buffer);
- $this->_out('1 0 obj');
- $this->_out('<page;$i++)
- $kids.=(3+2*$i).' 0 R ';
- $this->_out($kids.']');
- $this->_out('/Count '.$this->page);
- $this->_out('/MediaBox [0 0 '.$wPt.' '.$hPt.']');
- $this->_out('>>');
- $this->_out('endobj');
- //Resources
- $this->offsets[2]=strlen($this->buffer);
- $this->_out('2 0 obj');
- $this->_out('<_out('/Font <<');
- for($i=1;$i<=count($this->fonts);$i++)
- $this->_out('/F'.$i.' '.($nf+$i).' 0 R');
- $this->_out('>>');
- if(count($this->images))
- {
- $this->_out('/XObject <<');
- $nbpal=0;
- reset($this->images);
- while(list(,$info)=each($this->images))
- {
- $this->_out('/I'.$info['n'].' '.($ni+$info['n']+$nbpal).' 0 R');
- if($info['cs']=='Indexed')
- $nbpal++;
- }
- $this->_out('>>');
- }
- $this->_out('>>');
- $this->_out('endobj');
- //Info
- $this->_newobj();
- $this->_out('<title))
- $this->_out('/Title ('.$this->_escape($this->title).')');
- if(!empty($this->subject))
- $this->_out('/Subject ('.$this->_escape($this->subject).')');
- if(!empty($this->author))
- $this->_out('/Author ('.$this->_escape($this->author).')');
- if(!empty($this->keywords))
- $this->_out('/Keywords ('.$this->_escape($this->keywords).')');
- if(!empty($this->creator))
- $this->_out('/Creator ('.$this->_escape($this->creator).')');
- $this->_out('/CreationDate (D:'.date('YmdHis').')>>');
- $this->_out('endobj');
- //Catalog
- $this->_newobj();
- $this->_out('<DisplayMode=='fullpage')
- $this->_out('/OpenAction [3 0 R /Fit]');
- elseif($this->DisplayMode=='fullwidth')
- $this->_out('/OpenAction [3 0 R /FitH null]');
- elseif($this->DisplayMode=='real')
- $this->_out('/OpenAction [3 0 R /XYZ null null 1]');
- else
- $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->DisplayMode/100).']');
- $this->_out('/Pages 1 0 R>>');
- $this->_out('endobj');
- //Cross-ref
- $o=strlen($this->buffer);
- $this->_out('xref');
- $this->_out('0 '.($this->n+1));
- $this->_out('0000000000 65535 f ');
- for($i=1;$i<=$this->n;$i++)
- $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i]));
- //Trailer
- $this->_out('trailer');
- $this->_out('<n+1));
- $this->_out('/Root '.$this->n.' 0 R');
- $this->_out('/Info '.($this->n-1).' 0 R>>');
- $this->_out('startxref');
- $this->_out($o);
- $this->_out('%%EOF');
- $this->state=3;
-}
+ /**
+ * Reads a 4-byte integer from a file
+ *
+ * @param string The file name and path
+ *
+ * @return integer The 4-byte integer
+ *
+ * @access private
+ *
+ * @see _parsepng()
+ */
+ function _freadint($f)
+ {
+ $i = ord(fread($f, 1)) << 24;
+ $i += ord(fread($f, 1)) << 16;
+ $i += ord(fread($f, 1)) << 8;
+ $i += ord(fread($f, 1));
-function _beginpage($orientation)
-{
- $this->page++;
- $this->pages[$this->page]='';
- $this->state=2;
- $this->x=$this->lMargin;
- $this->y=$this->tMargin;
- $this->lasth=0;
- $this->FontFamily='';
- //Page orientation
- if(!$orientation)
- $orientation=$this->DefOrientation;
- else
- {
- $orientation=strtoupper($orientation{0});
- if($orientation!=$this->DefOrientation)
- $this->OrientationChanges[$this->page]=true;
- }
- if($orientation!=$this->CurOrientation)
- {
- //Change orientation
- if($orientation=='P')
- {
- $this->wPt=$this->fwPt;
- $this->hPt=$this->fhPt;
- $this->w=$this->fw;
- $this->h=$this->fh;
- }
- else
- {
- $this->wPt=$this->fhPt;
- $this->hPt=$this->fwPt;
- $this->w=$this->fh;
- $this->h=$this->fw;
- }
- $this->PageBreakTrigger=$this->h-$this->bMargin;
- $this->CurOrientation=$orientation;
- }
- //Set transformation matrix
- $this->_out(round($this->k,6).' 0 0 '.round($this->k,6).' 0 '.$this->hPt.' cm');
-}
+ return $i;
+ } // end of the "_freadint()" method
-function _endpage()
-{
- //End of page contents
- $this->state=1;
-}
-function _newobj()
-{
- //Begin a new object
- $this->n++;
- $this->offsets[$this->n]=strlen($this->buffer);
- $this->_out($this->n.' 0 obj');
-}
+ /**
+ * Extracts info from a PNG file
+ *
+ * @param string The file name and path
+ *
+ * @return array The images informations
+ *
+ * @access private
+ *
+ * @see _freadint()
+ */
+ function _parsepng($file)
+ {
+ $f = fopen($file, 'rb');
+ if (!$f) {
+ $this->Error('Can\'t open image file: ' . $file);
+ }
-function _setfont($family,$style,$size)
-{
- global $fpdf_charwidths;
+ // Checks signature
+ if (fread($f, 8) != chr(137) . 'PNG' . chr(13) . chr(10) . chr(26) . chr(10)) {
+ $this->Error('Not a PNG file: ' . $file);
+ }
- $family=strtolower($family);
- if($family=='')
- $family=$this->FontFamily;
- if($family=='arial')
- $family='helvetica';
- if($family=='symbol' or $family=='zapfdingbats')
- $style='';
- $style=strtoupper($style);
- if($style=='IB')
- $style='BI';
- if($size==0)
- $size=$this->FontSizePt;
- //Test if font is already selected
- if($this->FontFamily==$family and $this->FontStyle==$style and $this->FontSizePt==$size)
- return true;
- //Retrieve Type1 font name
- if(!isset($this->fontnames[$family.$style]))
- return false;
- $fontname=$this->fontnames[$family.$style];
- //Test if used for the first time
- if(!isset($this->fonts[$fontname]))
- {
- $n=count($this->fonts);
- $this->fonts[$fontname]=$n+1;
- if(!isset($fpdf_charwidths[$family.$style]))
- {
- //include metric file
- $file=$family;
- if($family=='times' or $family=='helvetica')
- $file.=strtolower($style);
- $file.='.php3';
- if(defined('FPDF_FONTPATH'))
- $file=FPDF_FONTPATH.$file;
- include($file);
- if(!isset($fpdf_charwidths[$family.$style]))
- $this->Error('Could not include font metric file');
- }
- }
- //Select it
- $this->FontFamily=$family;
- $this->FontStyle=$style;
- $this->FontSizePt=$size;
- $this->FontSize=round($size/$this->k,2);
- if($this->page>0)
- $this->_out('BT /F'.$this->fonts[$fontname].' '.$this->FontSize.' Tf ET');
- return true;
-}
+ // Reads header chunk
+ fread($f,4);
+ if (fread($f, 4) != 'IHDR') {
+ $this->Error('Incorrect PNG file: ' . $file);
+ }
+ $w = $this->_freadint($f);
+ $h = $this->_freadint($f);
+ $bpc = ord(fread($f,1));
+ if ($bpc > 8) {
+ $this->Error('16-bit depth not supported: ' . $file);
+ }
+ $ct = ord(fread($f, 1));
+ if ($ct == 0) {
+ $colspace = 'DeviceGray';
+ }
+ else if ($ct == 2) {
+ $colspace = 'DeviceRGB';
+ }
+ else if ($ct == 3) {
+ $colspace = 'Indexed';
+ }
+ else {
+ $this->Error('Alpha channel not supported: ' . $file);
+ }
+ if (ord(fread($f, 1)) != 0) {
+ $this->Error('Unknown compression method: ' . $file);
+ }
+ if (ord(fread($f, 1)) != 0) {
+ $this->Error('Unknown filter method: ' . $file);
+ }
+ if (ord(fread($f, 1)) != 0) {
+ $this->Error('Interlacing not supported: ' . $file);
+ }
+ fread($f, 4);
+ $parms = '/DecodeParms <>';
-function _setfontsize($size)
-{
- //Test if size already selected
- if($this->FontSizePt==$size)
- return;
- //Select it
- $fontname=$this->fontnames[$this->FontFamily.$this->FontStyle];
- $this->FontSizePt=$size;
- $this->FontSize=round($size/$this->k,2);
- if($this->page>0)
- $this->_out('BT /F'.$this->fonts[$fontname].' '.$this->FontSize.' Tf ET');
-}
+ // Scans chunks looking for palette, transparency and image data
+ $pal = '';
+ $trns = '';
+ $data = '';
+ do {
+ $n = $this->_freadint($f);
+ $type = fread($f, 4);
+ if ($type == 'PLTE') {
+ // Reads palette
+ $pal = fread($f, $n);
+ fread($f, 4);
+ }
+ else if ($type == 'tRNS') {
+ // Reads transparency info
+ $t = fread($f, $n);
+ if ($ct == 0) {
+ $trns = array(substr($t, 1, 1));
+ }
+ else if ($ct == 2) {
+ $trns = array(substr($t, 1, 1), substr($t, 3, 1), substr($t, 5, 1));
+ }
+ else {
+ $pos = strpos(' ' . $t, chr(0));
+ if ($pos) {
+ $trns = array($pos - 1);
+ }
+ fread($f,4);
+ } // end if... else if... else
+ }
+ else if ($type == 'IDAT') {
+ // Reads image data block
+ $data .= fread($f, $n);
+ fread($f, 4);
+ }
+ else if ($type == 'IEND') {
+ break;
+ }
+ else {
+ fread($f, $n + 4);
+ } // end if... else if... else
+ } while($n); // end do
-function _parsejpg($file)
-{
- //Extract info from a JPEG file
- $a=GetImageSize($file);
- if(!$a)
- $this->Error('Missing or incorrect image file: '.$file);
- if($a[2]!=2)
- $this->Error('Not a JPEG file: '.$file);
- if(!isset($a['channels']) or $a['channels']==3)
- $colspace='DeviceRGB';
- elseif($a['channels']==4)
- $colspace='DeviceCMYK';
- else
- $colspace='DeviceGray';
- $bpc=isset($a['bits']) ? $a['bits'] : 8;
- //Read whole file
- $f=fopen($file,'rb');
- $data=fread($f,filesize($file));
- fclose($f);
- return array('w'=>$a[0],'h'=>$a[1],'cs'=>$colspace,'bpc'=>$bpc,'f'=>'DCTDecode','data'=>$data);
-}
+ if ($colspace == 'Indexed' && empty($pal)) {
+ $this->Error('Missing palette in ' . $file);
+ }
+ fclose($f);
-function _parsepng($file)
-{
- //Extract info from a PNG file
- $f=fopen($file,'rb');
- if(!$f)
- $this->Error('Can\'t open image file: '.$file);
- //Check signature
- if(fread($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10))
- $this->Error('Not a PNG file: '.$file);
- //Read header chunk
- fread($f,4);
- if(fread($f,4)!='IHDR')
- $this->Error('Incorrect PNG file: '.$file);
- $w=$this->_freadint($f);
- $h=$this->_freadint($f);
- $bpc=ord(fread($f,1));
- if($bpc>8)
- $this->Error('16-bit depth not supported: '.$file);
- $ct=ord(fread($f,1));
- if($ct==0)
- $colspace='DeviceGray';
- elseif($ct==2)
- $colspace='DeviceRGB';
- elseif($ct==3)
- $colspace='Indexed';
- else
- $this->Error('Alpha channel not supported: '.$file);
- if(ord(fread($f,1))!=0)
- $this->Error('Unknown compression method: '.$file);
- if(ord(fread($f,1))!=0)
- $this->Error('Unknown filter method: '.$file);
- if(ord(fread($f,1))!=0)
- $this->Error('Interlacing not supported: '.$file);
- fread($f,4);
- $parms='/DecodeParms <>';
- //Scan chunks looking for palette, transparency and image data
- $pal='';
- $trns='';
- $data='';
- do
- {
- $n=$this->_freadint($f);
- $type=fread($f,4);
- if($type=='PLTE')
- {
- //Read palette
- $pal=fread($f,$n);
- fread($f,4);
- }
- elseif($type=='tRNS')
- {
- //Read transparency info
- $t=fread($f,$n);
- if($ct==0)
- $trns=array(substr($t,1,1));
- elseif($ct==2)
- $trns=array(substr($t,1,1),substr($t,3,1),substr($t,5,1));
- else
- {
- $pos=strpos($t,chr(0));
- if(is_int($pos))
- $trns=array($pos);
- }
- fread($f,4);
- }
- elseif($type=='IDAT')
- {
- //Read image data block
- $data.=fread($f,$n);
- fread($f,4);
- }
- elseif($type=='IEND')
- break;
- else
- fread($f,$n+4);
- }
- while($n);
- if($colspace=='Indexed' and empty($pal))
- $this->Error('Missing palette in '.$file);
- fclose($f);
- return array('w'=>$w,'h'=>$h,'cs'=>$colspace,'bpc'=>$bpc,'f'=>'FlateDecode','parms'=>$parms,'pal'=>$pal,'trns'=>$trns,'data'=>$data);
-}
+ return array('w' => $w,
+ 'h' => $h,
+ 'cs' => $colspace,
+ 'bpc' => $bpc,
+ 'f' => 'FlateDecode',
+ 'parms' => $parms,
+ 'pal' => $pal,
+ 'trns' => $trns,
+ 'data' => $data);
+ } // end of the "_parsepng()" method
-function _freadint($f)
-{
- //Read a 4-byte integer from file
- $i=ord(fread($f,1))<<24;
- $i+=ord(fread($f,1))<<16;
- $i+=ord(fread($f,1))<<8;
- $i+=ord(fread($f,1));
- return $i;
-}
-function _escape($s)
-{
- //Add \ before \, ( and )
- return str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$s)));
-}
-function _out($s)
-{
- //Add a line to the document
- if($this->state==2)
- $this->pages[$this->page].=$s."\n";
- else
- $this->buffer.=$s."\n";
-}
-//End of class
-}
+ /**************************************************************************
+ * *
+ * Public methods *
+ * *
+ **************************************************************************/
-// loic1: get the user agent whatever are the PHP version and the
-// "register globals" value
-if (!empty($_SERVER) && isset($_SERVER['HTTP_USER_AGENT'])) {
- $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
-}
-else if (!empty($_ENV) && isset($_ENV['HTTP_USER_AGENT'])) {
+ /**
+ * Sets auto page break mode and triggering margin
+ *
+ * @param string The auto page break mode
+ * @param double Maximum size till the bottom of the page to start adding
+ * page break
+ *
+ * @access public
+ */
+ function SetAutoPageBreak($auto, $margin = 0)
+ {
+ $this->AutoPageBreak = $auto;
+ $this->bMargin = $margin;
+ $this->PageBreakTrigger = $this->h - $margin;
+ } // end of the "SetAutoPageBreak()" method
+
+
+ /**
+ * Sets display mode in viewer
+ *
+ * @param mixed The zoom mode (fullpage, fullwidth, real, default,
+ * zoom or an zoom factor -real-)
+ * @param string The layout mode (single, continuous, two or default)
+ *
+ * @access public
+ */
+ function SetDisplayMode($zoom = 'default', $layout = 'continuous')
+ {
+ if (is_string($zoom)) {
+ $zoom = strtolower($zoom);
+ }
+ $layout = strtolower($layout);
+
+ // Zoom mode
+ if ($zoom == 'fullpage' || $zoom == 'fullwidth' || $zoom == 'real' || $zoom == 'default'
+ || !is_string($zoom)) {
+ $this->ZoomMode = $zoom;
+ } else if ($zoom == 'zoom') {
+ $this->ZoomMode = $layout;
+ } else {
+ $this->Error('Incorrect zoom display mode: ' . $zoom);
+ } // end if... else if... else...
+
+ // Layout mode
+ if ($layout == 'single' || $layout == 'continuous' || $layout=='two' || $layout=='default') {
+ $this->LayoutMode = $layout;
+ } else if ($zoom != 'zoom') {
+ $this->Error('Incorrect layout display mode: ' . $layout);
+ } // end if... else if...
+ } // end of the "SetDisplayMode()" method
+
+
+ /**
+ * Sets page compression
+ *
+ * @param boolean whether to compress file or not
+ *
+ * @access public
+ */
+ function SetCompression($compress)
+ {
+ if (function_exists('gzcompress')) {
+ $this->compress = $compress;
+ } else {
+ $this->compress = FALSE;
+ } // end if... else...
+ } // end of the "SetCompression()" method
+
+
+ /**
+ * Sets page margins
+ *
+ * @param double The left margin
+ * @param double The top margin
+ * @param double The right margin
+ *
+ * @access public
+ */
+ function SetMargins($left, $top, $right = -1)
+ {
+ $this->lMargin = $left;
+ $this->tMargin = $top;
+ if ($right == -1) {
+ $right = $left;
+ }
+ $this->rMargin = $right;
+ } // end of the "SetMargins()" method
+
+
+ /**
+ * The FPDF constructor
+ *
+ * @param string The page orientation (p, portrait, l or landscape)
+ * @param string The unit for sizes (pt, mm, cm or in)
+ * @param mixed The page format (A3, A4, A5, letter, legal or an array
+ * with page sizes)
+ *
+ * @access public
+ */
+ function FPDF($orientation = 'P', $unit = 'mm', $format = 'A4')
+ {
+ // Initialization of properties
+ $this->page = 0;
+ $this->n = 2;
+ $this->buffer = '';
+ $this->pages = array();
+ $this->OrientationChanges = array();
+ $this->state = 0;
+ $this->fonts = array();
+ $this->FontFiles = array();
+ $this->diffs = array();
+ $this->images = array();
+ $this->InFooter = FALSE;
+ $this->FontFamily = '';
+ $this->FontStyle = '';
+ $this->FontSizePt = 12;
+ $this->underline = FALSE;
+ $this->DrawColor = '0 G';
+ $this->FillColor = '0 g';
+ $this->TextColor = '0 g';
+ $this->ColorFlag = FALSE;
+ $this->ws = 0;
+
+ // Font names
+ $this->CoreFonts['courier'] = 'Courier';
+ $this->CoreFonts['courierB'] = 'Courier-Bold';
+ $this->CoreFonts['courierI'] = 'Courier-Oblique';
+ $this->CoreFonts['courierBI'] = 'Courier-BoldOblique';
+ $this->CoreFonts['helvetica'] = 'Helvetica';
+ $this->CoreFonts['helveticaB'] = 'Helvetica-Bold';
+ $this->CoreFonts['helveticaI'] = 'Helvetica-Oblique';
+ $this->CoreFonts['helveticaBI'] = 'Helvetica-BoldOblique';
+ $this->CoreFonts['times'] = 'Times-Roman';
+ $this->CoreFonts['timesB'] = 'Times-Bold';
+ $this->CoreFonts['timesI'] = 'Times-Italic';
+ $this->CoreFonts['timesBI'] = 'Times-BoldItalic';
+ $this->CoreFonts['symbol'] = 'Symbol';
+ $this->CoreFonts['zapfdingbats'] = 'ZapfDingbats';
+
+ // Scale factor
+ if ($unit == 'pt') {
+ $this->k = 1;
+ } else if ($unit == 'mm') {
+ $this->k = 72/25.4;
+ } else if ($unit == 'cm') {
+ $this->k = 72/2.54;
+ } else if ($unit == 'in') {
+ $this->k = 72;
+ } else {
+ $this->Error('Incorrect unit: ' . $unit);
+ } // end if... else if... else...
+
+ // Page format
+ if (is_string($format)) {
+ $format = strtolower($format);
+ if ($format == 'a3') {
+ $format = array(841.89, 1190.55);
+ } else if ($format == 'a4') {
+ $format = array(595.28, 841.89);
+ } else if ($format == 'a5') {
+ $format = array(420.94, 595.28);
+ } else if ($format == 'letter') {
+ $format = array(612, 792);
+ } else if ($format == 'legal') {
+ $format = array(612, 1008);
+ } else {
+ $this->Error('Unknown page format: ' . $format);
+ } // end if... else if... else...
+ $this->fwPt = $format[0];
+ $this->fhPt = $format[1];
+ }
+ else {
+ $this->fwPt = $this->_FPDF_round($format[0] * $this->k, 2);
+ $this->fhPt = $this->_FPDF_round($format[1] * $this->k, 2);
+ } // end if... else...
+ $this->fw = $this->_FPDF_round($this->fwPt / $this->k, 2);
+ $this->fh = $this->_FPDF_round($this->fhPt / $this->k, 2);
+
+ // Page orientation
+ $orientation = strtolower($orientation);
+ if ($orientation == 'p' || $orientation == 'portrait') {
+ $this->DefOrientation = 'P';
+ $this->wPt = $this->fwPt;
+ $this->hPt = $this->fhPt;
+ }
+ else if ($orientation == 'l' || $orientation == 'landscape') {
+ $this->DefOrientation = 'L';
+ $this->wPt = $this->fhPt;
+ $this->hPt = $this->fwPt;
+ }
+ else {
+ $this->Error('Incorrect orientation: ' . $orientation);
+ } // end if... else if... else...
+ $this->CurOrientation = $this->DefOrientation;
+ $this->w = $this->_FPDF_round($this->wPt / $this->k, 2);
+ $this->h = $this->_FPDF_round($this->hPt / $this->k, 2);
+
+ // Page margins (1 cm)
+ $margin = $this->_FPDF_round(28.35 / $this->k,2);
+ $this->SetMargins($margin, $margin);
+
+ // Interior cell margin (1 mm)
+ $this->cMargin = $margin / 10;
+
+ // Line width (0.2 mm)
+ $this->LineWidth = $this->_FPDF_round(.567 / $this->k,3);
+
+ // Automatic page break
+ $this->SetAutoPageBreak(TRUE, 2 * $margin);
+
+ // Full width display mode
+ $this->SetDisplayMode('fullwidth');
+
+ // Compression
+ $this->SetCompression(TRUE);
+
+ // Links
+ $this->links = array();
+ } // end of the "FPDF()" constructor
+
+
+ /**
+ * Sets left margin of the page
+ *
+ * @param double The left margin
+ *
+ * @access public
+ */
+ function SetLeftMargin($margin)
+ {
+ $this->lMargin = $margin;
+ if ($this->page > 0 && $this->x < $margin) {
+ $this->x = $margin;
+ }
+ } // end of the "SetLeftMargin()" method
+
+
+ /**
+ * Sets top margin of the page
+ *
+ * @param double The top margin
+ *
+ * @access public
+ */
+ function SetTopMargin($margin)
+ {
+ $this->tMargin = $margin;
+ } // end of the "SetTopMargin()" method
+
+
+ /**
+ * Sets right margin of the page
+ *
+ * @param double The right margin
+ *
+ * @access public
+ */
+ function SetRightMargin($margin)
+ {
+ $this->rMargin = $margin;
+ } // end of the "SetRightMargin()" method
+
+
+ /**
+ * Sets the title of the document (among the document properties)
+ *
+ * @param string The title of the document
+ *
+ * @access public
+ */
+ function SetTitle($title)
+ {
+ $this->title = $title;
+ } // end of the "SetTitle()" method
+
+
+ /**
+ * Sets the subject of the document (among the document properties)
+ *
+ * @param string The subject of the document
+ *
+ * @access public
+ */
+ function SetSubject($subject)
+ {
+ $this->subject = $subject;
+ } // end of the "SetSubject()" method
+
+
+ /**
+ * Sets the author of the document (among the document properties)
+ *
+ * @param string The author of the document
+ *
+ * @access public
+ */
+ function SetAuthor($author)
+ {
+ $this->author = $author;
+ } // end of the "SetAuthor()" method
+
+
+ /**
+ * Sets keywords of the document (among the document properties)
+ *
+ * @param string The keyword list for the document
+ *
+ * @access public
+ */
+ function SetKeywords($keywords)
+ {
+ $this->keywords = $keywords;
+ } // end of the "SetKeywords()" method
+
+
+ /**
+ * Sets the creator of the document (among the document properties)
+ *
+ * @param string The creator of the document
+ *
+ * @access public
+ */
+ function SetCreator($creator)
+ {
+ $this->creator = $creator;
+ } // end of the "SetCreator()" method
+
+
+ /**
+ * Defines an alias for the total number of pages
+ *
+ * @param string The alias string
+ *
+ * @access public
+ */
+ function AliasNbPages($alias = '{nb}')
+ {
+ $this->AliasNbPages = $alias;
+ } // end of the "AliasNbPages()" method
+
+
+ /**
+ * Selects a font
+ *
+ * @param string The font name
+ * @param string The font style (B, I, BI)
+ * @param double The font size (in points)
+ *
+ * @global double The character width
+ *
+ * @access public
+ */
+ function SetFont($family, $style = '', $size = 0)
+ {
+ global $fpdf_charwidths;
+
+ $family = strtolower($family);
+ if ($family == '') {
+ $family = $this->FontFamily;
+ }
+ if ($family == 'arial') {
+ $family = 'helvetica';
+ }
+ $style = strtoupper($style);
+ if ($family == 'symbol' || $family == 'zapfdingbats') {
+ $style = '';
+ }
+ if (strpos(' ' . $style, 'U')) {
+ $this->underline = TRUE;
+ $style = str_replace('U', '', $style);
+ } else {
+ $this->underline = FALSE;
+ }
+ if ($style == 'IB') {
+ $style = 'BI';
+ }
+ if ($size == 0) {
+ $size = $this->FontSizePt;
+ }
+
+ // Tests if the font is already selected
+ if ($this->FontFamily == $family && $this->FontStyle == $style && $this->FontSizePt == $size) {
+ return;
+ }
+
+ // Tests if used for the first time
+ $fontkey = $family . $style;
+ if (!isset($this->fonts[$fontkey])) {
+ // Checks if one of the core fonts
+ if (isset($this->CoreFonts[$fontkey])) {
+ if (!isset($fpdf_charwidths[$fontkey])) {
+ // Loads metric file
+ $file = $family;
+ if ($family == 'times' || $family == 'helvetica') {
+ $file .= strtolower($style);
+ }
+ $file .= '.php3';
+ // loic1: PHP3 compatibility
+ // if (defined('FPDF_FONTPATH')) {
+ // $file = FPDF_FONTPATH . $file;
+ // }
+ if (isset($GLOBALS['FPDF_font_path'])) {
+ $file = $GLOBALS['FPDF_font_path'] . $file;
+ }
+ include($file);
+ if (!isset($fpdf_charwidths[$fontkey])) {
+ $this->Error('Could not include font metric file');
+ }
+ } // end if
+ $i = count($this->fonts) + 1;
+ $this->fonts[$fontkey] = array('i' => $i,
+ 'type' => 'core',
+ 'name' => $this->CoreFonts[$fontkey],
+ 'up' => -100,
+ 'ut' => 50,
+ 'cw' => $fpdf_charwidths[$fontkey]);
+ }
+ else {
+ $this->Error('Undefined font: ' . $family . ' ' . $style);
+ } // end if... else...
+ } // end if
+
+ // Selects it
+ $this->FontFamily = $family;
+ $this->FontStyle = $style;
+ $this->FontSizePt = $size;
+ $this->FontSize = $this->_FPDF_round($size / $this->k, 2);
+ // loic1: PHP3 compatibility
+ // $this->CurrentFont = &$this->fonts[$fontkey];
+ eval('$this->CurrentFont = ' . ($GLOBALS['FPDF_is_php4'] ? '&' : '') . '$this->fonts[\'' . $fontkey . '\'];');
+ if ($this->page > 0) {
+ $this->_out('BT /F' . $this->CurrentFont['i'] . ' ' . $this->FontSize . ' Tf ET');
+ }
+ } // end of the "SetFont()" method
+
+
+ /**
+ * Sends the header of the page
+ *
+ * This method has to be implemented in your own inherited class
+ *
+ * @access public
+ */
+ function Header()
+ {
+ // void
+ } // end of the "Header()" method
+
+
+ /**
+ * Sends the footer of the page
+ *
+ * This method has to be implemented in your own inherited class
+ *
+ * @access public
+ */
+ function Footer()
+ {
+ // void
+ } // end of the "Footer()" method
+
+
+ /**
+ * Begin the document
+ *
+ * @access public
+ */
+ function Open()
+ {
+ $this->_begindoc();
+ } // end of the "Open()" method
+
+
+ /**
+ * Starts a new page
+ *
+ * @param string The page orientation (p, portrait, l or landscape)
+ *
+ * @access public
+ */
+ function AddPage($orientation = '')
+ {
+ // Backups some core variables
+ $family = $this->FontFamily;
+ $style = $this->FontStyle . ($this->underline ? 'U' : '');
+ $size = $this->FontSizePt;
+ $lw = $this->LineWidth;
+ $dc = $this->DrawColor;
+ $fc = $this->FillColor;
+ $tc = $this->TextColor;
+ $cf = $this->ColorFlag;
+
+ // If a page is already defined close it before starting the new one
+ if ($this->page > 0) {
+ // Page footer
+ $this->InFooter = TRUE;
+ $this->Footer();
+ $this->InFooter = FALSE;
+ // Close page
+ $this->_endpage();
+ }
+
+ // Do start the new page
+ $this->_beginpage($orientation);
+ // Sets line cap style to square
+ $this->_out('2 J');
+ // Sets line width
+ $this->LineWidth = $lw;
+ $this->_out($lw . ' w');
+ // Sets font
+ if ($family) {
+ $this->SetFont($family, $style, $size);
+ }
+ // Sets colors
+ $this->DrawColor = $dc;
+ if ($dc != '0 G') {
+ $this->_out($dc);
+ }
+ $this->FillColor = $fc;
+ if ($fc != '0 g') {
+ $this->_out($fc);
+ }
+ $this->TextColor = $tc;
+ $this->ColorFlag = $cf;
+ // Sets Page header
+ $this->Header();
+ // Restores line width
+ if ($this->LineWidth != $lw) {
+ $this->LineWidth = $lw;
+ $this->_out($lw . ' w');
+ }
+ // Restores font
+ if ($family) {
+ $this->SetFont($family, $style, $size);
+ }
+ // Restores colors
+ if ($this->DrawColor!=$dc) {
+ $this->DrawColor = $dc;
+ $this->_out($dc);
+ }
+ if ($this->FillColor!=$fc) {
+ $this->FillColor = $fc;
+ $this->_out($fc);
+ }
+ $this->TextColor = $tc;
+ $this->ColorFlag = $cf;
+ } // end of the "AddPage()" method
+
+
+ /**
+ * Terminates and closes the document
+ *
+ * @access public
+ */
+ function Close()
+ {
+ // Terminates document
+ if ($this->page == 0) {
+ $this->AddPage();
+ }
+
+ // Displays the page footer
+ $this->InFooter = TRUE;
+ $this->Footer();
+ $this->InFooter = FALSE;
+
+ // Closes page and document
+ $this->_endpage();
+ $this->_enddoc();
+ } // end of the "Close()" method
+
+
+ /**
+ * Gets the current page number
+ *
+ * @return integer The current page number
+ *
+ * @access public
+ */
+ function PageNo()
+ {
+ return $this->page;
+ } // end of the "PageNo()" method
+
+
+ /**
+ * Sets color for all stroking operations
+ *
+ * @param integer The red level (0 to 255)
+ * @param integer The green level (0 to 255)
+ * @param integer The blue level (0 to 255)
+ *
+ * @access public
+ */
+ function SetDrawColor($r, $g = -1, $b = -1)
+ {
+ if (($r == 0 && $g == 0 && $b == 0) || $g == -1) {
+ $this->DrawColor = substr($r / 255, 0, 5) . ' G';
+ } else {
+ $this->DrawColor = substr($r / 255, 0, 5) . ' '
+ . substr($g / 255, 0, 5) . ' '
+ . substr($b / 255, 0, 5) . ' RG';
+ } // end if... else...
+
+ // If a page is defined, applies this property
+ if ($this->page > 0) {
+ $this->_out($this->DrawColor);
+ }
+ } // end of the "SetDrawColor()" method
+
+
+ /**
+ * Sets color for all filling operations
+ *
+ * @param integer The red level (0 to 255)
+ * @param integer The green level (0 to 255)
+ * @param integer The blue level (0 to 255)
+ *
+ * @access public
+ */
+ function SetFillColor($r, $g = -1, $b =-1)
+ {
+ if (($r == 0 && $g == 0 && $b == 0) || $g == -1) {
+ $this->FillColor = substr($r / 255, 0, 5) . ' g';
+ } else {
+ $this->FillColor = substr($r / 255, 0, 5) . ' '
+ . substr($g / 255, 0, 5) . ' '
+ . substr($b / 255, 0, 5) . ' rg';
+ } // end if... else...
+
+ $this->ColorFlag = ($this->FillColor != $this->TextColor);
+
+ // If a page is defined, applies this property
+ if ($this->page > 0) {
+ $this->_out($this->FillColor);
+ }
+ } // end of the "SetDrawColor()" method
+
+
+ /**
+ * Sets color for text
+ *
+ * @param integer The red level (0 to 255)
+ * @param integer The green level (0 to 255)
+ * @param integer The blue level (0 to 255)
+ *
+ * @access public
+ */
+ function SetTextColor($r, $g = -1, $b =-1)
+ {
+ if (($r == 0 && $g == 0 && $b == 0) || $g == -1) {
+ $this->TextColor = substr($r / 255, 0, 5) . ' g';
+ } else {
+ $this->TextColor = substr($r / 255, 0, 5) . ' '
+ . substr($g / 255, 0, 5) . ' '
+ . substr($b / 255, 0, 5) . ' rg';
+ } // end if... else...
+
+ $this->ColorFlag = ($this->FillColor != $this->TextColor);
+ } // end of the "SetTextColor()" method
+
+
+ /**
+ * Sets the line width
+ *
+ * @param double The line width
+ *
+ * @access public
+ */
+ function SetLineWidth($width)
+ {
+ $this->LineWidth = $width;
+
+ // If a page is defined, applies this property
+ if ($this->page > 0) {
+ $this->_out($width . ' w');
+ }
+ } // end of the "SetLineWidth()" method
+
+
+ /**
+ * Draws a line
+ *
+ * @param double The horizontal position of the starting point
+ * @param double The vertical position of the starting point
+ * @param double The horizontal position of the ending point
+ * @param double The vertical position of the ending point
+ *
+ * @access public
+ */
+ function Line($x1, $y1, $x2, $y2)
+ {
+ $this->_out($x1 . ' -' . $y1 . ' m ' . $x2 . ' -' . $y2 . ' l S');
+ } // end of the "Line()" method
+
+
+ /**
+ * Draws a rectangle
+ *
+ * @param double The horizontal position of the top left corner
+ * @param double The vertical position of the top left corner
+ * @param double The horizontal position of the bottom right corner
+ * @param double The vertical position of the bottom right corner
+ * @param string The rectangle style
+ *
+ * @access public
+ */
+ function Rect($x, $y, $w, $h, $style = '')
+ {
+ if ($style == 'F') {
+ $op = 'f';
+ } else if ($style == 'FD' || $style=='DF') {
+ $op = 'B';
+ } else {
+ $op = 'S';
+ } // end if... else if... else
+
+ $this->_out($x . ' -' . $y . ' ' . $w . ' -' . $h . ' re ' . $op);
+ } // end of the "Rect()" method
+
+
+ /**
+ * Adds a TrueType font
+ *
+ * @param string The font name
+ * @param string The font style (B, I, BI)
+ * @param string The font file definition
+ *
+ * @access public
+ */
+ function AddFont($family, $style = '', $file = '')
+ {
+ $family = strtolower($family);
+ $style = strtoupper($style);
+ if ($style == 'IB') {
+ $style = 'BI';
+ }
+ if (isset($this->fonts[$family . $style])) {
+ $this->Error('Font already added: ' . $family . ' ' . $style);
+ }
+ if ($file == '') {
+ $file = str_replace(' ', '', $family) . strtolower($style) . '.php3';
+ }
+ // loic1: PHP3 compatibility
+ // if (defined('FPDF_FONTPATH')) {
+ // $file = FPDF_FONTPATH . $file;
+ // }
+ if (isset($GLOBALS['FPDF_font_path'])) {
+ $file = $GLOBALS['FPDF_font_path'] . $file;
+ }
+ include($file);
+ if (!isset($name)) {
+ $this->Error('Could not include font definition file');
+ }
+
+ $i = count($this->fonts) + 1;
+ $this->fonts[$family . $style] = array('i' => $i,
+ 'type' => $type,
+ 'name' => $name,
+ 'desc' => $desc,
+ 'up' => $up,
+ 'ut' => $ut,
+ 'cw' => $cw,
+ 'enc' => $enc,
+ 'file' => $file);
+ // Searches existing encodings
+ if ($diff) {
+ $d = 0;
+ $nb = count($this->diffs);
+ for ($i = 1; $i <= $nb; $i++) {
+ if ($this->diffs[$i] == $diff) {
+ $d = $i;
+ break;
+ } // end if
+ } // end for
+ if ($d == 0) {
+ $d = $nb + 1;
+ $this->diffs[$d] = $diff;
+ } // end if
+ $this->fonts[$family . $style]['diff'] = $d;
+ } // end if
+
+ if ($file) {
+ $this->FontFiles[$file] = array('originalsize' => $originalsize);
+ }
+ } // end of the "AddFont()" method
+
+
+ /**
+ * Sets font size
+ *
+ * @param double The font size (in points)
+ *
+ * @access public
+ */
+ function SetFontSize($size)
+ {
+ if ($this->FontSizePt == $size) {
+ return;
+ }
+ $this->FontSizePt = $size;
+ $this->FontSize = $this->_FPDF_round($size / $this->k, 2);
+ if($this->page > 0)
+ $this->_out('BT /F' . $this->CurrentFont['i'] . ' ' . $this->FontSize . ' Tf ET');
+ } // end of the "SetFontSize()" method
+
+
+ /**
+ * Creates a new internal link
+ *
+ * @return integer The link id
+ *
+ * @access public
+ */
+ function AddLink()
+ {
+ $n = count($this->links) + 1;
+ $this->links[$n] = array(0, 0);
+ return $n;
+ } // end of the "AddLink()" method
+
+
+ /**
+ * Sets destination of internal link
+ *
+ * @param integer The link id
+ * @param double The y position on the page
+ * @param integer The page number
+ *
+ * @access public
+ */
+ function SetLink($link, $y = 0, $page = -1)
+ {
+ if ($y == -1) {
+ $y = $this->y;
+ }
+ if ($page == -1) {
+ $page = $this->page;
+ }
+ $this->links[$link] = array($page, $this->hPt - $y * $this->k);
+ } // end of the "SetLink()" method
+
+
+ /**
+ * Put a link inside a rectangular area of the page
+ *
+ * @param double The top left x position
+ * @param double The top left y position
+ * @param double The rectangle width
+ * @param double The rectangle height
+ * @param mixed The link id or an url
+ *
+ * @access public
+ */
+ 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);
+ } // end of the "Link()" method
+
+
+ /**
+ * Outputs a string
+ *
+ * @param double The x position
+ * @param double The y position
+ * @param string The string
+ *
+ * @access public
+ */
+ function Text($x, $y, $txt)
+ {
+ $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)));
+ $s = 'BT ' . $x . ' -' . $y . ' Td (' . $txt . ') Tj ET';
+ if ($this->underline && $txt != '') {
+ $s .= ' ' . $this->_dounderline($x, $y, $txt);
+ }
+ if ($this->ColorFlag) {
+ $s = 'q ' . $this->TextColor . ' ' . $s . ' Q';
+ }
+ $this->_out($s);
+ } // end of the "Text()" method
+
+
+ /**
+ * Gets whether automatic page break is on or not
+ *
+ * @return boolean Whether automatic page break is on or not
+ *
+ * @access public
+ */
+ function AcceptPageBreak()
+ {
+ return $this->AutoPageBreak;
+ } // end of the "AcceptPageBreak()" method
+
+
+ /**
+ * Output a cell
+ *
+ * @param double The cell width
+ * @param double The cell height
+ * @param string The text to output
+ * @param mixed Wether to add borders or not (see the manual)
+ * @param integer Where to put the cursor once the output is done
+ * @param string Align mode
+ * @param integer Whether to fill the cell with a color or not
+ * @param mixed The link id or an url
+ *
+ * @access public
+ */
+ function Cell($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0, $link = '')
+ {
+ if ($this->y + $h > $this->PageBreakTrigger
+ && !$this->InFooter
+ && $this->AcceptPageBreak()) {
+ $x = $this->x;
+ $ws = $this->ws;
+ if ($ws > 0) {
+ $this->ws = 0;
+ $this->_out('0 Tw');
+ }
+ $this->AddPage($this->CurOrientation);
+ $this->x = $x;
+ if ($ws > 0) {
+ $this->ws = $ws;
+ $this->_out($ws . ' Tw');
+ }
+ } // end if
+
+ if ($w == 0) {
+ $w = $this->w - $this->rMargin - $this->x;
+ }
+
+ $s = '';
+ if ($fill == 1 || $border == 1) {
+ $s .= $this->x . ' -' . $this->y . ' ' . $w . ' -' . $h . ' re ';
+ if ($fill == 1) {
+ $s .= ($border == 1) ? 'B ' : 'f ';
+ } else {
+ $s .= 'S ';
+ }
+ } // end if
+
+ if (is_string($border)) {
+ $x = $this->x;
+ $y = $this->y;
+ if (strpos(' ' . $border, 'L')) {
+ $s .= $x . ' -' . $y . ' m ' . $x . ' -' . ($y + $h) . ' l S ';
+ }
+ if (strpos(' ' . $border, 'T')) {
+ $s .= $x . ' -' . $y . ' m ' . ($x+$w) . ' -' . $y . ' l S ';
+ }
+ if (strpos(' ' . $border, 'R')) {
+ $s .= ($x + $w) . ' -' . $y . ' m ' . ($x+$w) . ' -' . ($y+$h) . ' l S ';
+ }
+ if (strpos(' ' . $border, 'B')) {
+ $s .= $x . ' -' . ($y + $h) . ' m ' . ($x + $w) . ' -' . ($y + $h) . ' l S ';
+ }
+ } // end if
+
+ if ($txt != '') {
+ if ($align == 'R') {
+ $dx = $w - $this->cMargin - $this->GetStringWidth($txt);
+ }
+ else if ($align == 'C') {
+ $dx = ($w - $this->GetStringWidth($txt)) / 2;
+ }
+ else {
+ $dx = $this->cMargin;
+ }
+ $txt = str_replace(')', '\\)', str_replace('(', '\\(', str_replace('\\', '\\\\', $txt)));
+ if ($this->ColorFlag) {
+ $s .= 'q ' . $this->TextColor . ' ';
+ }
+ $s .= 'BT ' . ($this->x+$dx)
+ . ' -' . ($this->y + .5 * $h + .3 * $this->FontSize)
+ . ' Td (' . $txt . ') Tj ET';
+ if ($this->underline) {
+ $s .= ' ' . $this->_dounderline($this->x+$dx, $this->y + .5 * $h + .3 * $this->FontSize, $txt);
+ }
+ if ($this->ColorFlag) {
+ $s .= ' Q';
+ }
+ if ($link) {
+ $this->Link($this->x + $this->cMargin, $this->y + .5 * $h - .5 * $this->FontSize, $this->GetStringWidth($txt), $this->FontSize, $link);
+ }
+ } // end if
+
+ if ($s) {
+ $this->_out($s);
+ }
+ $this->lasth = $h;
+
+ if ($ln > 0) {
+ // Go to next line
+ $this->y += $h;
+ if ($ln == 1) {
+ $this->x = $this->lMargin;
+ }
+ } else {
+ $this->x += $w;
+ }
+ } // end of the "Cell()" method
+
+
+ /**
+ * Output text with automatic or explicit line breaks
+ *
+ * @param double The cell width
+ * @param double The cell height
+ * @param string The text to output
+ * @param mixed Wether to add borders or not (see the manual)
+ * @param string Align mode
+ * @param integer Whether to fill the cell with a color or not
+ *
+ * @access public
+ */
+ function MultiCell($w, $h, $txt, $border = 0, $align = 'J', $fill = 0)
+ {
+ // loic1: PHP3 compatibility
+ // $cw = &$this->CurrentFont['cw'];
+ if ($w == 0) {
+ $w = $this->w - $this->lMargin - $this->x;
+ }
+ $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
+ $s = str_replace("\r", '', $txt);
+ $nb = strlen($s);
+ if ($nb>0 && $s[$nb - 1] == "\n") {
+ $nb--;
+ }
+
+ $b = 0;
+ if ($border) {
+ if ($border == 1) {
+ $border = 'LTRB';
+ $b = 'LRT';
+ $b2 = 'LR';
+ }
+ else {
+ $b2 = '';
+ if (strpos(' ' . $border, 'L')) {
+ $b2 .= 'L';
+ }
+ if (strpos(' ' . $border, 'R')) {
+ $b2 .= 'R';
+ }
+ $b = (strpos(' ' . $border, 'T')) ? $b2 . 'T' : $b2;
+ } // end if... else...
+ } // end if
+
+ $sep = -1;
+ $i = 0;
+ $j = 0;
+ $l = 0;
+ $ns = 0;
+ $nl = 1;
+ while ($i < $nb) {
+ // Gets next character
+ $c = $s[$i];
+
+ // Explicit line break
+ if ($c == "\n") {
+ if ($this->ws > 0) {
+ $this->ws = 0;
+ $this->_out('0 Tw');
+ }
+ $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
+ $i++;
+ $sep = -1;
+ $j = $i;
+ $l = 0;
+ $ns = 0;
+ $nl++;
+ if ($border && $nl == 2) {
+ $b = $b2;
+ }
+ continue;
+ } // end if
+
+ // Space character
+ if ($c == ' ') {
+ $sep = $i;
+ $ls = $l;
+ $ns++;
+ } // end if
+
+ // Other character
+ // loic1: PHP3 compatibility
+ // $l += $cw[$c];
+ $l += $this->CurrentFont['cw'][$c];
+ if ($l > $wmax) {
+ // Automatic line break
+ if ($sep == -1) {
+ if ($i == $j) {
+ $i++;
+ }
+ if ($this->ws > 0) {
+ $this->ws = 0;
+ $this->_out('0 Tw');
+ }
+ $this->Cell($w, $h, substr($s, $j, $i - $j), $b, 2, $align, $fill);
+ }
+ else {
+ if ($align == 'J') {
+ $this->ws = ($ns > 1)
+ ? $this->_FPDF_round(($wmax - $ls) / 1000 * $this->FontSize / ($ns - 1), 3)
+ : 0;
+ $this->_out($this->ws.' Tw');
+ }
+ $this->Cell($w, $h, substr($s, $j, $sep - $j), $b, 2, $align, $fill);
+ $i = $sep + 1;
+ } // end if... else...
+
+ $sep = -1;
+ $j = $i;
+ $l = 0;
+ $ns = 0;
+ $nl++;
+ if ($border && $nl == 2) {
+ $b = $b2;
+ }
+ }
+ else {
+ $i++;
+ } // end if... else
+ } // end while
+
+ // Last chunk
+ if ($this->ws > 0) {
+ $this->ws = 0;
+ $this->_out('0 Tw');
+ }
+
+ if ($border && strpos(' ' . $border, 'B')) {
+ $b .= 'B';
+ }
+ $this->Cell($w, $h, substr($s, $j, $i), $b, 2, $align, $fill);
+ $this->x = $this->lMargin;
+ } // end of the "MultiCell()" method
+
+
+ /**
+ * Output text in flowing mode
+ *
+ * @param double The line height
+ * @param string The text to output
+ * @param mixed The link id or an url
+ *
+ * @access public
+ */
+ function Write($h, $txt, $link = '')
+ {
+ // loic1: PHP3 compatibility
+ // $cw = &$this->CurrentFont['cw'];
+ $w = $this->w - $this->rMargin - $this->x;
+ $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
+ $s = str_replace("\r", '', $txt);
+ $nb = strlen($s);
+ $sep = -1;
+ $i = 0;
+ $j = 0;
+ $l = 0;
+ $nl = 1;
+
+ while ($i < $nb) {
+ // Gets next character
+ $c = $s[$i];
+
+ // Explicit line break
+ if ($c == "\n") {
+ $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
+ $i++;
+ $sep = -1;
+ $j = $i;
+ $l = 0;
+ if ($nl == 1) {
+ $this->x = $this->lMargin;
+ $w = $this->w - $this->rMargin - $this->x;
+ $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
+ }
+ $nl++;
+ continue;
+ }
+
+ // Space character
+ if ($c == ' ') {
+ $sep = $i;
+ $ls = $l;
+ } // end if
+
+ // Other character
+ // loic1: PHP3 compatibility
+ // $l += $cw[$c];
+ $l += $this->CurrentFont['cw'][$c];
+ if ($l > $wmax) {
+ // Automatic line break
+ if ($sep == -1) {
+ if($this->x > $this->lMargin) {
+ // Move to next line
+ $this->x =$this->lMargin;
+ $this->y +=$h;
+ $w = $this->w - $this->rMargin - $this->x;
+ $wmax =($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
+ $i++;
+ $nl++;
+ continue;
+ }
+ if ($i == $j) {
+ $i++;
+ }
+ $this->Cell($w, $h, substr($s, $j, $i - $j), 0, 2, '', 0, $link);
+ }
+ else {
+ $this->Cell($w, $h, substr($s, $j, $sep - $j), 0, 2, '', 0, $link);
+ $i = $sep + 1;
+ } // end if... else...
+
+ $sep = -1;
+ $j = $i;
+ $l = 0;
+ if ($nl == 1) {
+ $this->x = $this->lMargin;
+ $w = $this->w - $this->rMargin - $this->x;
+ $wmax = ($w - 2 * $this->cMargin) * 1000 / $this->FontSize;
+ }
+ $nl++;
+ }
+ else {
+ $i++;
+ } // end if... else...
+ } // end while
+
+ // Last chunk
+ if ($i != $j) {
+ $w = $this->_FPDF_round($l / 1000 * $this->FontSize, 2);
+ $this->Cell($w, $h, substr($s, $j, $i), 0, 0, '', 0, $link);
+ }
+ } // end of the "Write()" method
+
+
+ /**
+ * Puts an image on the page
+ *
+ * @param string The image file (JPEG or PNG format)
+ * @param double The top left x position
+ * @param double The top left y position
+ * @param double The image width
+ * @param double The image height
+ * @param string The image type (JPG, JPEG or PNG)
+ * @param mixed The link id or an url
+ *
+ * @access public
+ */
+ function Image($file, $x, $y, $w, $h = 0, $type = '', $link = '')
+ {
+ if (!isset($this->images[$file])) {
+ // First use of image, get info
+ if ($type == '') {
+ $pos = strrpos($file, '.');
+ if (!$pos) {
+ $this->Error('Image file has no extension and no type was specified: ' . $file);
+ }
+ $type = substr($file, $pos + 1);
+ } // end if
+
+ $type = strtolower($type);
+ $mqr = get_magic_quotes_runtime();
+ set_magic_quotes_runtime(0);
+ if ($type == 'jpg' || $type == 'jpeg') {
+ $info = $this->_parsejpg($file);
+ }
+ else if ($type == 'png') {
+ $info = $this->_parsepng($file);
+ }
+ else {
+ $this->Error('Unsupported image file type: ' . $type);
+ }
+ set_magic_quotes_runtime($mqr);
+ $info['n'] = count($this->images) + 1;
+ $this->images[$file] = $info;
+ }
+ else {
+ $info = $this->images[$file];
+ } // end if... else...
+
+ // Automatic width or height calculus
+ if ($w == 0) {
+ $w = $this->_FPDF_round($h * $info['w'] / $info['h'], 2);
+ }
+ if ($h == 0) {
+ $h = $this->_FPDF_round($w * $info['h'] / $info['w'], 2);
+ }
+ $this->_out('q ' . $w . ' 0 0 ' . $h . ' ' . $x . ' -' . ($y+$h) . ' cm /I' . $info['n'] . ' Do Q');
+
+ if ($link) {
+ $this->Link($x, $y, $w, $h, $link);
+ }
+ } // end of the "Image()" method
+
+
+ /**
+ * Appends a line feed
+ *
+ * @param double The line height
+ *
+ * @access public
+ */
+ function Ln($h = '')
+ {
+ $this->x = $this->lMargin;
+ // Sets default line height to last cell height
+ if (is_string($h)) {
+ $this->y += $this->lasth;
+ }
+ else {
+ $this->y += $h;
+ }
+ } // end of the "Ln()" method
+
+
+ /**
+ * Gets x position
+ *
+ * @return double The x position
+ *
+ * @access public
+ */
+ function GetX()
+ {
+ return $this->x;
+ } // end of the "GetX()" method
+
+
+ /**
+ * Sets x position
+ *
+ * @param double The x position
+ *
+ * @access public
+ */
+ function SetX($x)
+ {
+ if ($x >= 0) {
+ $this->x = $x;
+ } else {
+ $this->x = $this->w + $x;
+ }
+ } // end of the "SetX()" method
+
+
+ /**
+ * Gets y position
+ *
+ * @return double The y position
+ *
+ * @access public
+ */
+ function GetY()
+ {
+ return $this->y;
+ } // end of the "GetY()" method
+
+
+ /**
+ * Sets y position and resets x
+ *
+ * @param double The y position
+ *
+ * @access public
+ */
+ function SetY($y)
+ {
+ $this->x = $this->lMargin;
+ if ($y >= 0) {
+ $this->y = $y;
+ } else {
+ $this->y = $this->h + $y;
+ }
+ } // end of the "SetY()" method
+
+
+ /**
+ * Sets x and y positions
+ *
+ * @param double The x position
+ * @param double The y position
+ *
+ * @access public
+ */
+ function SetXY($x,$y)
+ {
+ $this->SetY($y);
+ $this->SetX($x);
+ } // end of the "SetXY()" method
+
+
+ /**
+ * Outputs PDF to file or browser
+ *
+ * @param string The file name
+ * @param boolean Whether to display the document inside the browser
+ * (with Acrobat plugin), to enforce download as file or
+ * to save it on the server
+ *
+ * @global string The browser id string
+ *
+ * @access public
+ */
+ function Output($file = '', $download = FALSE)
+ {
+ global $HTTP_USER_AGENT;
+
+ if ($this->state < 3) {
+ $this->Close();
+ }
+
+ // Send to browser
+ if ($file == '') {
+ header('Content-Type: application/pdf');
+ if (headers_sent()) {
+ $this->Error('Some data has already been output to browser, can\'t send PDF file');
+ }
+ header('Content-Length: ' . strlen($this->buffer));
+ header('Content-disposition: inline; filename=doc.pdf');
+ echo $this->buffer;
+ }
+ // Download file
+ else if ($download) {
+ if (!empty($HTTP_USER_AGENT)
+ && (strpos($HTTP_USER_AGENT, 'MSIE 5.5') || strpos($HTTP_USER_AGENT, 'Opera'))) {
+ header('Content-Type: application/dummy');
+ }
+ else {
+ header('Content-Type: application/octet-stream');
+ }
+ if (headers_sent()) {
+ $this->Error('Some data has already been output to browser, can\'t send PDF file');
+ }
+ header('Content-Length: ' . strlen($this->buffer));
+ header('Content-disposition: attachment; filename=' . $file);
+ echo $this->buffer;
+ }
+ // Save file locally
+ else {
+ $f = fopen($file, 'wb');
+ if (!$f) {
+ $this->Error('Unable to create output file: ' . $file);
+ }
+ fwrite($f, $this->buffer, strlen($this->buffer));
+ fclose($f);
+ } // end if... else if... else
+ } // end of the "Output()" method
+
+} // End of the "FPDF" class
+
+
+
+/**
+ * Handles silly IE contype request
+ */
+if (!empty($_ENV) && isset($_ENV['HTTP_USER_AGENT'])) {
$HTTP_USER_AGENT = $_ENV['HTTP_USER_AGENT'];
}
+else if (!empty($_SERVER) && isset($_SERVER['HTTP_USER_AGENT'])) {
+ $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
+}
else if (!empty($HTTP_ENV_VARS) && isset($HTTP_ENV_VARS['HTTP_USER_AGENT'])) {
$HTTP_USER_AGENT = $HTTP_ENV_VARS['HTTP_USER_AGENT'];
}
-
-//Handle silly IE contype request
-if (isset($HTTP_USER_AGENT) and $HTTP_USER_AGENT == 'contype') {
- header('Content-Type: application/pdf');
- exit();
+else if (@getenv('HTTP_USER_AGENT')) {
+ $HTTP_USER_AGENT = getenv('HTTP_USER_AGENT');
}
+if ($HTTP_USER_AGENT == 'contype') {
+ header('Content-Type: application/pdf');
+ exit();
+}
+
+
+/**
+ * Gets PHP version (PHP3 or PHP4)
+ */
+$FPDF_is_php4 = (floor(phpversion()) >= 4);
?>
diff --git a/pdf_schema.php3 b/pdf_schema.php3
index 647fd344f..2e0848705 100644
--- a/pdf_schema.php3
+++ b/pdf_schema.php3
@@ -17,14 +17,43 @@ require('./libraries/common.lib.php3');
* Gets the "fpdf" libraries and defines the pdf font path
*/
require('./libraries/fpdf/fpdf.php3');
-define('FPDF_FONTPATH', './libraries/fpdf/font/');
+// loic1: PHP3 compatibility
+// define('FPDF_FONTPATH', './libraries/fpdf/font/');
+$FPDF_font_path = './libraries/fpdf/font/';
+
+
+/**
+ * Emulates the "array_search" function with PHP < 4.0.5
+ */
+if (PMA_PHP_INT_VERSION < 40005) {
+ function array_search($needle, $haystack) {
+ $match = FALSE;
+
+ reset($haystack);
+ while (list($key, $value) = each($haystack)) {
+ if ($value == $needle) {
+ $match = $key;
+ }
+ } // end while
+
+ return $match;
+ } // end of the "array_search" function
+} // end if
+
/**
* Extends the "FPDF" class and prepares the work
+ *
+ * @access public
+ *
+ * @see FPDF
*/
class PMA_PDF extends FPDF
{
+ /**
+ * Defines private properties
+ */
var $x_min;
var $y_min;
var $l_marg;
@@ -32,22 +61,88 @@ class PMA_PDF extends FPDF
var $scale;
var $title;
- function PMA_PDF_setScale($scale = 1, $x_min = 0, $y_min = 0, $l_marg, $t_marg)
- {
- $this->scale = $scale;
- $this->x_min = $x_min;
- $this->y_min = $y_min;
- $this->l_marg = $l_marg;
- $this->t_marg = $t_marg;
- }
+ /**
+ * The PMA_PDF constructor
+ *
+ * This function just refers to the "FPDF" constructor: with PHP3 a class
+ * must have a constructor
+ *
+ * @param string The page orientation (p, portrait, l or landscape)
+ * @param string The unit for sizes (pt, mm, cm or in)
+ * @param mixed The page format (A3, A4, A5, letter, legal or an array
+ * with page sizes)
+ *
+ * @access public
+ *
+ * @see FPDF::FPDF()
+ */
+ function PMA_PDF($orientation = 'P', $unit = 'mm', $format = 'A4')
+ {
+ $this->FPDF($orientation, $unit, $format);
+ } // end of the "PMA_PDF()" method
+
+
+ /**
+ * Sets the scalling factor, defines minimum coordinates and margins
+ *
+ * @param double The scalling factor
+ * @param double The minimum X coordinate
+ * @param double The minimum Y coordinate
+ * @param double The left margin
+ * @param double The top margin
+ *
+ * @access public
+ */
+ function PMA_PDF_setScale($scale = 1, $x_min = 0, $y_min = 0, $l_marg = -1, $t_marg = -1)
+ {
+ $this->scale = $scale;
+ $this->x_min = $x_min;
+ $this->y_min = $y_min;
+ if ($this->l_marg != -1) {
+ $this->l_marg = $l_marg;
+ }
+ if ($this->t_marg != -1) {
+ $this->t_marg = $t_marg;
+ }
+ } // end of the "PMA_PDF_setScale" function
+
+
+ /**
+ * Outputs a scalled cell
+ *
+ * @param double The cell width
+ * @param double The cell height
+ * @param string The text to output
+ * @param mixed Wether to add borders or not
+ * @param integer Where to put the cursor once the output is done
+ * @param string Align mode
+ * @param integer Whether to fill the cell with a color or not
+ *
+ * @access public
+ *
+ * @see FPDF::Cell()
+ */
function PMA_PDF_cellScale($w, $h = 0, $txt = '', $border = 0, $ln = 0, $align = '', $fill = 0)
{
$h = $h / $this->scale;
$w = $w / $this->scale;
$this->Cell($w, $h, $txt, $border, $ln, $align, $fill);
- }
+ } // end of the "PMA_PDF_cellScale" function
+
+ /**
+ * Draws a scalled line
+ *
+ * @param double The horizontal position of the starting point
+ * @param double The vertical position of the starting point
+ * @param double The horizontal position of the ending point
+ * @param double The vertical position of the ending point
+ *
+ * @access public
+ *
+ * @see FPDF::Line()
+ */
function PMA_PDF_lineScale($x1, $y1, $x2, $y2)
{
$x1 = ($x1 - $this->x_min) / $this->scale + $this->l_marg;
@@ -55,48 +150,75 @@ class PMA_PDF extends FPDF
$x2 = ($x2 - $this->x_min) / $this->scale + $this->l_marg;
$y2 = ($y2 - $this->y_min) / $this->scale + $this->t_marg;
$this->Line($x1, $y1, $x2, $y2);
- }
+ } // end of the "PMA_PDF_lineScale" function
+
+ /**
+ * Sets x and y scalled positions
+ *
+ * @param double The x position
+ * @param double The y position
+ *
+ * @access public
+ *
+ * @see FPDF::SetXY()
+ */
function PMA_PDF_setXyScale($x, $y)
{
$x = ($x - $this->x_min) / $this->scale + $this->l_marg;
$y = ($y - $this->y_min) / $this->scale + $this->t_marg;
$this->SetXY($x, $y);
- }
+ } // end of the "PMA_PDF_setXyScale" function
+
+ /**
+ * Sets the X scalled positions
+ *
+ * @param double The x position
+ *
+ * @access public
+ *
+ * @see FPDF::SetX()
+ */
function PMA_PDF_setXScale($x)
{
$x = ($x - $this->x_min) / $this->scale + $this->l_marg;
$this->SetX($x);
- }
+ } // end of the "PMA_PDF_setXScale" function
+
+ /**
+ * Sets the scalled font size
+ *
+ * @param double The font size (in points)
+ *
+ * @access public
+ *
+ * @see FPDF::SetFontSize()
+ */
function PMA_PDF_setFontSizeScale($size)
{
// Set font size in points
$size = $size / $this->scale;
$this->SetFontSize($size);
- }
+ } // end of the "PMA_PDF_setFontSizeScale" function
+
+ /**
+ * Sets the scalled line width
+ *
+ * @param double The line width
+ *
+ * @access public
+ *
+ * @see FPDF::SetLineWidth()
+ */
function PMA_PDF_setLineWidthScale($width)
{
$width = $width / $this->scale;
$this->SetLineWidth($width);
- }
+ } // end of the "PMA_PDF_setLineWidthScale" function
- /**
- * Aliases the "Error()" function from the FPDF class to the
- * "PMA_PDF_die()" one
- *
- * @param string the error mesage
- *
- * @access public
- *
- * @see PMA_PDF_die()
- */
- function Error($error_message = '')
- {
- PMA_PDF_die($error_message);
- } // end of the "Error()" method
/**
* Displays an error message
@@ -140,10 +262,334 @@ class PMA_PDF extends FPDF
include('./footer.inc.php3');
exit();
} // end of the "PMA_PDF_die()" function
-} // end class "PMA_PDF"
+
+ /**
+ * Aliases the "Error()" function from the FPDF class to the
+ * "PMA_PDF_die()" one
+ *
+ * @param string the error mesage
+ *
+ * @access public
+ *
+ * @see PMA_PDF_die()
+ */
+ function Error($error_message = '')
+ {
+ $this->PMA_PDF_die($error_message);
+ } // end of the "Error()" method
+} // end of the "PMA_PDF" class
+
+
+
+/**
+ * Draws tables schema
+ *
+ * @access private
+ *
+ * @see PMA_RT
+ */
+class PMA_RT_Table
+{
+ /**
+ * Defines private properties
+ */
+ var $nb_fiels;
+ var $table_name;
+ var $width = 0;
+ var $height;
+ var $fields = array();
+ var $height_cell = 6;
+ var $x, $y;
+
+
+ /**
+ * Sets the width of the table
+ *
+ * @param integer The font size
+ *
+ * @global object The current PDF document
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
+ function PMA_RT_Table_setWidth($ff)
+ {
+ global $pdf;
+
+ reset($this->fields);
+ while (list(, $field) = each($this->fields)) {
+ $this->width = max($this->width, $pdf->GetStringWidth($field));
+ }
+ $this->width += $pdf->GetStringWidth(' ');
+ $pdf->SetFont($ff, 'B');
+ $this->width = max($this->width, $pdf->GetStringWidth(' ' . $this->table_name));
+ $pdf->SetFont($ff, '');
+ } // end of the "PMA_RT_Table_setWidth()" method
+
+
+ /**
+ * Sets the height of the table
+ *
+ * @access private
+ */
+ function PMA_RT_Table_setHeight()
+ {
+ $this->height = (count($this->fields) + 1) * $this->height_cell;
+ } // end of the "PMA_RT_Table_setHeight()" method
+
+
+ /**
+ * Do draw the table
+ *
+ * @param boolean Whether to display table position or not
+ * @param integer The font size
+ *
+ * @global object The current PDF document
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
+ function PMA_RT_Table_draw($show_info, $ff)
+ {
+ global $pdf;
+
+ $pdf->PMA_PDF_setXyScale($this->x, $this->y);
+ $pdf->SetFont($ff, 'B');
+ $pdf->SetTextColor(200);
+ $pdf->SetFillColor(0, 0, 128);
+ if ($show_info){
+ $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, $pdf->_FPDF_round($this->width) . 'x' . $pdf->_FPDF_round($this->height) . ' ' . $this->table_name, 1, 1, 'C', 1);
+ } else {
+ $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, $this->table_name, 1, 1, 'C', 1);
+ }
+ $pdf->PMA_PDF_setXScale($this->x);
+ $pdf->SetFont($ff, '');
+ $pdf->SetTextColor(0);
+ $pdf->SetFillColor(255);
+
+ reset($this->fields);
+ while (list(, $field) = each($this->fields)) {
+ $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, ' ' . $field, 1, 1, 'L', 1);
+ $pdf->PMA_PDF_setXScale($this->x);
+ }
+ if ($pdf->PageNo() > 1) {
+ $pdf->PMA_PDF_die($GLOBALS['strScaleFactorSmall']);
+ }
+ } // end of the "PMA_RT_Table_draw()" method
+
+
+ /**
+ * The "PMA_RT_Table" constructor
+ *
+ * @param string The table name
+ * @param integer The font size
+ *
+ * @global object The current PDF document
+ * @global integer The current page number (from the
+ * $cfg['Servers'][$i]['table_coords'] table)
+ *
+ * @access private
+ *
+ * @see PMA_PDF, PMA_RT_Table::PMA_RT_Table_setWidth,
+ * PMA_RT_Table::PMA_RT_Table_setHeight
+ */
+ function PMA_RT_Table($table_name, $ff)
+ {
+ global $pdf, $pdf_page_number;
+
+ $this->table_name = $table_name;
+ $sql = 'DESCRIBE ' . PMA_backquote($table_name);
+ $result = mysql_query($sql);
+ if (!$result || !mysql_num_rows($result)) {
+ $pdf->PMA_PDF_die(sprintf($GLOBALS['strPdfInvalidTblName'], $table_name));
+ }
+ // load fields
+ while ($row = mysql_fetch_array($result)) {
+ $this->fields[] = $row[0];
+ }
+
+ //height and width
+ $this->PMA_RT_Table_setWidth($ff);
+ $this->PMA_RT_Table_setHeight();
+
+ //x and y
+ $sql = 'SELECT x, y FROM '
+ . PMA_backquote($GLOBALS['cfg']['Server']['table_coords'])
+ . ' WHERE table_name = \'' . PMA_sqlAddslashes($table_name) . '\''
+ . ' AND pdf_page_number = ' . $pdf_page_number;
+ $result = mysql_query($sql);
+ if (!$result || !mysql_num_rows($result)) {
+ $pdf->PMA_PDF_die(sprintf($GLOBALS['strConfigureTableCoord'], $table_name));
+ }
+ list($this->x, $this->y) = mysql_fetch_array($result);
+ $this->x = (double) $this->x;
+ $this->y = (double) $this->y;
+ } // end of the "PMA_RT_Table()" method
+} // end class "PMA_RT_Table"
+
+
+
+/**
+ * Draws relation links
+ *
+ * @access private
+ *
+ * @see PMA_RT
+ */
+class PMA_RT_Relation
+{
+ /**
+ * Defines private properties
+ */
+ var $x_src, $y_src;
+ var $src_dir ;
+ var $dest_dir;
+ var $x_dest, $y_dest;
+ var $w_tick = 5;
+
+
+ /**
+ * Gets arrows coordinates
+ *
+ * @param string The current table name
+ * @param string The relation column name
+ *
+ * @return array Arrows coordinates
+ *
+ * @access private
+ */
+ function PMA_RT_Relation_getXy($table, $column)
+ {
+ $pos = array_search($column, $table->fields);
+ // x_left, x_right, y
+ return array($table->x, $table->x + $table->width, $table->y + ($pos + 1.5) * $table->height_cell);
+ } // end of the "PMA_RT_Relation_getXy()" method
+
+
+ /**
+ * Do draws relation links
+ *
+ * @param boolean Whether to use one color per relation or not
+ * @param integer The id of the link to draw
+ *
+ * @global object The current PDF document
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
+ function PMA_RT_Relation_draw($change_color, $i)
+ {
+ global $pdf;
+
+ if ($change_color){
+ $d = $i % 6;
+ $j = ($i - $d) / 6;
+ $j = $j % 4;
+ $j++;
+ $case = array(
+ array(1, 0, 0),
+ array(0, 1, 0),
+ array(0, 0, 1),
+ array(1, 1, 0),
+ array(1, 0, 1),
+ array(0, 1, 1)
+ );
+ list ($a, $b, $c) = $case[$d];
+ $e = (1 - ($j - 1) / 6);
+ $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e); }
+ else {
+ $pdf->SetDrawColor(0);
+ } // end if... else...
+
+ $pdf->PMA_PDF_setLineWidthScale(0.2);
+ $pdf->PMA_PDF_lineScale($this->x_src, $this->y_src, $this->x_src + $this->src_dir * $this->w_tick, $this->y_src);
+ $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest, $this->x_dest, $this->y_dest);
+ $pdf->PMA_PDF_setLineWidthScale(0.1);
+ $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick, $this->y_src, $this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest);
+
+ //arrow
+ $root2 = 2 * sqrt(2);
+ $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src + $this->w_tick / $root2);
+ $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src - $this->w_tick / $root2);
+
+ $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest + $this->w_tick / $root2);
+ $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest - $this->w_tick / $root2);
+ $pdf->SetDrawColor(0);
+ } // end of the "PMA_RT_Table_draw()" method
+
+
+ /**
+ * The "PMA_RT_Relation" constructor
+ *
+ * @param string The master table name
+ * @param string The relation field in the master table
+ * @param string The foreign table name
+ * @param string The relation field in the foreign table
+ *
+ *
+ * @access private
+ *
+ * @see PMA_RT_Relation::PMA_RT_Relation_getXy
+ */
+ function PMA_RT_Relation($master_table, $master_field, $foreign_table, $foreign_field)
+ {
+ $src_pos = $this->PMA_RT_Relation_getXy($master_table , $master_field);
+ $dest_pos = $this->PMA_RT_Relation_getXy($foreign_table, $foreign_field);
+ $src_left = $src_pos[0] - $this->w_tick;
+ $src_right = $src_pos[1] + $this->w_tick;
+ $dest_left = $dest_pos[0] - $this->w_tick;
+ $dest_right = $dest_pos[1] + $this->w_tick;
+
+ $d1 = abs($src_left - $dest_left);
+ $d2 = abs($src_right - $dest_left);
+ $d3 = abs($src_left - $dest_right);
+ $d4 = abs($src_right - $dest_right);
+ $d = min($d1, $d2, $d3, $d4);
+
+ if ($d == $d1) {
+ $this->x_src = $src_pos[0];
+ $this->src_dir = -1;
+ $this->x_dest = $dest_pos[0];
+ $this->dest_dir = -1;
+ } else if ($d == $d2) {
+ $this->x_src = $src_pos[1];
+ $this->src_dir = 1;
+ $this->x_dest = $dest_pos[0];
+ $this->dest_dir = -1;
+ } else if ($d == $d3) {
+ $this->x_src = $src_pos[0];
+ $this->src_dir = -1;
+ $this->x_dest = $dest_pos[1];
+ $this->dest_dir = 1;
+ } else {
+ $this->x_src = $src_pos[1];
+ $this->src_dir = 1;
+ $this->x_dest = $dest_pos[1];
+ $this->dest_dir = 1;
+ }
+ $this->y_src = $src_pos[2];
+ $this->y_dest = $dest_pos[2];
+ } // end of the "PMA_RT_Relation()" method
+} // end of the "PMA_RT_Relation" class
+
+
+
+/**
+ * Draws and send the database schema
+ *
+ * @access public
+ *
+ * @see PMA_PDF
+ */
class PMA_RT
{
+ /**
+ * Defines private properties
+ */
var $tables = array();
var $relations = array();
var $ff = 'Arial';
@@ -157,10 +603,169 @@ class PMA_RT
var $l_marg = 10;
var $r_marg = 10;
+
+ /**
+ * Sets X and Y minimum and maximum for a table cell
+ *
+ * @param string The table name
+ *
+ * @access private
+ */
+ function PMA_RT_setMinMax($table)
+ {
+ $this->x_max = max($this->x_max, $table->x + $table->width);
+ $this->y_max = max($this->y_max, $table->y + $table->height);
+ $this->x_min = min($this->x_min, $table->x);
+ $this->y_min = min($this->y_min, $table->y);
+ } // end of the "PMA_RT_setMinMax()" method
+
+
+ /**
+ * Defines relation objects
+ *
+ * @param string The master table name
+ * @param string The relation field in the master table
+ * @param string The foreign table name
+ * @param string The relation field in the foreign table
+ *
+ * @access private
+ *
+ * @see PMA_RT_setMinMax()
+ */
+ function PMA_RT_addRelation($master_table , $master_field, $foreign_table, $foreign_field)
+ {
+ if (!isset($this->tables[$master_table])) {
+ $this->tables[$master_table] = new PMA_RT_Table($master_table, $this->ff);
+ $this->PMA_RT_setMinMax($this->tables[$master_table]);
+ }
+ if (!isset($this->tables[$foreign_table])) {
+ $this->tables[$foreign_table] = new PMA_RT_Table($foreign_table, $this->ff);
+ $this->PMA_RT_setMinMax($this->tables[$foreign_table]);
+ }
+ $this->relations[] = new PMA_RT_Relation($this->tables[$master_table], $master_field, $this->tables[$foreign_table], $foreign_field);
+ } // end of the "PMA_RT_addRelation()" method
+
+
+ /**
+ * Draws the grid
+ *
+ * @global object the current PMA_PDF instance
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
+ function PMA_RT_strokeGrid()
+ {
+ global $pdf;
+
+ $pdf->SetMargins(0, 0);
+ $pdf->SetDrawColor(200, 200, 200);
+
+ // Draws horizontal lines
+ for ($l = 0; $l < 21; $l++) {
+ $pdf->line(0, $l * 10, 297, $l * 10);
+ // Avoid duplicates
+ if ($l > 0) {
+ $pdf->SetXY(0, $l * 10);
+ $label = (string) $pdf->_FPDF_round(($l * 10 - $this->t_marg) * $this->scale + $this->y_min);
+ $pdf->Cell(5, 5, ' ' . $label);
+ } // end if
+ } // end for
+
+ // Draws vertical lines
+ for ($j = 0; $j < 30 ;$j++) {
+ $pdf->line($j * 10, 0, $j * 10, 210);
+ $pdf->SetXY($j * 10, 0);
+ $label = (string) $pdf->_FPDF_round(($j * 10 - $this->l_marg) * $this->scale + $this->x_min);
+ $pdf->Cell(5, 7, $label);
+ } // end for
+ } // end of the "PMA_RT_strokeGrid()" method
+
+
+ /**
+ * Draws relation arrows
+ *
+ * @param boolean Whether to use one color per relation or not
+ *
+ * @access private
+ *
+ * @see PMA_RT_Relation::PMA_RT_Relation_draw()
+ */
+ function PMA_RT_drawRelations($change_color)
+ {
+ $i = 0;
+ reset($this->relations);
+ while (list(, $relation) = each($this->relations)) {
+ $relation->PMA_RT_Relation_draw($change_color, $i);
+ $i++;
+ } // end while
+ } // end of the "PMA_RT_drawRelations()" method
+
+
+ /**
+ * Draws tables
+ *
+ * @param boolean Whether to display table position or not
+ *
+ * @access private
+ *
+ * @see PMA_RT_Table::PMA_RT_Table_draw()
+ */
+ function PMA_RT_drawTables($show_info)
+ {
+ reset($this->tables);
+ while (list(, $table) = each($this->tables)) {
+ $table->PMA_RT_Table_draw($show_info, $this->ff);
+ }
+ } // end of the "PMA_RT_drawTables()" method
+
+
+ /**
+ * Ouputs the PDF document to a file
+ *
+ * @global object The current PDF document
+ * @global string The current database name
+ * @global integer The current page number (from the
+ * $cfg['Servers'][$i]['table_coords'] table)
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
+ function PMA_RT_showRt()
+ {
+ global $pdf, $db, $pdf_page_number;
+
+ $pdf->SetDisplayMode('fullpage');
+ $pdf->Output($db . '_' . $pdf_page_number . '.pdf', TRUE);
+ } // end of the "PMA_RT_showRt()" method
+
+
+ /**
+ * The "PMA_RT" constructor
+ *
+ * @param mixed The scalling factor
+ * @param integer The page number to draw (from the
+ * $cfg['Servers'][$i]['table_coords'] table)
+ * @param boolean Whether to display table position or not
+ * @param boolean Whether to use one color per relation or not
+ * @param boolean Whether to draw grids or not
+ *
+ * @global object The current PDF document
+ *
+ * @access private
+ *
+ * @see PMA_PDF
+ */
function PMA_RT($scale, $which_rel, $show_info = 0, $change_color = 0 , $show_grid = 0)
{
global $pdf;
+ // Font face depends on the current language
+ $this->ff = str_replace('"', '', substr($GLOBALS['right_font_family'], 0, strpos($GLOBALS['right_font_family'], ',')));
+
+ // Initializes a new document
$pdf = new PMA_PDF('L');
$pdf->title = sprintf($GLOBALS['strPdfDbSchema'], $GLOBALS['db'], $which_rel);
$pdf->cMargin = 0;
@@ -206,273 +811,9 @@ class PMA_RT
$this->PMA_RT_showRt();
} // end of the "PMA_RT()" method
+} // end of the "PMA_RT" class
- function PMA_RT_addRelation($master_table , $master_field, $foreign_table, $foreign_field)
- {
- if (!isset($this->tables[$master_table])) {
- $this->tables[$master_table] = new PMA_RT_Table($master_table, $this->ff);
- $this->PMA_RT_setMinMax($this->tables[$master_table]);
- }
- if (!isset($this->tables[$foreign_table])) {
- $this->tables[$foreign_table] = new PMA_RT_Table($foreign_table, $this->ff);
- $this->PMA_RT_setMinMax($this->tables[$foreign_table]);
- }
- $this->relations[] = new PMA_RT_Relation($this->tables[$master_table], $master_field, $this->tables[$foreign_table], $foreign_field);
- }
-
- function PMA_RT_setMinMax($table)
- {
- $this->x_max = max($this->x_max, $table->x + $table->width);
- $this->y_max = max($this->y_max, $table->y + $table->height);
- $this->x_min = min($this->x_min, $table->x);
- $this->y_min = min($this->y_min, $table->y);
-
- }
-
- function PMA_RT_drawTables($show_info)
- {
- foreach ($this->tables as $table) {
- $table->PMA_RT_Table_draw($show_info, $this->ff);
- }
- }
-
- function PMA_RT_drawRelations($change_color)
- {
- $i = 0;
- foreach ($this->relations as $relation) {
- $relation->PMA_RT_Relation_draw($change_color, $i);
- $i++;
- }
- }
-
- /**
- * Draws the grid
- *
- * @global object the current PMA_PDF instance
- *
- * @access private
- *
- * @see PMA_RT()
- */
- function PMA_RT_strokeGrid()
- {
- global $pdf;
-
- $pdf->SetMargins(0, 0);
- $pdf->SetDrawColor(200, 200, 200);
-
- // Draws horizontal lines
- for ($l = 0; $l < 21; $l++) {
- $pdf->line(0, $l * 10, 297, $l * 10);
- // Avoid duplicates
- if ($l > 0) {
- $pdf->SetXY(0, $l * 10);
- $label = (string) round(($l * 10 - $this->t_marg) * $this->scale + $this->y_min);
- $pdf->Cell(5, 5, ' ' . $label);
- } // end if
- } // end for
-
- // Draws vertical lines
- for ($j = 0; $j < 30 ;$j++) {
- $pdf->line($j * 10, 0, $j * 10, 210);
- $pdf->SetXY($j * 10, 0);
- $label = (string) round(($j * 10 - $this->l_marg) * $this->scale + $this->x_min);
- $pdf->Cell(5, 7, $label);
- } // end for
- } // end of the "PMA_RT_strokeGrid()" method
-
- function PMA_RT_showRt()
- {
- global $pdf, $db, $pdf_page_number;
-
- $pdf->SetDisplayMode('fullpage');
- $pdf->Output($db . '_' . $pdf_page_number . '.pdf', TRUE);
- }
-} // end class "PMA_RT"
-
-class PMA_RT_Relation
-{
- var $x_src, $y_src;
- var $src_dir ;
- var $dest_dir;
- var $x_dest, $y_dest;
- var $w_tick = 5;
-
- function PMA_RT_Relation($master_table, $master_field, $foreign_table, $foreign_field)
- {
- $src_pos = $this->PMA_RT_Relation_getXy($master_table , $master_field);
- $dest_pos = $this->PMA_RT_Relation_getXy($foreign_table, $foreign_field);
- $src_left = $src_pos[0] - $this->w_tick;
- $src_right = $src_pos[1] + $this->w_tick;
- $dest_left = $dest_pos[0] - $this->w_tick;
- $dest_right = $dest_pos[1] + $this->w_tick;
-
- $d1 = abs($src_left - $dest_left);
- $d2 = abs($src_right - $dest_left);
- $d3 = abs($src_left - $dest_right);
- $d4 = abs($src_right - $dest_right);
- $d = min($d1, $d2, $d3, $d4);
-
- if ($d == $d1) {
- $this->x_src = $src_pos[0];
- $this->src_dir = -1;
- $this->x_dest = $dest_pos[0];
- $this->dest_dir = -1;
- } else if ($d == $d2) {
- $this->x_src = $src_pos[1];
- $this->src_dir = 1;
- $this->x_dest = $dest_pos[0];
- $this->dest_dir = -1;
- } else if ($d == $d3) {
- $this->x_src = $src_pos[0];
- $this->src_dir = -1;
- $this->x_dest = $dest_pos[1];
- $this->dest_dir = 1;
- } else {
- $this->x_src = $src_pos[1];
- $this->src_dir = 1;
- $this->x_dest = $dest_pos[1];
- $this->dest_dir = 1;
- }
- $this->y_src = $src_pos[2];
- $this->y_dest = $dest_pos[2];
- }
-
- function PMA_RT_Relation_getXy($table, $column)
- {
- $pos = array_search($column, $table->fields);
- //x_left, x_right ,y
- return array($table->x, $table->x + $table->width, $table->y + ($pos + 1.5) * $table->height_cell);
- }
-
- function PMA_RT_Relation_draw($change_color, $i)
- {
- global $pdf;
-
- if ($change_color){
- $d = $i % 6;
- $j = ($i - $d) / 6;
- $j = $j % 4;
- $j++;
- $case = array(
- array(1, 0, 0),
- array(0, 1, 0),
- array(0, 0, 1),
- array(1, 1, 0),
- array(1, 0, 1),
- array(0, 1, 1)
- );
- list ($a, $b, $c) = $case[$d];
- $e = (1 - ($j - 1) / 6);
- $pdf->SetDrawColor($a * 255 * $e, $b * 255 * $e, $c * 255 * $e); }
- else {
- $pdf->SetDrawColor(0);
- }
-
- $pdf->PMA_PDF_setLineWidthScale(0.2);
- $pdf->PMA_PDF_lineScale($this->x_src, $this->y_src, $this->x_src + $this->src_dir * $this->w_tick, $this->y_src);
- $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest, $this->x_dest, $this->y_dest);
- $pdf->PMA_PDF_setLineWidthScale(0.1);
- $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick, $this->y_src, $this->x_dest + $this->dest_dir * $this->w_tick, $this->y_dest);
-
- //arrow
- $root2 = 2 * sqrt(2);
- $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src + $this->w_tick / $root2);
- $pdf->PMA_PDF_lineScale($this->x_src + $this->src_dir * $this->w_tick * 0.75, $this->y_src, $this->x_src + $this->src_dir * (0.75 - 1 / $root2) * $this->w_tick, $this->y_src - $this->w_tick / $root2);
-
- $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest + $this->w_tick / $root2);
- $pdf->PMA_PDF_lineScale($this->x_dest + $this->dest_dir * $this->w_tick / 2, $this->y_dest, $this->x_dest + $this->dest_dir * (0.5 + 1 / $root2) * $this->w_tick, $this->y_dest - $this->w_tick / $root2);
- $pdf->SetDrawColor(0);
- }
-} // end class "PMA_RT_Relation"
-
-class PMA_RT_Table
-{
- var $nb_fiels;
- var $table_name;
- var $width = 0;
- var $height;
- var $fields = array();
- var $height_cell = 6;
- var $x, $y;
-
- function PMA_RT_Table($table_name, $ff)
- {
- global $pdf, $pdf_page_number;
-
- $this->table_name = $table_name;
- $sql = 'DESCRIBE ' . PMA_backquote($table_name);
- $result = mysql_query($sql);
- if (!$result || !mysql_num_rows($result)) {
- $pdf->PMA_PDF_die(sprintf($GLOBALS['strInvalidTblName'], $table_name));
- }
- // load fields
- while ($row = mysql_fetch_array($result)) {
- $this->fields[] = $row[0];
- }
-
- //height and width
- $this->PMA_RT_Table_setWidth($ff);
- $this->PMA_RT_Table_setHeight();
-
- //x and y
- $sql = 'SELECT x, y FROM '
- . PMA_backquote($GLOBALS['cfg']['Server']['table_coords'])
- . ' WHERE table_name = \'' . PMA_sqlAddslashes($table_name) . '\''
- . ' AND pdf_page_number = ' . $pdf_page_number;
- $result = mysql_query($sql);
- if (!$result || !mysql_num_rows($result)) {
- $pdf->PMA_PDF_die(sprintf($GLOBALS['strConfigureTableCoord'], $table_name));
- }
- list($this->x, $this->y) = mysql_fetch_array($result);
- }
-
- function PMA_RT_Table_setWidth($ff)
- {
- global $pdf;
-
- foreach ($this->fields as $field) {
- $this->width = max($this->width, $pdf->GetStringWidth($field));
- }
- $this->width += $pdf->GetStringWidth(' ');
- $pdf->SetFont($ff, 'B');
- $this->width = max($this->width, $pdf->GetStringWidth(' ' . $this->table_name));
- $pdf->SetFont($ff, '');
- }
-
- function PMA_RT_Table_setHeight()
- {
- $this->height = (sizeof($this->fields) + 1) * $this->height_cell;
- }
-
- function PMA_RT_Table_draw($show_info, $ff)
- {
- global $pdf;
-
- $pdf->PMA_PDF_setXyScale($this->x, $this->y);
- $pdf->SetFont($ff, 'B');
- $pdf->SetTextColor(200);
- $pdf->SetFillColor(0, 0, 128);
- if ($show_info){
- $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, round($this->width) . 'x' . round($this->height) . ' ' . $this->table_name , 1, 1, 'C', 1);
- } else {
- $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, $this->table_name, 1, 1, 'C', 1);
- }
- $pdf->PMA_PDF_setXScale($this->x);
- $pdf->SetFont($ff, '');
- $pdf->SetTextColor(0);
- $pdf->SetFillColor(255);
-
- foreach ($this->fields as $field) {
- $pdf->PMA_PDF_cellScale($this->width, $this->height_cell, ' ' . $field, 1, 1, 'L', 1);
- $pdf->PMA_PDF_setXScale($this->x);
- }
- if ($pdf->PageNo() > 1) {
- $pdf->PMA_PDF_die($GLOBALS['strScaleFactorSmall']);
- }
- }
-} // end class "PMA_RT_Table"
/**