Location: PHPKode > scripts > Portable Programming Document > portable-programming-document/php_pdf.class.php
<?php

/*
   Created by Jon Lawrence.
   (c) 2005 AAB Software under the GPL.
   v. 1.0.0

   Description:
   The purpose of this class is to take a PHP string or PHP file and create a color-coded PDF document
   for portability and printability of PHP source code.

   Name:
   This class will assume the title of "PPD" for "Portable Programming Document" and each PDF that
   is generated by this class will have that as the "generator"
*/

define("PHP_PDF_ver", "PHP->PDF Converter v1.0.1");
define("PDFresolution", 72);
define("DEBUG", false);

class PHP_PDF
{
	/* Set up the class variables to be used */

	/* PRIVATE */
	var $handle;		// PDF handle to be used.
	var $plain;		// Plain version of PHP source
	var $fonts;		// Font array for normal/bold/italic/boldItalic
	var $color;		//current color to work with.
	var $font;		//current font to work with.
	var $page;		//current page
	var $curX;
	var $curY;
	var $line;
	var $lineNum;
	var $inLine;
	var $pVersion;	//the php version array of regular expressions. enum(4, 5);
	var $pUsed;		//sets 4 or 5 for the version.

	/* PUBLIC */
	var $margin;	// border size of page in inches
	var $width;		//width of the page in inches
	var $height;		//heigh of the page in inches
	var $fontSpace;	// font spacing (in pixels)
	var $fontSize;	//font size of document
	var $centerHead;	//the header to be on each page centered.

	function PHP_PDF($title="PPD [Portable Programming Document]", $author="PHP->PDF Converter")
	{
		/* Start out the with the basic creation and prepare for inputed file/string */

		//set the regular expressions depending on php version
		$this->pVersion = array(4 => "|<font color=\"#([^\"]{6})\">([[:print:]\n]*)</font>|U", 5 => "|<span style=\"color: #([^\"]{6})\">([[:print:]\n]*)</span>|U");
		$this->pUsed = 4;

		/* SET UP DEFAULTS FOR PUBLIC VARS	 */
		$this->margin = .5;
		$this->width = 8.5;
		$this->height = 11;
		$this->fontSpace = 5;
		$this->fontSize = 8;
		$this->color = "000000";
		$this->line = 1;
		$this->centerHead = false;
		
		$this->handle = PDF_new();
		pdf_open_file($this->handle);

		pdf_set_info($this->handle, "Title", $title);
		pdf_set_info($this->handle, "Creator", PHP_PDF_ver);
		pdf_set_info($this->handle, "Author", $author);
		pdf_set_info($this->handle, "Subject", "text/phps");

		/* Default font is Times-Roman */
		$normal = pdf_findfont($this->handle, "Courier", "host", 0);
		$bold = pdf_findfont($this->handle, "Times-Bold", "host", 0);
		$italic = pdf_findfont($this->handle, "Times-Italic", "host", 0);
		$BoldItalic = pdf_findfont($this->handle, "Times-BoldItalic", "host", 0);
		$this->fonts = array("normal" => $normal, "bold" => $bold, "italic" => $italic, "bolditalic" => $BoldItalic);

		$this->page = -1;
	}

	function loadText($text, $linenum=true)
	{
		$this->plain = $text;
		$this->_create($linenum);
	}

	function loadFile($fname=__FILE__, $linenum=true)
	{
		$this->plain = file_get_contents($fname);
		if(DEBUG)
			echo $fname."\n";
		$this->_create($linenum);
	}

	function getPDF()
	{
		//get the PDF data
		return pdf_get_buffer($this->handle);
	}

	/* used to set the current php version */
	function setPHP($ver=4)
	{
		$this->pUsed = ($ver==5) ? 5 : 4;
	}

	function _create($linenum = false)
	{
		/* Create the PDF from $this->plain */
		$this->lineNum = $linenum;
		$t_array = explode("\n", highlight_string($this->plain, true));
		$colored = $t_array[1];		//pull the needed string from the array.
		$this->inLine = false;

		/* function variables */
		list($curX, $curY) = $this->_newPage();
		$this->_setColor("000000");
		$font = $this->fonts['normal'];
		$beginLine = $this->margin*PDFresolution;
		$stepLine = $this->fontSize + $this->fontSpace;

		$colored = str_replace("<br />", "\n ", $colored);

		//Match all the <font color="#023456">Stuff</font>
		$numMatch = preg_match_all($this->pVersion[$this->pUsed], $colored, $matches);
		if($numMatch==0) return false;

		// Start loop for the fonts
		for($i=0; $i < $numMatch; $i++)
		{
			$this->_setColor($matches[1][$i]);
			$match = str_replace("<br />", "\n ", $matches[2][$i]);
			$t_array = explode("\n", $match);
			//echo "### ". count($t_array) . " ###\n";
			if(count($t_array)>1)
			{
				for($j=0;$j<count($t_array)-1;$j++)
				{
					$cLine = $t_array[$j];
					$cLine = str_replace("\t", "    ", $cLine);
					$cLine = html_entity_decode($cLine);
					$this->_writeText($cLine);
					if($linenum===true && $this->inLine===false) $this->_writeNum();
					$this->inLine = false;
					$this->_newLine();
					$this->line++;
				}
				$cLine = $t_array[count($t_array)-1];
				//$cLine = str_replace("\t", "    ", $cLine);
				$cLine = html_entity_decode($cLine);
				$this->_writeText($cLine);
			}
			else
			{
				$cLine = $t_array[0];
				$cLine = html_entity_decode($cLine);
				$this->_writeText($cLine);
			}
		}

		//pdf_end_page($this->handle);
		if($linenum===true) $this->_writeNum();
		$this->_endPage();
		pdf_close($this->handle);
	} //END function _create()

	/* Function to set the text color */
	function _setColor($hex)
	{
		list($red, $green, $blue) = sscanf($hex, "%02x%02x%02x");
		//echo "$hex::$red:$green:$blue<br />";
		pdf_setcolor($this->handle, "both", "rgb", $red/255, $green/255, $blue/255);
		//pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
		//Make sure the text is filled with the current "fill" color
		pdf_set_value($this->handle, "textrendering", 0);
		$this->color = $hex;
	}

	function _writeNum()
	{
		$curY = pdf_get_value($this->handle, "texty", 0);
		pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
		pdf_set_value($this->handle, "textrendering", 0);
		pdf_show_xy($this->handle, sprintf("%03d", $this->line), 10, $curY);
		$this->_setColor($this->color);
	}

	/* function to enter header info */
	function setHeader($text)
	{
		$this->centerHead = $text;
	}

	/* function to begin a new page */
	function _newPage()
	{
		if($this->page > -1)
		{
			//Write a "PDF Created by" at the bottom of each page.
			//pdf_end_page($this->handle);
			$this->_endPage();
		}
		pdf_begin_page($this->handle, $this->width*PDFresolution, $this->height*PDFresolution);
		//return the starting (x,y) of page
		list($curX, $curY) = array($this->margin * PDFresolution, ($this->height-$this->margin)*PDFresolution-($this->fontSize+$this->fontSpace));
		$val = pdf_set_text_pos($this->handle, $curX, $curY);
		$curX = pdf_get_value($this->handle, "textx", 0);
		$curY = pdf_get_value($this->handle, "texty", 0);
		//echo "::_newPage() (x,y) = ($curX, $curY)<br />";
		$this->page++;
		pdf_setfont($this->handle, $this->fonts['normal'], $this->fontSize);
		$this->_setColor($this->color);
		return array($curX, $curY);

	}

	function _endPage()
	{
		/* Print Footer */
		/* NOTE -- you may change this footer only if you credit the author somewhere else in
		   a visible fashion! */
		$copy = "PDF Generated by PPD programmed by Jon Lawrence";
		$width = pdf_stringwidth($this->handle, $copy);
		$startPlace = (($this->width*PDFresolution)-$width)/2;
		pdf_setcolor($this->handle, "both", "rgb", 0,0,0);
		pdf_set_value($this->handle, "textrendering", 0);
		pdf_show_xy($this->handle, $copy, $startPlace, 10);
		/* Print header */
		if($this->centerHead)
		{
			$width = pdf_stringwidth($this->handle, $this->centerHead);
			$startPlace = (($this->width*PDFresolution)-$width)/2;
			pdf_show_xy($this->handle, $this->centerHead, $startPlace, ($this->height*PDFresolution-$this->fontSize-10));
		}
		pdf_end_page($this->handle);

	}

	function _newLine()
	{
		//puts a new line in the PDF
		$beginLine = $this->margin*PDFresolution;
		$stepLine = $this->fontSize + $this->fontSpace;

		$curX = pdf_get_value($this->handle, "textx", 0);
		$curY = pdf_get_value($this->handle, "texty", 0);

		if(($curY-$stepLine) <= ($this->margin*PDFresolution))
		{
			$this->_newPage();
			return true;
		}

		$val=pdf_set_text_pos($this->handle, $beginLine, $curY-$stepLine);
		if(DEBUG)
			echo "\n";
		return true;
	}


	function _writeText($text)
	{
		$beginLine = $this->margin*PDFresolution;
		$stepLine = $this->fontSize + $this->fontSpace;

		$curX = pdf_get_value($this->handle, "textx", 0);
		$curY = pdf_get_value($this->handle, "texty", 0);
		//echo "$curX :: $curY<br />";
		//see if the entire line will fit
		$stringWidth = pdf_stringwidth($this->handle, $text);
		if(($stringWidth+$curX) <= (($this->width-$this->margin)*PDFresolution))
		{
			pdf_show($this->handle, $text);
			pdf_set_text_pos($this->handle, $curX+$stringWidth, $curY);
			if(DEBUG)
				echo $text;
		}
		else
		{
			//doesn't all fit....
			$insideFill = ($this->width-($this->margin*2))*PDFresolution;
			$numberLines = ceil($stringWidth/$insideFill);
			//check to see if a new page should be created first
			if(($numberLines*$stepLine) > ($curY - $this->margin*PDFresolution))
				$this->_newPage();
			$words = explode(" ", $text);
			foreach($words as $word)
			{
				$curX = pdf_get_value($this->handle, "textx", 0);
				$curY = pdf_get_value($this->handle, "texty", 0);
				$wordWidth = pdf_stringwidth($this->handle, $word);
				if(($wordWidth+$curX) > (($this->width-$this->margin)*PDFresolution))
				{
					if(($this->lineNum===true) && $this->inLine===false)
					{
						$this->_writeNum();
						$this->inLine = true;
					}
					$this->_newLine();
				}
				pdf_show($this->handle, $word." ");
			}

		}

	} //END _writeText()
} //END PHP_PDF class

?>
Return current item: Portable Programming Document