Current File : /home/inlingua/public_html/dwarka/icentex/admin/backup/html2fpdf.php
<?php
/*
*** General-use version

DEBUG HINT:
- Inside function printbuffer make $fill=1
- Inside function Cell make:
if($fill==1 or $border==1)
{
//		if ($fill==1) $op=($border==1) ? 'B' : 'f';
//		else $op='S';
$op='S';
- Following these 2 steps you will be able to see the cell's boundaries

WARNING: When adding a new tag support, also add its name inside the function DisableTags()'s very long string

ODDITIES (?):
. It seems like saved['border'] and saved['bgcolor'] are useless inside the FlowingBlock...
These 2 attributes do the same thing?!?:
. $this->currentfont - mine
. $this->CurrentFont - fpdf's

TODO (in the future...):
- Make font-family, font-size, lineheight customizable
- Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported
- allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed)
- Improve CSS support
- support image side-by-side or one-below-another or both?
- Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example)

//////////////////////////////////////////////////////////////////////////////
//////////////DO NOT MODIFY THE CONTENTS OF THIS BOX//////////////////////////
//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// HTML2FPDF is a php script to read a HTML text and generate a PDF file.   //
// Copyright (C) 2004-2005 Renato Coelho                                    //
// This script may be distributed as long as the following files are kept   //
// together: 								                                                //
//	                          					                                    //
// fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

Misc. Observations:
- CSS + align = bug! (?)
OBS1: para textos de mais de 1 p�gina, talvez tenha que juntar varios $texto_artigo
antes de mandar gerar o PDF, para que o PDF gerado seja completo.
OBS2: there are 2 types of spaces 32 and 160 (ascii values)
OBS3: //! is a special comment to be used with source2doc.php, a script I created
in order to generate the doc on the site html2fpdf.sf.net
OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work
OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block)
OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 )
OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not)
Perl:  '/regexp/x'  where x == option ( x = i:ignore case , x = s: DOT gets \n as well)
========================END OF INITIAL COMMENTS=================================
*/

define('HTML2FPDF_VERSION','3.0(beta)');
if (!defined('RELATIVE_PATH')) define('RELATIVE_PATH','');
if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH','font/');
require_once(RELATIVE_PATH.'fpdf.php');
require_once(RELATIVE_PATH.'htmltoolkit.php');

class HTML2FPDF extends FPDF
{
//internal attributes
var $HREF; //! string
var $pgwidth; //! float
var $fontlist; //! array 
var $issetfont; //! bool
var $issetcolor; //! bool
var $titulo; //! string
var $oldx; //! float
var $oldy; //! float
var $B; //! int
var $U; //! int
var $I; //! int

var $tablestart; //! bool
var $tdbegin; //! bool
var $table; //! array
var $cell; //! array 
var $col; //! int
var $row; //! int

var $divbegin; //! bool
var $divalign; //! char
var $divwidth; //! float
var $divheight; //! float
var $divbgcolor; //! bool
var $divcolor; //! bool
var $divborder; //! int
var $divrevert; //! bool

var $listlvl; //! int
var $listnum; //! int
var $listtype; //! string
//array(lvl,# of occurrences)
var $listoccur; //! array
//array(lvl,occurrence,type,maxnum)
var $listlist; //! array
//array(lvl,num,content,type)
var $listitem; //! array

var $buffer_on; //! bool
var $pbegin; //! bool
var $pjustfinished; //! bool
var $blockjustfinished; //! bool
var $SUP; //! bool
var $SUB; //! bool
var $toupper; //! bool
var $tolower; //! bool
var $dash_on; //! bool
var $dotted_on; //! bool
var $strike; //! bool

var $CSS; //! array
var $cssbegin; //! bool
var $backupcss; //! array
var $textbuffer; //! array
var	$currentstyle; //! string
var $currentfont; //! string
var $colorarray; //! array
var $bgcolorarray; //! array
var $internallink; //! array
var $enabledtags; //! string

var $lineheight; //! int
var $basepath; //! string
// array('COLOR','WIDTH','OLDWIDTH')
var $outlineparam; //! array
var $outline_on; //! bool

var $specialcontent; //! string
var $selectoption; //! array

//options attributes
var $usecss; //! bool
var $usepre; //! bool
var $usetableheader; //! bool
var $shownoimg; //! bool

function HTML2FPDF($orientation='P',$unit='mm',$format='A4')
{
//! @desc Constructor
//! @return An object (a class instance)
	//Call parent constructor
	$this->FPDF($orientation,$unit,$format);
	//To make the function Footer() work properly
	$this->AliasNbPages();
	//Enable all tags as default
	$this->DisableTags();
  //Set default display preferences
  $this->DisplayPreferences('');
	//Initialization of the attributes
	$this->SetFont('Arial','',11); // Changeable?(not yet...)
  $this->lineheight = 5; // Related to FontSizePt == 11
  $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
  $this->SetFillColor(255);
	$this->HREF='';
	$this->titulo='';
	$this->oldx=-1;
	$this->oldy=-1;
	$this->B=0;
	$this->U=0;
	$this->I=0;

  $this->listlvl=0;
  $this->listnum=0; 
  $this->listtype='';
  $this->listoccur=array();
  $this->listlist=array();
  $this->listitem=array();

  $this->tablestart=false;
  $this->tdbegin=false; 
  $this->table=array(); 
  $this->cell=array();  
  $this->col=-1; 
  $this->row=-1; 

	$this->divbegin=false;
	$this->divalign="L";
	$this->divwidth=0; 
	$this->divheight=0; 
	$this->divbgcolor=false;
	$this->divcolor=false;
	$this->divborder=0;
	$this->divrevert=false;

	$this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans");
	$this->issetfont=false;
	$this->issetcolor=false;

  $this->pbegin=false;
  $this->pjustfinished=false;
  $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces
  $this->toupper=false;
  $this->tolower=false;
	$this->dash_on=false;
	$this->dotted_on=false;
  $this->SUP=false;
  $this->SUB=false;
  $this->buffer_on=false;
  $this->strike=false;

	$this->currentfont='';
	$this->currentstyle='';
  $this->colorarray=array();
  $this->bgcolorarray=array();
	$this->cssbegin=false;
  $this->textbuffer=array();
	$this->CSS=array();
	$this->backupcss=array();
	$this->internallink=array();

  $this->basepath = "";
  
  $this->outlineparam = array();
  $this->outline_on = false;

  $this->specialcontent = '';
  $this->selectoption = array();

  $this->shownoimg=false;
  $this->usetableheader=false;
  $this->usecss=true;
  $this->usepre=true;
}

function setBasePath($str)
{
//! @desc Inform the script where the html file is (full path - e.g. http://www.google.com/dir1/dir2/dir3/file.html ) in order to adjust HREF and SRC links. No-Parameter: The directory where this script is.
//! @return void
  $this->basepath = dirname($str) . "/";
  $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows
}

function ShowNOIMG_GIF($opt=true)
{
//! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable
//! @return void
  $this->shownoimg=$opt;
}

function UseCSS($opt=true)
{
//! @desc Enable/Disable CSS recognition. No-Parameter: Enable
//! @return void
  $this->usecss=$opt;
}

function UseTableHeader($opt=true)
{
//! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable
//! @return void
  $this->usetableheader=$opt;
}

function UsePRE($opt=true)
{
//! @desc Enable/Disable pre tag recognition. No-Parameter: Enable
//! @return void
  $this->usepre=$opt;
}

//Page header
function Header($content='')
{
//! @return void
//! @desc The header is printed in every page.
  if($this->usetableheader and $content != '')
  {
    $y = $this->y;
    foreach($content as $tableheader)
    {
      $this->y = $y;
      //Set some cell values
      $x = $tableheader['x'];
      $w = $tableheader['w'];
      $h = $tableheader['h'];
      $va = $tableheader['va'];
      $mih = $tableheader['mih'];
      $fill = $tableheader['bgcolor'];
      $border = $tableheader['border'];
      $align = $tableheader['a'];
      //Align
      $this->divalign=$align;
			$this->x = $x;
		  //Vertical align
		  if (!isset($va) || $va=='M') $this->y += ($h-$mih)/2;
      elseif (isset($va) && $va=='B') $this->y += $h-$mih;
			if ($fill)
      {
 					$color = ConvertColor($fill);
 					$this->SetFillColor($color['R'],$color['G'],$color['B']);
 					$this->Rect($x, $y, $w, $h, 'F');
			}
   		//Border
  		if (isset($border) and $border != 'all') $this->_tableRect($x, $y, $w, $h, $border);
  		elseif (isset($border) && $border == 'all') $this->Rect($x, $y, $w, $h);
  		//Print cell content
      $this->divwidth = $w-2;
      $this->divheight = 1.1*$this->lineheight;
      $textbuffer = $tableheader['textbuffer'];
      if (!empty($textbuffer)) $this->printbuffer($textbuffer,false,true/*inside a table*/);
      $textbuffer = array();
    }
    $this->y = $y + $h; //Update y coordinate
  }//end of 'if usetableheader ...'
}

//Page footer
function Footer()
{
//! @return void
//! @desc The footer is printed in every page!
    //Position at 1.0 cm from bottom
    $this->SetY(-10);
    //Copyright //especial para esta vers�o
    $this->SetFont('Arial','B',9);
  	$this->SetTextColor(0);
    //Arial italic 9
    $this->SetFont('Arial','I',9);
    //Page number
    $this->Cell(0,10,$this->PageNo().'/{nb}',0,0,'C');
    //Return Font to normal
    $this->SetFont('Arial','',11);
}

///////////////////
/// HTML parser ///
///////////////////
function WriteHTML($html)
{
//! @desc HTML parser
//! @return void
/* $e == content */

  $this->ReadMetaTags($html);
  $html = AdjustHTML($html,$this->usepre); //Try to make HTML look more like XHTML
  if ($this->usecss) $html = $this->ReadCSS($html);
	//Add new supported tags in the DisableTags function
	$html=str_replace('<?','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word
	$html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string
  //Explode the string in order to parse the HTML code
	$a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);

	foreach($a as $i => $e)
	{

		if($i%2==0)
		{
			//TEXT

			//Adjust lineheight
      //			$this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer?
			//Adjust text, if needed
			if (strpos($e,"&") !== false) //HTML-ENTITIES decoding
			{
        if (strpos($e,"#") !== false) $e = value_entity_decode($e); // Decode value entities
        //Avoid crashing the script on PHP 4.0
        $version = phpversion();
        $version = str_replace('.','',$version);
        if ($version >= 430) $e = html_entity_decode($e,ENT_QUOTES,'cp1252'); // changes &nbsp; and the like by their respective char
        else $e = lesser_entity_decode($e);
      }
      $e = str_replace(chr(160),chr(32),$e); //unify ascii code of spaces (in order to recognize all of them correctly)
      if (strlen($e) == 0) continue;
			if ($this->divrevert) $e = strrev($e);
			if ($this->toupper) $e = strtoupper($e);
			if ($this->tolower) $e = strtolower($e);
      //Start of 'if/elseif's
			if($this->titulo) $this->SetTitle($e);
  		elseif($this->specialcontent)
			{
			    if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true) //SELECT tag (form element)
          {
             $stringwidth = $this->GetStringWidth($e);
             if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH']) $this->selectoption['MAXWIDTH'] = $stringwidth;
             if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '') $this->selectoption['SELECTED'] = $e;
          }
          else $this->textbuffer[] = array("���"/*identifier*/.$this->specialcontent."���".$e);
      }
			elseif($this->tablestart)
			{
          if($this->tdbegin)
          {
	  				$this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
  					$this->cell[$this->row][$this->col]['text'][] = $e;
            $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e);
					}
					//Ignore content between <table>,<tr> and a <td> tag (this content is usually only a bunch of spaces)
			}
			elseif($this->pbegin or $this->HREF or $this->divbegin or $this->SUP or $this->SUB or $this->strike or $this->buffer_on) $this->textbuffer[] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray); //Accumulate text on buffer
			else
			{
     			if ($this->blockjustfinished) $e = ltrim($e);
     			if ($e != '')
     			{
               $this->Write($this->lineheight,$e); //Write text directly in the PDF
               if ($this->pjustfinished) $this->pjustfinished = false;
          }
      }
		}
		else
		{
			//Tag
			if($e{0}=='/') $this->CloseTag(strtoupper(substr($e,1)));
			else
			{
        $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
      	$e = preg_replace($regexp,"=\"\$1\"",$e);
				$regexp = '| (\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
      	$e = preg_replace($regexp," \$1=\"\$2\"",$e);
      	//Fix path values, if needed
      	if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) )
        {
            $regexp = '/ (href|src)="(.*?)"/i';
            preg_match($regexp,$e,$auxiliararray);
            $path = $auxiliararray[2];
            $path = str_replace("\\","/",$path); //If on Windows
            //Get link info and obtain its absolute path
            $regexp = '|^./|';
            $path = preg_replace($regexp,'',$path);
            if($path{0} != '#') //It is not an Internal Link
            { 
              if (strpos($path,"../") !== false ) //It is a Relative Link
              {
                  $backtrackamount = substr_count($path,"../");
                  $maxbacktrack = substr_count($this->basepath,"/") - 1;
                  $filepath = str_replace("../",'',$path);
                  $path = $this->basepath;
                  //If it is an invalid relative link, then make it go to directory root
                  if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
                  //Backtrack some directories
                  for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
                  $path = $path . "/" . $filepath; //Make it an absolute path
              }
              elseif( strpos($path,":/") === false) //It is a Local Link
              {
                $path = $this->basepath . $path; 
              }
              //Do nothing if it is an Absolute Link
            }
            $regexp = '/ (href|src)="(.*?)"/i';
          	$e = preg_replace($regexp,' \\1="'.$path.'"',$e);
        }//END of Fix path values
				//Extract attributes
				$contents=array();
        preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents);
        preg_match('/\\S+/',$e,$a2);
        $tag=strtoupper($a2[0]);
				$attr=array();
				if (!empty($contents))
				{
  				foreach($contents[0] as $v)
  				{
  				    if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
    					{
    						$attr[strtoupper($a3[1])]=$a3[2];
     					}
  				}
				}
				$this->OpenTag($tag,$attr);
			}
		}
	}//end of	foreach($a as $i=>$e)
	//Create Internal Links, if needed
  if (!empty($this->internallink) )
  {
    foreach($this->internallink as $k=>$v)
    {
      if (strpos($k,"#") !== false ) continue; //ignore
      $ypos = $v['Y'];
      $pagenum = $v['PAGE'];
      $sharp = "#";
      while (array_key_exists($sharp.$k,$this->internallink))
      {
         $internallink = $this->internallink[$sharp.$k];
         $this->SetLink($internallink,$ypos,$pagenum);
         $sharp .= "#";
      }
    }
  }
}

function OpenTag($tag,$attr)
{
//! @return void
// What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>

  $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J');

  $this->blockjustfinished=false;
	//Opening tag
	switch($tag){
	  case 'PAGE_BREAK': //custom-tag
	  case 'NEWPAGE': //custom-tag
			$this->blockjustfinished = true;
	    $this->AddPage();
	    break;
	  case 'OUTLINE': //custom-tag (CSS2 property - browsers don't support it yet - Jan2005)
  	  //Usage: (default: width=normal color=white)
  	  //<outline width="(thin|medium|thick)" color="(usualcolorformat)" >Text</outline>
  	  //Mix this tag with the <font color="(usualcolorformat)"> tag to get mixed colors on outlined text!
	    $this->buffer_on = true;
	    if (isset($attr['COLOR'])) $this->outlineparam['COLOR'] = ConvertColor($attr['COLOR']);
	    else $this->outlineparam['COLOR'] = array('R'=>255,'G'=>255,'B'=>255); //white
      $this->outlineparam['OLDWIDTH'] = $this->LineWidth;
	    if (isset($attr['WIDTH']))
	    {
	       switch(strtoupper($attr['WIDTH']))
	       {
	           case 'THIN': $this->outlineparam['WIDTH'] = 0.75*$this->LineWidth; break;
	           case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth; break;
	           case 'THICK': $this->outlineparam['WIDTH'] = 1.75*$this->LineWidth; break;
         }
      }
      else $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth
	    break;
	  case 'BDO':
  	  if (isset($attr['DIR']) and (strtoupper($attr['DIR']) == 'RTL' )) $this->divrevert = true;
	    break;
	  case 'S':
	  case 'STRIKE':
	  case 'DEL':
	    $this->strike=true;
	    break;
		case 'SUB':
		  $this->SUB=true;
		  break;
		case 'SUP':
		  $this->SUP=true;
      break;
    case 'CENTER':
      $this->buffer_on = true;
      if ($this->tdbegin)	$this->cell[$this->row][$this->col]['a'] = $align['center'];
      else 
      {
   			$this->divalign = $align['center'];
        if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
      }
      break;
    case 'ADDRESS': 
      $this->buffer_on = true;
  		$this->SetStyle('I',true);
      if (!$this->tdbegin and $this->x != $this->lMargin) $this->Ln($this->lineheight);
      break;
		case 'TABLE': // TABLE-BEGIN
    	if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
      $this->tablestart = true;
   		$this->table['nc'] = $this->table['nr'] = 0;
   		if (isset($attr['REPEAT_HEADER']) and $attr['REPEAT_HEADER'] == true) $this->UseTableHeader(true);
			if (isset($attr['WIDTH'])) $this->table['w']	= ConvertSize($attr['WIDTH'],$this->pgwidth);
			if (isset($attr['HEIGHT']))	$this->table['h']	= ConvertSize($attr['HEIGHT'],$this->pgwidth);
			if (isset($attr['ALIGN']))	$this->table['a']	= $align[strtolower($attr['ALIGN'])];
			if (isset($attr['BORDER']))	$this->table['border']	= $attr['BORDER'];
			if (isset($attr['BGCOLOR'])) $this->table['bgcolor'][-1]	= $attr['BGCOLOR'];
			break;
		case 'TR':
			$this->row++;
			$this->table['nr']++;
			$this->col = -1;
			if (isset($attr['BGCOLOR']))$this->table['bgcolor'][$this->row]	= $attr['BGCOLOR'];
  		break;
		case 'TH':
			$this->SetStyle('B',true);
     	if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center";
		case 'TD':
		  $this->tdbegin = true;
			$this->col++;
      while (isset($this->cell[$this->row][$this->col])) $this->col++;
			//Update number column
  		if ($this->table['nc'] < $this->col+1) $this->table['nc'] = $this->col+1;
			$this->cell[$this->row][$this->col] = array();
			$this->cell[$this->row][$this->col]['text'] = array();
			$this->cell[$this->row][$this->col]['s'] = 3;
			if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
			if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h']	= ConvertSize($attr['HEIGHT'],$this->pgwidth);
			if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])];
			if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])];
			if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
			if (isset($attr['BGCOLOR'])) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR'];
			$cs = $rs = 1;
			if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1)	$cs = $this->cell[$this->row][$this->col]['colspan']	= $attr['COLSPAN'];
			if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1)	$rs = $this->cell[$this->row][$this->col]['rowspan']	= $attr['ROWSPAN'];
			//Chiem dung vi tri de danh cho cell span (�mais hein?)
			for ($k=$this->row ; $k < $this->row+$rs ;$k++)
        for($l=$this->col; $l < $this->col+$cs ;$l++)
        {
  				if ($k-$this->row || $l-$this->col)	$this->cell[$k][$l] = 0;
  			}
			if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1;
  		break;
		case 'OL':
      if ( !isset($attr['TYPE']) or $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1'
      else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here
		case 'UL':
      if ( (!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL')
      {
         //Insert UL defaults
         if ($this->listlvl == 0) $this->listtype = 'disc';
         elseif ($this->listlvl == 1) $this->listtype = 'circle';
         else $this->listtype = 'square';
      }
      elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE'];
      $this->buffer_on = false;
      if ($this->listlvl == 0)
      {
        //First of all, skip a line
        if (!$this->pjustfinished)
        {
            if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
            $this->Ln($this->lineheight);
        }
        $this->oldx = $this->x;
        $this->listlvl++; // first depth level
        $this->listnum = 0; // reset
        $this->listoccur[$this->listlvl] = 1;
        $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
      }
      else
      {
        if (!empty($this->textbuffer))
        {
          $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
          $this->listnum++;
        }
  		  $this->textbuffer = array();
  		  $occur = $this->listoccur[$this->listlvl];
        $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
        $this->listlvl++;
        $this->listnum = 0; // reset

        if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
        else $this->listoccur[$this->listlvl]++;
  		  $occur = $this->listoccur[$this->listlvl];
        $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
      }
      break;
		case 'LI':
		  //Observation: </LI> is ignored
      if ($this->listlvl == 0) //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
      {
        //First of all, skip a line
        if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
        $this->oldx = $this->x;
        $this->listlvl++; // first depth level
        $this->listnum = 0; // reset
        $this->listoccur[$this->listlvl] = 1;
        $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
      }
      if ($this->listnum == 0)
      {
        $this->buffer_on = true; //activate list 'bufferization'
        $this->listnum++;
  		  $this->textbuffer = array();
      }
      else
      {
        $this->buffer_on = true; //activate list 'bufferization'
        if (!empty($this->textbuffer))
        {
          $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
          $this->listnum++;
        }
  		  $this->textbuffer = array();
      }
      break;
		case 'H1': // 2 * fontsize
		case 'H2': // 1.5 * fontsize
		case 'H3': // 1.17 * fontsize
		case 'H4': // 1 * fontsize
		case 'H5': // 0.83 * fontsize
		case 'H6': // 0.67 * fontsize
  		//Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html
		  if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
      $this->buffer_on = true;
			if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
			elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
			$this->SetStyle('B',true);
      switch($tag)
      {
          case 'H1': 
              $this->SetFontSize(2*$this->FontSizePt); 
              $this->lineheight *= 2;
              break;
          case 'H2': 
              $this->SetFontSize(1.5*$this->FontSizePt); 
              $this->lineheight *= 1.5;
              break;
          case 'H3':
              $this->SetFontSize(1.17*$this->FontSizePt);
              $this->lineheight *= 1.17;
              break;
          case 'H4':
              $this->SetFontSize($this->FontSizePt); 
              break;
          case 'H5': 
              $this->SetFontSize(0.83*$this->FontSizePt); 
              $this->lineheight *= 0.83;
              break;
          case 'H6': 
              $this->SetFontSize(0.67*$this->FontSizePt); 
              $this->lineheight *= 0.67;
              break;
      }
		  break;
		case 'HR': //Default values: width=100% align=center color=gray
		  //Skip a line, if needed
			if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
			$this->Ln(0.2*$this->lineheight);
		  $hrwidth = $this->pgwidth;
		  $hralign = 'C';
		  $hrcolor = array('R'=>200,'G'=>200,'B'=>200);
		  if($attr['WIDTH'] != '') $hrwidth = ConvertSize($attr['WIDTH'],$this->pgwidth);
		  if($attr['ALIGN'] != '') $hralign = $align[strtolower($attr['ALIGN'])];
		  if($attr['COLOR'] != '') $hrcolor = ConvertColor($attr['COLOR']);
      $this->SetDrawColor($hrcolor['R'],$hrcolor['G'],$hrcolor['B']);
      $x = $this->x;
      $y = $this->y;
      switch($hralign)
      {
          case 'L':
          case 'J':
              break;
          case 'C':
              $empty = $this->pgwidth - $hrwidth;
              $empty /= 2;
              $x += $empty;
              break;
          case 'R':
              $empty = $this->pgwidth - $hrwidth;
              $x += $empty;
              break;
      }
      $oldlinewidth = $this->LineWidth;
			$this->SetLineWidth(0.3);
			$this->Line($x,$y,$x+$hrwidth,$y);
			$this->SetLineWidth($oldlinewidth);
			$this->Ln(0.2*$this->lineheight);
		  $this->SetDrawColor(0);
      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
			break;
		case 'INS':
			$this->SetStyle('U',true);
		  break;
		case 'SMALL':
		  $newsize = $this->FontSizePt - 1;
		  $this->SetFontSize($newsize);
		  break;
		case 'BIG':
		  $newsize = $this->FontSizePt + 1;
		  $this->SetFontSize($newsize);
		case 'STRONG':
			$this->SetStyle('B',true);
			break;
		case 'CITE':
		case 'EM':
			$this->SetStyle('I',true);
			break;
		case 'TITLE':
			$this->titulo = true;
			break;
		case 'B':
		case 'I':
		case 'U':
			if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
      {
   			$this->cssbegin=true;
 				if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
				elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
				//Read Inline CSS
				if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
				//Look for name in the $this->CSS array
				$this->backupcss = $properties;
				if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
		  }
			$this->SetStyle($tag,true);
			break;
		case 'A':
      if (isset($attr['NAME']) and $attr['NAME'] != '') $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition)
			if (isset($attr['HREF'])) $this->HREF=$attr['HREF'];
			break;
		case 'DIV':
      //in case of malformed HTML code. Example:(...)</div><li>Content</li><div>DIV1</div>(...)
  	  if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
   	  {
	        $this->buffer_on = false;
          if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
	        $this->textbuffer = array();
	        $this->listlvl--;
	        $this->printlistbuffer();
	        $this->pjustfinished = true; //act as if a paragraph just ended
      }
			$this->divbegin=true;
      if ($this->x != $this->lMargin)	$this->Ln($this->lineheight);
			if( isset($attr['ALIGN']) and  $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower($attr['ALIGN'])];
			if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
      {
   			$this->cssbegin=true;
 				if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
				elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
				//Read Inline CSS
				if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
				//Look for name in the $this->CSS array
				if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
		  }
			break;
		case 'IMG':
		  if(!empty($this->textbuffer) and !$this->tablestart)
		  {
		    //Output previously buffered content and output image below
        //Set some default values
        $olddivwidth = $this->divwidth;
        $olddivheight = $this->divheight;
        if ( $this->divwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin;
        if ( $this->divheight == 0) $this->divheight = $this->lineheight;
        //Print content
    	  $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
        $this->textbuffer=array(); 
      	//Reset values
        $this->divwidth = $olddivwidth;
        $this->divheight = $olddivheight;
		    $this->textbuffer=array();
		    $this->Ln($this->lineheight);
      }
			if(isset($attr['SRC']))
      {
          $srcpath = $attr['SRC'];
  				if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0;
				  else $attr['WIDTH'] = ConvertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4;
				  if(!isset($attr['HEIGHT']))	$attr['HEIGHT'] = 0;
				  else $attr['HEIGHT'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4;
				  if ($this->tdbegin) 
				  {
  				  $bak_x = $this->x;
            $bak_y = $this->y;
            //Check whether image exists locally or on the URL
            $f_exists = @fopen($srcpath,"rb");
            if (!$f_exists) //Show 'image not found' icon instead
            {
                if(!$this->shownoimg) break;
                $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
                $srcpath .= 'no_img.gif';
            }
            $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
            $this->y = $bak_y;
            $this->x = $bak_x;
          }
				  elseif($this->pbegin or $this->divbegin)
				  {
            //In order to support <div align='center'><img ...></div>
            $ypos = 0;
  				  $bak_x = $this->x;
            $bak_y = $this->y;
            //Check whether image exists locally or on the URL
            $f_exists = @fopen($srcpath,"rb");
            if (!$f_exists) //Show 'image not found' icon instead
            {
                if(!$this->shownoimg) break;
                $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
                $srcpath .= 'no_img.gif';
            }
            $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
            $this->y = $bak_y;
            $this->x = $bak_x;
            $xpos = '';
            switch($this->divalign)
            {
                case "C":
                     $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
                     $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2;
                     $xpos = 'xpos='.$empty.',';
                     break;
                case "R":
                     $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
                     $empty = ($this->pgwidth - $sizesarray['WIDTH']);
                     $xpos = 'xpos='.$empty.',';
                     break;
                default: break;
            }
     				$numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ;
     				$ypos = $numberoflines * $this->lineheight;
     				$this->textbuffer[] = array("���"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
            while($numberoflines) {$this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);$numberoflines--;}
          }
          else
          {
            $imgborder = 0;
            if (isset($attr['BORDER'])) $imgborder = ConvertSize($attr['BORDER'],$this->pgwidth);
            //Check whether image exists locally or on the URL
            $f_exists = @fopen($srcpath,"rb");
            if (!$f_exists) //Show 'image not found' icon instead
            {
                $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
                $srcpath .= 'no_img.gif';
            }
            $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'',$this->HREF); //Output Image
  				  $ini_x = $sizesarray['X'];
            $ini_y = $sizesarray['Y'];
            if ($imgborder)
            {
                $oldlinewidth = $this->LineWidth;
			          $this->SetLineWidth($imgborder);
                $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']);
			          $this->SetLineWidth($oldlinewidth);
            }
          }
  				if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin;
  				if ($this->tablestart)
  				{
     				$this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."���".$sizesarray['OUTPUT']);
            $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin
            $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
            if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
            if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
  				}
			}
			break;
		case 'BLOCKQUOTE':
		case 'BR':
		  if($this->tablestart)
		  {
		    $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      	$this->cell[$this->row][$this->col]['text'][] = "\n";
        if (!isset($this->cell[$this->row][$this->col]['maxs'])) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s'] +2; //+2 == margin
        elseif($this->cell[$this->row][$this->col]['maxs'] < $this->cell[$this->row][$this->col]['s']) $this->cell[$this->row][$this->col]['maxs'] = $this->cell[$this->row][$this->col]['s']+2;//+2 == margin
        $this->cell[$this->row][$this->col]['s'] = 0;// reset
      }
			elseif($this->divbegin or $this->pbegin or $this->buffer_on)  $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
			else {$this->Ln($this->lineheight);$this->blockjustfinished = true;}
			break;
		case 'P':
      //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
  	  if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
   	  {
	        $this->buffer_on = false;
          if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
	        $this->textbuffer = array();
	        $this->listlvl--;
	        $this->printlistbuffer();
	        $this->pjustfinished = true; //act as if a paragraph just ended
      }
      if ($this->tablestart)
      {
          $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
          $this->cell[$this->row][$this->col]['text'][] = "\n";
          break;
      }
		  $this->pbegin=true;
			if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
			elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
		  //Save x,y coords in case we need to print borders...
		  $this->oldx = $this->x;
		  $this->oldy = $this->y;
			if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
			if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
      {
   			$this->cssbegin=true;
 				if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
				elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
				//Read Inline CSS
				if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
				//Look for name in the $this->CSS array
				$this->backupcss = $properties;
				if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
		  }
			break;
		case 'SPAN':
		  $this->buffer_on = true;
 		  //Save x,y coords in case we need to print borders...
 		  $this->oldx = $this->x;
 		  $this->oldy = $this->y;
			if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
      {
   			$this->cssbegin=true;
 				if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
				elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
				//Read Inline CSS
				if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
				//Look for name in the $this->CSS array
				$this->backupcss = $properties;
				if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!
		  }
      break;
		case 'PRE':
		  if($this->tablestart)
		  {
		    $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      	$this->cell[$this->row][$this->col]['text'][] = "\n";
      }
			elseif($this->divbegin or $this->pbegin or $this->buffer_on)  $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      else
      {
      	if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
			  elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
		    $this->buffer_on = true;
		    //Save x,y coords in case we need to print borders...
		    $this->oldx = $this->x;
		    $this->oldy = $this->y;
			  if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
			  if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
        {
       			$this->cssbegin=true;
            if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
				    elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
				    //Read Inline CSS
				    if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
				    //Look for name in the $this->CSS array
				    $this->backupcss = $properties;
				    if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!
  		  }
			}
    case 'TT':
    case 'KBD':
    case 'SAMP':
		case 'CODE':
			$this->SetFont('courier');
  		$this->currentfont='courier';
		  break;
		case 'TEXTAREA':
		  $this->buffer_on = true;
      $colsize = 20; //HTML default value 
      $rowsize = 2; //HTML default value
  		if (isset($attr['COLS'])) $colsize = $attr['COLS'];
  		if (isset($attr['ROWS'])) $rowsize = $attr['ROWS'];
  		if (!$this->tablestart)
  		{
		    if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
		    $this->col = $colsize;
		    $this->row = $rowsize;
		  }
		  else //it is inside a table
		  {
  		  $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table
        $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin
        if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5;
      }
		  break;
		case 'SELECT':
		  $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table
		  break;
		case 'OPTION':
      $this->selectoption['ACTIVE'] = true;
		  if (empty($this->selectoption))
      {
  		  $this->selectoption['MAXWIDTH'] = '';
        $this->selectoption['SELECTED'] = '';
      }
      if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = '';
		  break;
		case 'FORM':
		  if($this->tablestart)
		  {
		    $this->cell[$this->row][$this->col]['textbuffer'][] = array($e,$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      	$this->cell[$this->row][$this->col]['text'][] = "\n";
      }
		  elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed
		  break;
    case 'INPUT':
      if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)
      if (!$this->tablestart)
      {
        switch(strtoupper($attr['TYPE'])){
          case 'CHECKBOX': //Draw Checkbox
                $checked = false;
                if (isset($attr['CHECKED'])) $checked = true;
        			  $this->SetFillColor(235,235,235);
        			  $this->x += 3;
                $this->Rect($this->x,$this->y+1,3,3,'DF');
                if ($checked) 
                {
                  $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3);
                  $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1);
                }
        			  $this->SetFillColor(255);
        			  $this->x += 3.5;
                break;
          case 'RADIO': //Draw Radio button
                $checked = false;
                if (isset($attr['CHECKED'])) $checked = true;
                $this->x += 4;
                $this->Circle($this->x,$this->y+2.2,1,'D');
                $this->_out('0.000 g');
                if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF');
                $this->Write(5,$texto,$this->x);
                $this->x += 2;
                break;
          case 'BUTTON': // Draw a button
          case 'SUBMIT':
          case 'RESET':
                $texto='';
                if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
                $nihil = 2.5;
                $this->x += 2;
        			  $this->SetFillColor(190,190,190);
                $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping
        			  $this->x += $nihil;
                $this->Write(5,$texto,$this->x);
        			  $this->x += $nihil;
        			  $this->SetFillColor(255);
                break;
          case 'PASSWORD':
                if (isset($attr['VALUE']))
                {
                    $num_stars = strlen($attr['VALUE']);
                    $attr['VALUE'] = str_repeat('*',$num_stars);
                }
          case 'TEXT': //Draw TextField
          default: //default == TEXT
                $texto='';
                if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
                $tamanho = 20;
                if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
        			  $this->SetFillColor(235,235,235);
                $this->x += 2;
                $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping
                if ($texto != '')
                {
                  $this->x += 1;
                  $this->Write(5,$texto,$this->x);
                  $this->x -= $this->GetStringWidth($texto);
                }
        		    $this->SetFillColor(255);
        		    $this->x += 2*$tamanho;
                break;
        }
      }
      else //we are inside a table
      {
        $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
        $type = '';
        $text = '';
        $height = 0;
        $width = 0;
        switch(strtoupper($attr['TYPE'])){
          case 'CHECKBOX': //Draw Checkbox
                $checked = false;
                if (isset($attr['CHECKED'])) $checked = true;
                $text = $checked;
                $type = 'CHECKBOX';
                $width = 4;
   			        $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
                $this->cell[$this->row][$this->col]['s'] += $width;
                if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
                break;
          case 'RADIO': //Draw Radio button
                $checked = false;
                if (isset($attr['CHECKED'])) $checked = true;
                $text = $checked;
                $type = 'RADIO';
                $width = 3;
                $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
                $this->cell[$this->row][$this->col]['s'] += $width;
                if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
                break;
          case 'BUTTON': $type = 'BUTTON'; // Draw a button
          case 'SUBMIT': if ($type == '') $type = 'SUBMIT';
          case 'RESET': if ($type == '') $type = 'RESET';
                $texto='';
                if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " ";
                $text = $texto;
                $width = $this->GetStringWidth($texto)+3;
                $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
                $this->cell[$this->row][$this->col]['s'] += $width;
                if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
                break;
          case 'PASSWORD':
                if (isset($attr['VALUE']))
                {
                    $num_stars = strlen($attr['VALUE']);
                    $attr['VALUE'] = str_repeat('*',$num_stars);
                }
                $type = 'PASSWORD';
          case 'TEXT': //Draw TextField
          default: //default == TEXT
                $texto='';
                if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
                $tamanho = 20;
                if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
                $text = $texto;
                $width = 2*$tamanho;
                if ($type == '') $type = 'TEXT';
                $this->cell[$this->row][$this->col]['textbuffer'][] = array("���"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."���".$text);
                $this->cell[$this->row][$this->col]['s'] += $width;
                if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
                break;
        }
      }
      break;
		case 'FONT':
//Font size is ignored for now
			if (isset($attr['COLOR']) and $attr['COLOR']!='')
      {
				$cor = ConvertColor($attr['COLOR']);
				//If something goes wrong switch color to black
			  $cor['R'] = (isset($cor['R'])?$cor['R']:0);
        $cor['G'] = (isset($cor['G'])?$cor['G']:0);
        $cor['B'] = (isset($cor['B'])?$cor['B']:0);
			  $this->colorarray = $cor;
				$this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
				$this->issetcolor = true;
			}
			if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist))
      {
				$this->SetFont(strtolower($attr['FACE']));
				$this->issetfont=true;
			}
			//'If' disabled in this version due lack of testing (you may enable it if you want)
//			if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') {
//				$this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);
//				$this->issetfont=true;
//			}
			break;
	}//end of switch
  $this->pjustfinished=false;
}

function CloseTag($tag)
{
//! @return void
	//Closing tag
	if($tag=='OPTION') $this->selectoption['ACTIVE'] = false;
	if($tag=='BDO') $this->divrevert = false;
	if($tag=='INS') $tag='U';
	if($tag=='STRONG') $tag='B';
	if($tag=='EM' or $tag=='CITE') $tag='I';
  if($tag=='OUTLINE')
  {
	  if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
	  {
      //Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer
      //if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']);
      $this->SetTextOutline(false);
      $this->outlineparam=array();
      //Save x,y coords ???
      $x = $this->x;
      $y = $this->y;
      //Set some default values
      $this->divwidth = $this->pgwidth - $x + $this->lMargin;
      //Print content
  	  $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
      $this->textbuffer=array(); 
     	//Reset values
     	$this->Reset();
      $this->buffer_on=false;
    }
    $this->SetTextOutline(false);
    $this->outlineparam=array();
  }
	if($tag=='A')
	{
	  if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on)
	  {
       //Deactivate $this->HREF for its info is already stored inside $this->textbuffer
       $this->HREF='';
       //Save x,y coords ???
       $x = $this->x;
       $y = $this->y;
       //Set some default values
       $this->divwidth = $this->pgwidth - $x + $this->lMargin;
       //Print content
       $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
       $this->textbuffer=array();
       //Reset values
       $this->Reset();
    }
    $this->HREF=''; 
  }
	if($tag=='TH') $this->SetStyle('B',false);
	if($tag=='TH' or $tag=='TD') $this->tdbegin = false;
	if($tag=='SPAN')
	{
    if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
    {
      if($this->cssbegin)
      {
          //Check if we have borders to print
          if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
          {
   	          $texto=''; 
              foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
              $tempx = $this->x;
              if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor);
              if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight);
		          if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight);
              $this->x = $tempx;
              $this->x -= 1; //adjust alignment
          }
		      $this->cssbegin=false;
		      $this->backupcss=array();
      }
      //Save x,y coords ???
      $x = $this->x;
      $y = $this->y;
      //Set some default values
      $this->divwidth = $this->pgwidth - $x + $this->lMargin;
      //Print content
  	  $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
      $this->textbuffer=array(); 
    	//Reset values
    	$this->Reset();
    }
    $this->buffer_on=false;
  }
	if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode
	{
   $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
	 if(!$this->tablestart)
   {
    if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
    if ($tag=='P') 
    {
      $this->pbegin=false;
      $this->pjustfinished=true;
    }
    else $this->divbegin=false;
    $content='';
    foreach($this->textbuffer as $aux) $content .= $aux[0];
    $numlines = $this->WordWrap($content,$this->divwidth);
    if ($this->divheight == 0) $this->divheight = $numlines * 5;
    //Print content
	  $this->printbuffer($this->textbuffer);
    $this->textbuffer=array();
  	if ($tag=='P') $this->Ln($this->lineheight);
   }//end of 'if (!this->tablestart)'
   //Reset values
 	 $this->Reset();
	 $this->cssbegin=false;
	 $this->backupcss=array();
  }
	if($tag=='TABLE') { // TABLE-END 
    $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
		$this->table['cells'] = $this->cell;
		$this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0));
		$this->table['hr'] = array_pad(array(),$this->table['nr'],0);
		$this->_tableColumnWidth($this->table);
		$this->_tableWidth($this->table);
		$this->_tableHeight($this->table);

    //Output table on PDF
		$this->_tableWrite($this->table);
		
    //Reset values
    $this->tablestart=false; //bool
    $this->table=array(); //array
    $this->cell=array(); //array 
    $this->col=-1; //int
    $this->row=-1; //int
    $this->Reset();
		$this->Ln(0.5*$this->lineheight);
	}
	if(($tag=='UL') or ($tag=='OL')) {
   if ($this->buffer_on == false) $this->listnum--;//Adjust minor BUG (this happens when there are two </OL> together)
	  if ($this->listlvl == 1) // We are closing the last OL/UL tag
	  {
       $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
	     $this->buffer_on = false;
       if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
	     $this->textbuffer = array();
	     $this->listlvl--;
	     $this->printlistbuffer();
    }
    else // returning one level
    {
       if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
	     $this->textbuffer = array();
	     $occur = $this->listoccur[$this->listlvl]; 
       $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
	     $this->listlvl--;
	     $occur = $this->listoccur[$this->listlvl];
	     $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
	     $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
       $this->buffer_on = false;
    }
  }
 	if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6')
 	  {
      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
      if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
      {
        //These 2 codelines are useless?
   	    $texto=''; 
        foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
        //Save x,y coords ???
        $x = $this->x;
        $y = $this->y;
        //Set some default values
        $this->divwidth = $this->pgwidth;
        //Print content
    	  $this->printbuffer($this->textbuffer);
        $this->textbuffer=array(); 
  			if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
      	//Reset values
      	$this->Reset();
      }
    $this->buffer_on=false;
    $this->lineheight = 5;
 		$this->Ln($this->lineheight);
    $this->SetFontSize(11);
 		$this->SetStyle('B',false);
  }
	if($tag=='TITLE')	{$this->titulo=false; $this->blockjustfinished = true;}
	if($tag=='FORM') $this->Ln($this->lineheight);
	if($tag=='PRE')
  {
      if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
      {
        if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
        $content='';
        foreach($this->textbuffer as $aux) $content .= $aux[0];
        $numlines = $this->WordWrap($content,$this->divwidth);
        if ($this->divheight == 0) $this->divheight = $numlines * 5;
        //Print content
        $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space
        $this->printbuffer($this->textbuffer);
        $this->textbuffer=array();
  			if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
      	//Reset values
      	$this->Reset();
        $this->Ln(1.1*$this->lineheight);
      }
		  if($this->tablestart)
		  {
		    $this->cell[$this->row][$this->col]['textbuffer'][] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      	$this->cell[$this->row][$this->col]['text'][] = "\n";
      }
			if($this->divbegin or $this->pbegin or $this->buffer_on)  $this->textbuffer[] = array("\n",$this->HREF,$this->currentstyle,$this->colorarray,$this->currentfont,$this->SUP,$this->SUB,''/*internal link*/,$this->strike,$this->outlineparam,$this->bgcolorarray);
      $this->cssbegin=false;
	    $this->backupcss=array();
      $this->buffer_on = false;
      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
      $this->pjustfinished = true; //behaves the same way
  }
	if($tag=='CODE' or $tag=='PRE' or $tag=='TT' or $tag=='KBD' or $tag=='SAMP')
  {
  	 $this->currentfont='';
     $this->SetFont('arial');
	}
	if($tag=='B' or $tag=='I' or $tag=='U')	
	{
	  $this->SetStyle($tag,false);
	  if ($this->cssbegin and !$this->divbegin and !$this->pbegin and !$this->buffer_on)
	  {
      //Reset values
    	$this->Reset();
		  $this->cssbegin=false;
  		$this->backupcss=array();
		}
	}
	if($tag=='TEXTAREA')
	{
	  if (!$this->tablestart) //not inside a table
	  {
  	  //Draw arrows too?
  	  $texto = '';
  	  foreach($this->textbuffer as $v) $texto .= $v[0];
    	$this->SetFillColor(235,235,235);
 			$this->SetFont('courier');
      $this->x +=3;
      $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3);
      if ( $linesneeded > $this->row ) //Too many words inside textarea
      {
          $textoaux = explode("\n",$texto);
          $texto = '';
          for($i=0;$i < $this->row;$i++)
          {
               if ($i == $this->row-1) $texto .= $textoaux[$i];
               else $texto .= $textoaux[$i] . "\n";
          }
          //Inform the user that some text has been truncated
          $texto{strlen($texto)-1} = ".";
          $texto{strlen($texto)-2} = ".";
          $texto{strlen($texto)-3} = ".";
      }
      $backup_y = $this->y;
      $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF');
      if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto);
      $this->y = $backup_y + $this->row*$this->lineheight;
 			$this->SetFont('arial');
    }
    else //inside a table
    {
 				$this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
				$this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
        $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
       	$this->specialcontent = '';
    }
  	$this->SetFillColor(255);
    $this->textbuffer=array(); 
    $this->buffer_on = false;
  }
	if($tag=='SELECT')
	{
	  $texto = '';
	  $tamanho = 0;
    if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH'];
    if ($this->tablestart)
    {
        $texto = "���".$this->specialcontent."���".$this->selectoption['SELECTED'];
        $aux = explode("���",$texto);
        $texto = $aux[2];
        $texto = "���".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."���".$texto;
        $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box
        $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later

        if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
 				$this->cell[$this->row][$this->col]['textbuffer'][] = array($texto);
				$this->cell[$this->row][$this->col]['text'][] = '';

    }
    else //not inside a table
    {
      $texto = $this->selectoption['SELECTED']