<?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 = 'Legal')
  {
    //! @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', '', 9);
    //Page number
    $this->Cell(75, 1, $this->PageNo() . '/{nb}', 0, 0, 'L');


    // $this->Image('C:\xampp\htdocs\tender\images\RailTech-GroupLogo.jpg',200,200);
    $this->Cell(5, 5, '');
    $this->SetFont('Arial', 'B', 9);
    $this->Cell(25, 5, ' ');
    $this->SetFont('Arial', '', 9);
    $this->Cell(38, 5, '');
    $this->Cell(-25, 12, '', 0, 1, 'R');
    $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('<?php ', '< ', $html); //Fix '<?php 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 = (int)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); //manoj this is able to set font size for atleast h5
      $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'];
        $this->SetFillColor(235, 235, 235);
        $this->x += 2;
        $this->Rect($this->x, $this->y, $tamanho + 2, 5, 'DF'); //+2 margin
        $this->x += 1;
        if ($texto != '') $this->Write(5, $texto, $this->x);
        $this->x += $tamanho - $this->GetStringWidth($texto) + 2;
        $this->SetFillColor(190, 190, 190);
        $this->Rect($this->x - 1, $this->y, 5, 5, 'DF'); //Arrow Box
        $this->SetFont('zapfdingbats');
        $this->Write(5, chr(116), $this->x); //Down arrow
        $this->SetFont('arial');
        $this->SetFillColor(255);
        $this->x += 1;
      }
      $this->selectoption = array();
      $this->specialcontent = '';
      $this->textbuffer = array();
    }
    if ($tag == 'SUB' or $tag == 'SUP')  //subscript or superscript
    {
      if (!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on and !$this->strike) {
        //Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer
        $this->SUB = false;
        $this->SUP = false;
        //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->SUB = false;
      $this->SUP = false;
    }
    if ($tag == 'S' or $tag == 'STRIKE' or $tag == 'DEL') {
      if (!$this->pbegin and !$this->divbegin and !$this->tablestart) {
        //Deactivate $this->strike for its info is already stored inside $this->textbuffer
        $this->strike = false;
        //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->strike = false;
    }
    if ($tag == 'ADDRESS' or $tag == 'CENTER') // <ADDRESS> or <CENTER> tag
    {
      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
      if (!$this->pbegin and !$this->divbegin and !$this->tablestart) {
        //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);
        $this->textbuffer = array();
        //Reset values
        $this->Reset();
      }
      $this->buffer_on = false;
      if ($tag == 'ADDRESS') $this->SetStyle('I', false);
    }
    if ($tag == 'BIG') {
      $newsize = $this->FontSizePt - 1;
      $this->SetFontSize($newsize);
      $this->SetStyle('B', false);
    }
    if ($tag == 'SMALL') {
      $newsize = $this->FontSizePt + 1;
      $this->SetFontSize($newsize);
    }
    if ($tag == 'FONT') {
      if ($this->issetcolor == true) {
        $this->colorarray = array();
        $this->SetTextColor(0);
        $this->issetcolor = false;
      }
      if ($this->issetfont) {
        $this->SetFont('arial');
        $this->issetfont = false;
      }
      if ($this->cssbegin) {
        //Get some attributes back!
        $this->setCSS($this->backupcss);
      }
    }
  }

  function printlistbuffer()
  {
    //! @return void
    //! @desc Prints all list-related buffered info

    //Save x coordinate
    $x = $this->oldx;
    foreach ($this->listitem as $item) {
      //Set default width & height values
      $this->divwidth = $this->pgwidth;
      $this->divheight = $this->lineheight;
      //Get list's buffered data
      $lvl = $item[0];
      $num = $item[1];
      $this->textbuffer = $item[2];
      $occur = $item[3];
      $type = $this->listlist[$lvl][$occur]['TYPE'];
      $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
      switch ($type) //Format type
      {
        case 'A':
          $num = dec2alpha($num, true);
          $maxnum = dec2alpha($maxnum, true);
          $type = str_pad($num, strlen($maxnum), ' ', STR_PAD_LEFT) . ".";
          break;
        case 'a':
          $num = dec2alpha($num, false);
          $maxnum = dec2alpha($maxnum, false);
          $type = str_pad($num, strlen($maxnum), ' ', STR_PAD_LEFT) . ".";
          break;
        case 'I':
          $num = dec2roman($num, true);
          $maxnum = dec2roman($maxnum, true);
          $type = str_pad($num, strlen($maxnum), ' ', STR_PAD_LEFT) . ".";
          break;
        case 'i':
          $num = dec2roman($num, false);
          $maxnum = dec2roman($maxnum, false);
          $type = str_pad($num, strlen($maxnum), ' ', STR_PAD_LEFT) . ".";
          break;
        case '1':
          $type = str_pad($num, strlen($maxnum), ' ', STR_PAD_LEFT) . ".";
          break;
        case 'disc':
          $type = chr(149);
          break;
        case 'square':
          $type = chr(110); //black square on Zapfdingbats font
          break;
        case 'circle':
          $type = chr(186);
          break;
        default:
          break;
      }
      $this->x = (5 * $lvl) + $x; //Indent list
      //Get bullet width including margins
      $oldsize = $this->FontSize * $this->k;
      if ($type == chr(110)) $this->SetFont('zapfdingbats', '', 5);
      $type .= ' ';
      $blt_width = $this->GetStringWidth($type) + $this->cMargin * 2;
      //Output bullet
      $this->Cell($blt_width, 5, $type, '', '', 'L');
      $this->SetFont('arial', '', $oldsize);
      $this->divwidth = $this->divwidth + $this->lMargin - $this->x;
      //Print content
      $this->printbuffer($this->textbuffer);
      $this->textbuffer = array();
    }
    //Reset all used values
    $this->listoccur = array();
    $this->listitem = array();
    $this->listlist = array();
    $this->listlvl = 0;
    $this->listnum = 0;
    $this->listtype = '';
    $this->textbuffer = array();
    $this->divwidth = 0;
    $this->divheight = 0;
    $this->oldx = -1;
    //At last, but not least, skip a line
    $this->Ln($this->lineheight);
  }

  function printbuffer($arrayaux, $outofblock = false, $is_table = false)
  {
    //! @return headache
    //! @desc Prepares buffered text to be printed with FlowingBlock()

    //Save some previous parameters
    $save = array();
    $save['strike'] = $this->strike;
    $save['SUP'] = $this->SUP;
    $save['SUB'] = $this->SUB;
    $save['DOTTED'] = $this->dotted_on;
    $save['DASHED'] = $this->dash_on;
    $this->SetDash(); //restore to no dash
    $this->dash_on = false;
    $this->dotted_on = false;

    $bak_y = $this->y;
    $bak_x = $this->x;
    $align = $this->divalign;
    $oldpage = $this->page;

    //Overall object size == $old_height
    //Line height == $this->divheight
    $old_height = $this->divheight;
    if ($is_table) {
      $this->divheight = 1.1 * $this->lineheight;
      $fill = 0;
    } else {
      $this->divheight = $this->lineheight;
      if ($this->FillColor == '1.000 g') $fill = 0; //avoid useless background painting (1.000 g == white background color)
      else $fill = 1;
    }

    $this->newFlowingBlock($this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table);

    $array_size = count($arrayaux);
    for ($i = 0; $i < $array_size; $i++) {
      $vetor = $arrayaux[$i];
      if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]);
      if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link
      //Activating buffer properties
      if (isset($vetor[10]) and !empty($vetor[10])) //Background color
      {
        $cor = $vetor[10];
        $this->SetFillColor($cor['R'], $cor['G'], $cor['B']);
        $this->divbgcolor = true;
      }
      if (isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
      {
        $cor = $vetor[9]['COLOR'];
        $outlinewidth = $vetor[9]['WIDTH'];
        $this->SetTextOutline($outlinewidth, $cor['R'], $cor['G'], $cor['B']);
        $this->outline_on = true;
      }
      if (isset($vetor[8]) and $vetor[8] === true) // strike-through the text
      {
        $this->strike = true;
      }
      if (isset($vetor[7]) and $vetor[7] != '') // internal link: <a name="anyvalue">
      {
        $this->internallink[$vetor[7]] = array("Y" => $this->y, "PAGE" => $this->page);
        $this->Bookmark($vetor[7] . " (pg. $this->page)", 0, $this->y);
        if (empty($vetor[0])) continue; //Ignore empty text
      }
      if (isset($vetor[6]) and $vetor[6] === true) // Subscript 
      {
        $this->SUB = true;
        $this->SetFontSize(6);
      }
      if (isset($vetor[5]) and $vetor[5] === true) // Superscript
      {
        $this->SUP = true;
        $this->SetFontSize(6);
      }
      if (isset($vetor[4]) and $vetor[4] != '') $this->SetFont($vetor[4]); // Font Family
      if (!empty($vetor[3])) //Font Color
      {
        $cor = $vetor[3];
        $this->SetTextColor($cor['R'], $cor['G'], $cor['B']);
      }
      if (isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
      {
        if (strpos($vetor[2], "B") !== false) $this->SetStyle('B', true);
        if (strpos($vetor[2], "I") !== false) $this->SetStyle('I', true);
        if (strpos($vetor[2], "U") !== false) $this->SetStyle('U', true);
      }
      if (isset($vetor[1]) and $vetor[1] != '') //LINK
      {
        if (strpos($vetor[1], ".") === false) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.) 
        {
          //Repeated reference to same anchor?
          while (array_key_exists($vetor[1], $this->internallink)) $vetor[1] = "#" . $vetor[1];
          $this->internallink[$vetor[1]] = $this->AddLink();
          $vetor[1] = $this->internallink[$vetor[1]];
        }
        $this->HREF = $vetor[1];
        $this->SetTextColor(0, 0, 255);
        $this->SetStyle('U', true);
      }
      //Print-out special content
      if (isset($vetor[0]) and $vetor[0]{
      0} == '�' and $vetor[0]{
      1} == '�' and $vetor[0]{
      2} == '�') //identifier has been identified!
      {
        $content = explode("���", $vetor[0]);
        $texto = $content[2];
        $content = explode(",", $content[1]);
        foreach ($content as $value) {
          $value = explode("=", $value);
          $specialcontent[$value[0]] = $value[1];
        }
        if ($this->flowingBlockAttr['contentWidth'] > 0) // Print out previously accumulated content
        {
          $width_used = $this->flowingBlockAttr['contentWidth'] / $this->k;
          //Restart Flowing Block
          $this->finishFlowingBlock($outofblock);
          $this->x = $bak_x + ($width_used % $this->divwidth) + 0.5; // 0.5 == margin
          $this->y -= ($this->lineheight + 0.5);
          $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)
          if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin
          if (($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divwidth) {
            $this->x = $bak_x;
            $this->y += $this->lineheight - 1;
          }
          $this->newFlowingBlock($this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table);
        }
        switch (strtoupper($specialcontent['type'])) {
          case 'IMAGE':
            //xpos and ypos used in order to support: <div align='center'><img ...></div>
            $xpos = 0;
            $ypos = 0;
            if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos'];
            if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos'];
            $width_used = (($this->x - $bak_x) + $specialcontent['width']) * $this->k; //in order to adjust x coordinate later
            //Is this the best way of fixing x,y coordinates?
            $fix_x = ($this->x + 2) * $this->k + ($xpos * $this->k); //+2 margin
            $fix_y = ($this->h - (($this->y + 2) + $specialcontent['height'])) * $this->k; //+2 margin
            $imgtemp = explode(" ", $texto);
            $imgtemp[5] = $fix_x; // x
            $imgtemp[6] = $fix_y; // y
            $texto = implode(" ", $imgtemp);
            $this->_out($texto);
            //Readjust x coordinate in order to allow text to be placed after this form element
            $this->x = $bak_x;
            $spacesize = $this->CurrentFont['cw'][' '] * ($this->FontSizePt / 1000);
            $spacenum = (int)ceil(($width_used / $spacesize));
            //Consider the space used so far in this line as a bunch of spaces
            if ($ypos != 0) $this->Ln($ypos);
            else $this->WriteFlowingBlock(str_repeat(' ', $spacenum));
            break;
          case 'INPUT':
            switch ($specialcontent['subtype']) {
              case 'PASSWORD':
              case 'TEXT': //Draw TextField
                $width_used = (($this->x - $bak_x) + $specialcontent['width']) * $this->k; //in order to adjust x coordinate later
                $this->SetFillColor(235, 235, 235);
                $this->x += 1;
                $this->y += 1;
                $this->Rect($this->x, $this->y, $specialcontent['width'], 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->y -= 1;
                //Readjust x coordinate in order to allow text to be placed after this form element
                $this->x = $bak_x;
                $spacesize = $this->CurrentFont['cw'][' '] * ($this->FontSizePt / 1000);
                $spacenum = (int)ceil(($width_used / $spacesize));
                //Consider the space used so far in this line as a bunch of spaces
                $this->WriteFlowingBlock(str_repeat(' ', $spacenum));
                break;
              case 'CHECKBOX': //Draw Checkbox
                $width_used = (($this->x - $bak_x) + $specialcontent['width']) * $this->k; //in order to adjust x coordinate later
                $checked = $texto;
                $this->SetFillColor(235, 235, 235);
                $this->y += 1;
                $this->x += 1;
                $this->Rect($this->x, $this->y, 3, 3, 'DF');
                if ($checked) {
                  $this->Line($this->x, $this->y, $this->x + 3, $this->y + 3);
                  $this->Line($this->x, $this->y + 3, $this->x + 3, $this->y);
                }
                $this->SetFillColor(255);
                $this->y -= 1;
                //Readjust x coordinate in order to allow text to be placed after this form element
                $this->x = $bak_x;
                $spacesize = $this->CurrentFont['cw'][' '] * ($this->FontSizePt / 1000);
                $spacenum = (int)ceil(($width_used / $spacesize));
                //Consider the space used so far in this line as a bunch of spaces
                $this->WriteFlowingBlock(str_repeat(' ', $spacenum));
                break;
              case 'RADIO': //Draw Radio button
                $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 0.5) * $this->k; //in order to adjust x coordinate later
                $checked = $texto;
                $this->x += 2;
                $this->y += 1.5;
                $this->Circle($this->x, $this->y + 1.2, 1, 'D');
                $this->_out('0.000 g');
                if ($checked) $this->Circle($this->x, $this->y + 1.2, 0.4, 'DF');
                $this->y -= 1.5;
                //Readjust x coordinate in order to allow text to be placed after this form element
                $this->x = $bak_x;
                $spacesize = $this->CurrentFont['cw'][' '] * ($this->FontSizePt / 1000);
                $spacenum = (int)ceil(($width_used / $spacesize));
                //Consider the space used so far in this line as a bunch of spaces
                $this->WriteFlowingBlock(str_repeat(' ', $spacenum));
                break;
              case 'BUTTON': // Draw a button
              case 'SUBMIT':
              case 'RESET':
                $nihil = ($specialcontent['width'] - $this->GetStringWidth($texto)) / 2;
                $this->x += 1.5;
                $this->y += 1;
                $this->SetFillColor(190, 190, 190);
                $this->Rect($this->x, $this->y, $specialcontent['width'], 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);
                $this->y -= 1;
                break;
              default:
                break;
            }
            break;
          case 'SELECT':
            $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8) * $this->k; //in order to adjust x coordinate later
            $this->SetFillColor(235, 235, 235); //light gray
            $this->x += 1.5;
            $this->y += 1;
            $this->Rect($this->x, $this->y, $specialcontent['width'] + 2, $this->lineheight, 'DF'); // +2 == margin
            $this->x += 1;
            if ($texto != '') $this->Write($this->lineheight, $texto, $this->x); //the combobox content
            $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2;
            $this->SetFillColor(190, 190, 190); //dark gray
            $this->Rect($this->x - 1, $this->y, 5, 5, 'DF'); //Arrow Box
            $this->SetFont('zapfdingbats');
            $this->Write($this->lineheight, chr(116), $this->x); //Down arrow
            $this->SetFont('arial');
            $this->SetFillColor(255);
            //Readjust x coordinate in order to allow text to be placed after this form element
            $this->x = $bak_x;
            $spacesize = $this->CurrentFont['cw'][' '] * ($this->FontSizePt / 1000);
            $spacenum = (int)ceil(($width_used / $spacesize));
            //Consider the space used so far in this line as a bunch of spaces
            $this->WriteFlowingBlock(str_repeat(' ', $spacenum));
            break;
          case 'TEXTAREA':
            //Setup TextArea properties
            $this->SetFillColor(235, 235, 235);
            $this->SetFont('courier');
            $this->currentfont = 'courier';
            $ta_lines = $specialcontent['lines'];
            $ta_height = 1.1 * $this->lineheight * $ta_lines;
            $ta_width = $specialcontent['width'];
            //Adjust x,y coordinates
            $this->x += 1.5;
            $this->y += 1.5;
            $linesneeded = $this->WordWrap($texto, $ta_width);
            if ($linesneeded > $ta_lines) //Too many words inside textarea
            {
              $textoaux = explode("\n", $texto);
              $texto = '';
              for ($i = 0; $i < $ta_lines; $i++) {
                if ($i == $ta_lines - 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;
            $backup_x = $this->x;
            $this->Rect($this->x, $this->y, $ta_width + 3, $ta_height, 'DF');
            if ($texto != '') $this->MultiCell($ta_width + 3, $this->lineheight, $texto);
            $this->y = $backup_y - 1.5;
            $this->x = $backup_x + $ta_width + 2.5;
            $this->SetFillColor(255);
            $this->SetFont('arial');
            $this->currentfont = '';
            break;
          default:
            break;
        }
      } else //THE text
      {
        if ($vetor[0] == "\n") //We are reading a <BR> now turned into newline ("\n")
        {
          //Restart Flowing Block
          $this->finishFlowingBlock($outofblock);
          if ($outofblock) $this->Ln($this->lineheight);
          $this->x = $bak_x;
          $this->newFlowingBlock($this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table);
        } else $this->WriteFlowingBlock($vetor[0], $outofblock);
      }
      //Check if it is the last element. If so then finish printing the block
      if ($i == ($array_size - 1)) $this->finishFlowingBlock($outofblock);
      //Now we must deactivate what we have used
      if ((isset($vetor[1]) and $vetor[1] != '') or $this->HREF != '') {
        $this->SetTextColor(0);
        $this->SetStyle('U', false);
        $this->HREF = '';
      }
      if (isset($vetor[2]) and $vetor[2] != '') {
        $this->SetStyle('B', false);
        $this->SetStyle('I', false);
        $this->SetStyle('U', false);
      }
      if (isset($vetor[3]) and $vetor[3] != '') {
        unset($cor);
        $this->SetTextColor(0);
      }
      if (isset($vetor[4]) and $vetor[4] != '') $this->SetFont('arial');
      if (isset($vetor[5]) and $vetor[5] === true) {
        $this->SUP = false;
        $this->SetFontSize(11);
      }
      if (isset($vetor[6]) and $vetor[6] === true) {
        $this->SUB = false;
        $this->SetFontSize(11);
      }
      //vetor7-internal links
      if (isset($vetor[8]) and $vetor[8] === true) // strike-through the text
      {
        $this->strike = false;
      }
      if (isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
      {
        $this->SetTextOutline(false);
        $this->outline_on = false;
      }
      if (isset($vetor[10]) and !empty($vetor[10])) //Background color
      {
        $this->SetFillColor(255);
        $this->divbgcolor = false;
      }
    } //end of for(i=0;i<arraysize;i++)

    //Restore some previously set parameters
    $this->strike = $save['strike'];
    $this->SUP = $save['SUP'];
    $this->SUB = $save['SUB'];
    $this->dotted_on = $save['DOTTED'];
    $this->dash_on = $save['DASHED'];
    if ($this->dash_on) $this->SetDash(2, 2);
    //Check whether we have borders to paint or not
    //(only works 100% if whole content spans only 1 page)
    if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor)) {
      if ($oldpage != $this->page) {
        //Only border on last page is painted (known bug)
        $x = $this->lMargin;
        $y = $this->tMargin;
        $old_height = $this->y - $y;
      } else {
        if ($this->oldx < 0) $x  = $this->x;
        else $x = $this->oldx;
        if ($this->oldy < 0) $y  = $this->y - $old_height;
        else $y = $this->oldy;
      }
      if ($this->divborder) $this->Rect($x, $y, $this->divwidth, $old_height);
      if ($this->dash_on) $this->Rect($x, $y, $this->divwidth, $old_height);
      if ($this->dotted_on) $this->DottedRect($x, $y, $this->divwidth, $old_height);
      $this->x = $bak_x;
    }
  }

  function Reset()
  {
    //! @return void
    //! @desc Resets several class attributes

    //	if ( $this->issetcolor !== true )
    //  {
    $this->SetTextColor(0);
    $this->SetDrawColor(0);
    $this->SetFillColor(255);
    $this->colorarray = array();
    $this->bgcolorarray = array();
    $this->issetcolor = false;
    //	}
    $this->HREF = '';
    $this->SetTextOutline(false);

    //$this->strike = false;

    $this->SetFontSize(9); //manoj this is able to set font for normal text origninal 11
    $this->SetStyle('B', false);
    $this->SetStyle('I', false);
    $this->SetStyle('U', false);
    $this->SetFont('arial');
    $this->divwidth = 0;
    $this->divheight = 0;
    $this->divalign = "L";
    $this->divrevert = false;
    $this->divborder = 0;
    $this->divbgcolor = false;
    $this->toupper = false;
    $this->tolower = false;
    $this->SetDash(); //restore to no dash
    $this->dash_on = false;
    $this->dotted_on = false;
    $this->oldx = -1;
    $this->oldy = -1;
  }

  function ReadMetaTags($html)
  {
    //! @return void
    //! @desc Pass meta tag info to PDF file properties
    $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
    $html = preg_replace($regexp, " \$1=\"\$2\"", $html);
    $regexp = '/<meta .*?(name|content)="(.*?)" .*?(name|content)="(.*?)".*?>/si';
    preg_match_all($regexp, $html, $aux);

    $firstattr = $aux[1];
    $secondattr = $aux[3];
    for ($i = 0; $i < count($aux[0]); $i++) {

      $name = (strtoupper($firstattr[$i]) == "NAME") ? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
      $content = (strtoupper($firstattr[$i]) == "CONTENT") ? $aux[2][$i] : $aux[4][$i];
      switch ($name) {
        case "KEYWORDS":
          $this->SetKeywords($content);
          break;
        case "AUTHOR":
          $this->SetAuthor($content);
          break;
        case "DESCRIPTION":
          $this->SetSubject($content);
          break;
      }
    }
    //Comercial do Aplicativo usado (no caso um script):
    $this->SetCreator("HTML2FPDF >> http://html2fpdf.sf.net");
  }

  //////////////////
  /// CSS parser ///
  //////////////////
  function ReadCSS($html)
  {
    //! @desc CSS parser
    //! @return string

    /*
* This version ONLY supports:  .class {...} / #id { .... }
* It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names
* This function must read the CSS code (internal or external) and order its value inside $this->CSS. 
*/

    $match = 0; // no match for instance
    $regexp = ''; // This helps debugging: showing what is the REAL string being processed

    //CSS inside external files
    $regexp = '/<link rel="stylesheet".*?href="(.+?)"\\s*?\/?>/si';
    $match = preg_match_all($regexp, $html, $CSSext);
    $ind = 0;

    while ($match) {
      //Fix path value
      $path = $CSSext[1][$ind];
      $path = str_replace("\\", "/", $path); //If on Windows
      //Get link info and obtain its absolute path
      $regexp = '|^./|';
      $path = preg_replace($regexp, '', $path);
      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
      //END of fix path value
      $CSSextblock = file_get_contents($path);

      //Get class/id name and its characteristics from $CSSblock[1]
      $regexp = '/[.# ]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
      preg_match_all($regexp, $CSSextblock, $extstyle);

      //Make CSS[Name-of-the-class] = array(key => value)
      $regexp = '/\\s*?(\\S+?):(.+?);/si';

      for ($i = 0; $i < count($extstyle[1]); $i++) {
        preg_match_all($regexp, $extstyle[2][$i], $extstyleinfo);
        $extproperties = $extstyleinfo[1];
        $extvalues = $extstyleinfo[2];
        for ($j = 0; $j < count($extproperties); $j++) {
          //Array-properties and Array-values must have the SAME SIZE!
          $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]);
        }
        $this->CSS[$extstyle[1][$i]] = $extclassproperties;
        $extproperties = array();
        $extvalues = array();
        $extclassproperties = array();
      }
      $match--;
      $ind++;
    } //end of match

    $match = 0; // reset value, if needed

    //CSS internal
    //Get content between tags and order it, using regexp
    $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css"> 
    $match = preg_match($regexp, $html, $CSSblock);

    if ($match) {
      //Get class/id name and its characteristics from $CSSblock[1]
      $regexp = '/[.#]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n
      preg_match_all($regexp, $CSSblock[1], $style);

      //Make CSS[Name-of-the-class] = array(key => value)
      $regexp = '/\\s*?(\\S+?):(.+?);/si';

      for ($i = 0; $i < count($style[1]); $i++) {
        preg_match_all($regexp, $style[2][$i], $styleinfo);
        $properties = $styleinfo[1];
        $values = $styleinfo[2];
        for ($j = 0; $j < count($properties); $j++) {
          //Array-properties and Array-values must have the SAME SIZE!
          $classproperties[strtoupper($properties[$j])] = trim($values[$j]);
        }
        $this->CSS[$style[1][$i]] = $classproperties;
        $properties = array();
        $values = array();
        $classproperties = array();
      }
    } // end of match

    //Remove CSS (tags and content), if any
    $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css"> 
    $html = preg_replace($regexp, '', $html);

    return $html;
  }

  function readInlineCSS($html)
  {
    //! @return array
    //! @desc Reads inline CSS and returns an array of properties

    //Fix incomplete CSS code
    $size = strlen($html) - 1;
    if ($html{
    $size} != ';') $html .= ';';
    //Make CSS[Name-of-the-class] = array(key => value)
    $regexp = '|\\s*?(\\S+?):(.+?);|i';
    preg_match_all($regexp, $html, $styleinfo);
    $properties = $styleinfo[1];
    $values = $styleinfo[2];
    //Array-properties and Array-values must have the SAME SIZE!
    $classproperties = array();
    for ($i = 0; $i < count($properties); $i++) $classproperties[strtoupper($properties[$i])] = trim($values[$i]);

    return $classproperties;
  }

  function setCSS($arrayaux)
  {
    //! @return void
    //! @desc Change some class attributes according to CSS properties
    if (!is_array($arrayaux)) return; //Removes PHP Warning
    foreach ($arrayaux as $k => $v) {
      switch ($k) {
        case 'WIDTH':
          $this->divwidth = ConvertSize($v, $this->pgwidth);
          break;
        case 'HEIGHT':
          $this->divheight = ConvertSize($v, $this->pgwidth);
          break;
        case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
          $prop = explode(' ', $v);
          if (count($prop) != 3) break; // Not supported: borders not fully declared
          //style: dashed dotted none (anything else => solid )
          if (strnatcasecmp($prop[1], "dashed") == 0) //found "dashed"! (ignores case)
          {
            $this->dash_on = true;
            $this->SetDash(2, 2); //2mm on, 2mm off
          } elseif (strnatcasecmp($prop[1], "dotted") == 0) //found "dotted"! (ignores case)
          {
            $this->dotted_on = true;
          } elseif (strnatcasecmp($prop[1], "none") == 0) $this->divborder = 0;
          else $this->divborder = 1;
          //color
          $coul = ConvertColor($prop[2]);
          $this->SetDrawColor($coul['R'], $coul['G'], $coul['B']);
          $this->issetcolor = true;
          break;
        case 'FONT-FAMILY': // one of the $this->fontlist fonts
          //If it is a font list, get all font types
          $aux_fontlist = explode(",", $v);
          $fontarraysize = count($aux_fontlist);
          for ($i = 0; $i < $fontarraysize; $i++) {
            $fonttype = $aux_fontlist[$i];
            $fonttype = trim($fonttype);
            //If font is found, set it, and exit loop
            if (in_array(strtolower($fonttype), $this->fontlist)) {
              $this->SetFont(strtolower($fonttype));
              break;
            }
            //If font = "courier new" for example, try simply looking for "courier"
            $fonttype = explode(" ", $fonttype);
            $fonttype = $fonttype[0];
            if (in_array(strtolower($fonttype), $this->fontlist)) {
              $this->SetFont(strtolower($fonttype));
              break;
            }
          }
          break;
        case 'FONT-SIZE': //Does not support: smaller, larger
          if (is_numeric($v{
          0})) {
            $mmsize = ConvertSize($v, $this->pgwidth);
            $this->SetFontSize($mmsize * (72 / 25.4)); //Get size in points (pt)
          } else {
            $v = strtoupper($v);
            switch ($v) {
                //Values obtained from http://www.w3schools.com/html/html_reference.asp
              case 'XX-SMALL':
                $this->SetFontSize((0.7) * 11);
                break;
              case 'X-SMALL':
                $this->SetFontSize((0.77) * 11);
                break;
              case 'SMALL':
                $this->SetFontSize((0.86) * 11);
                break;
              case 'MEDIUM':
                $this->SetFontSize(11);
                break;
              case 'LARGE':
                $this->SetFontSize((1.2) * 11);
                break;
              case 'X-LARGE':
                $this->SetFontSize((1.5) * 11);
                break;
              case 'XX-LARGE':
                $this->SetFontSize(2 * 11);
                break;
            }
          }
          break;
        case 'FONT-STYLE': // italic normal oblique
          switch (strtoupper($v)) {
            case 'ITALIC':
            case 'OBLIQUE':
              $this->SetStyle('I', true);
              break;
            case 'NORMAL':
              break;
          }
          break;
        case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
          switch (strtoupper($v)) {
            case 'BOLD':
              $this->SetStyle('B', true);
              break;
            case 'NORMAL':
              break;
          }
          break;
        case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
          switch (strtoupper($v)) {
            case 'LINE-THROUGH':
              $this->strike = true;
              break;
            case 'UNDERLINE':
              $this->SetStyle('U', true);
              break;
            case 'NONE':
              break;
          }
        case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
          switch (strtoupper($v)) //Not working 100%
          {
            case 'UPPERCASE':
              $this->toupper = true;
              break;
            case 'LOWERCASE':
              $this->tolower = true;
              break;
            case 'NONE':
              break;
          }
        case 'TEXT-ALIGN': //left right center justify
          switch (strtoupper($v)) {
            case 'LEFT':
              $this->divalign = "L";
              break;
            case 'CENTER':
              $this->divalign = "C";
              break;
            case 'RIGHT':
              $this->divalign = "R";
              break;
            case 'JUSTIFY':
              $this->divalign = "J";
              break;
          }
          break;
        case 'DIRECTION': //ltr(default) rtl
          if (strtolower($v) == 'rtl') $this->divrevert = true;
          break;
        case 'BACKGROUND': // bgcolor only
          $cor = ConvertColor($v);
          $this->bgcolorarray = $cor;
          $this->SetFillColor($cor['R'], $cor['G'], $cor['B']);
          $this->divbgcolor = true;
          break;
        case 'COLOR': // font color
          $cor = ConvertColor($v);
          $this->colorarray = $cor;
          $this->SetTextColor($cor['R'], $cor['G'], $cor['B']);
          $this->issetcolor = true;
          break;
      } //end of switch($k)
    } //end of foreach
  }

  function SetStyle($tag, $enable)
  {
    //! @return void
    //! @desc Enables/Disables B,I,U styles
    //Modify style and select corresponding font
    $this->$tag += ($enable ? 1 : -1);
    $style = '';
    //Fix some SetStyle misuse
    if ($this->$tag < 0) $this->$tag = 0;
    if ($this->$tag > 1) $this->$tag = 1;
    foreach (array('B', 'I', 'U') as $s)
      if ($this->$s > 0)
        $style .= $s;

    $this->currentstyle = $style;
    $this->SetFont('', $style);
  }

  function DisableTags($str = '')
  {
    //! @return void
    //! @desc Disable some tags using ',' as separator. Enable all tags calling this function without parameters.
    if ($str == '') //enable all tags
    {
      //Insert new supported tags in the long string below.
      $this->enabledtags = "<tt><kbd><samp><option><outline><span><newpage><page_break><s><strike><del><bdo><big><small><address><ins><cite><font><center><sup><sub><input><select><option><textarea><title><form><ol><ul><li><h1><h2><h3><h4><h5><h6><pre><b><u><i><a><img><p><br><strong><em><code><th><tr><blockquote><hr><td><tr><table><div>";
    } else {
      $str = explode(",", $str);
      foreach ($str as $v) $this->enabledtags = str_replace(trim($v), '', $this->enabledtags);
    }
  }

  ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
  //Thanks to vietcom (vncommando at yahoo dot com)
  /*     Modified by Renato Coelho
   in order to print tables that span more than 1 page and to allow 
   bold,italic and the likes inside table cells (and alignment now works with styles!)
*/

  //table		Array of (w, h, bc, nr, wc, hr, cells)
  //w			Width of table
  //h			Height of table
  //nc		Number column
  //nr		Number row
  //hr		List of height of each row
  //wc		List of width of each column
  //cells		List of cells of each rows, cells[i][j] is a cell in the table
  function _tableColumnWidth(&$table)
  {
    //! @return void
    $cs = &$table['cells'];
    $mw = $this->getStringWidth('W');
    $nc = $table['nc'];
    $nr = $table['nr'];
    $listspan = array();
    //Xac dinh do rong cua cac cell va cac cot tuong ung
    for ($j = 0; $j < $nc; $j++) //columns
    {
      $wc = &$table['wc'][$j];
      for ($i = 0; $i < $nr; $i++) //rows
      {
        if (isset($cs[$i][$j]) && $cs[$i][$j]) {
          $c = &$cs[$i][$j];
          $miw = $mw;
          if (isset($c['maxs']) and $c['maxs'] != '') $c['s'] = $c['maxs'];
          $c['maw']  = $c['s'];
          if (isset($c['nowrap'])) $miw = $c['maw'];
          if (isset($c['w'])) {
            if ($miw < $c['w'])  $c['miw'] = $c['w'];
            if ($miw > $c['w'])  $c['miw'] = $c['w']    = $miw;
            if (!isset($wc['w'])) $wc['w'] = 1;
          } else $c['miw'] = $miw;
          if ($c['maw']  < $c['miw']) $c['maw'] = $c['miw'];
          if (!isset($c['colspan'])) {
            if ($wc['miw'] < $c['miw'])    $wc['miw']  = $c['miw'];
            if ($wc['maw'] < $c['maw'])    $wc['maw']  = $c['maw'];
          } else $listspan[] = array($i, $j);
          //Check if minimum width of the whole column is big enough for a huge word to fit
          $auxtext = implode("", $c['text']);
          $minwidth = $this->WordWrap($auxtext, $wc['miw'] - 2); // -2 == margin
          if ($minwidth < 0 and (-$minwidth) > $wc['miw']) $wc['miw'] = (-$minwidth) + 2; //increase minimum width
          if ($wc['miw'] > $wc['maw']) $wc['maw'] = $wc['miw']; //update maximum width, if needed
        }
      } //rows
    } //columns
    //Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai
    $wc = &$table['wc'];
    foreach ($listspan as $span) {
      list($i, $j) = $span;
      $c = &$cs[$i][$j];
      $lc = $j + $c['colspan'];
      if ($lc > $nc) $lc = $nc;

      $wis = $wisa = 0;
      $was = $wasa = 0;
      $list = array();
      for ($k = $j; $k < $lc; $k++) {
        $wis += $wc[$k]['miw'];
        $was += $wc[$k]['maw'];
        if (!isset($c['w'])) {
          $list[] = $k;
          $wisa += $wc[$k]['miw'];
          $wasa += $wc[$k]['maw'];
        }
      }
      if ($c['miw'] > $wis) {
        if (!$wis) { //Cac cot chua co kich thuoc => chia deu
          for ($k = $j; $k < $lc; $k++) $wc[$k]['miw'] = $c['miw'] / $c['colspan'];
        } elseif (!count($list)) { //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
          $wi = $c['miw'] - $wis;
          for ($k = $j; $k < $lc; $k++) $wc[$k]['miw'] += ($wc[$k]['miw'] / $wis) * $wi;
        } else { //Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
          $wi = $c['miw'] - $wis;
          foreach ($list as $k)  $wc[$k]['miw'] += ($wc[$k]['miw'] / $wisa) * $wi;
        }
      }
      if ($c['maw'] > $was) {
        if (!$wis) { //Cac cot chua co kich thuoc => chia deu
          for ($k = $j; $k < $lc; $k++) $wc[$k]['maw'] = $c['maw'] / $c['colspan'];
        } elseif (!count($list)) {
          //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
          $wi = $c['maw'] - $was;
          for ($k = $j; $k < $lc; $k++) $wc[$k]['maw'] += ($wc[$k]['maw'] / $was) * $wi;
        } else { //Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
          $wi = $c['maw'] - $was;
          foreach ($list as $k)  $wc[$k]['maw'] += ($wc[$k]['maw'] / $wasa) * $wi;
        }
      }
    }
  }

  function _tableWidth(&$table)
  {
    //! @return void
    //! @desc Calculates the Table Width
    // @desc Xac dinh chieu rong cua table
    $widthcols = &$table['wc'];
    $numcols = $table['nc'];
    $tablewidth = 0;
    for ($i = 0; $i < $numcols; $i++) {
      $tablewidth += isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
    }
    if ($tablewidth > $this->pgwidth) $table['w'] = $this->pgwidth;
    if (isset($table['w'])) {
      $wis = $wisa = 0;
      $list = array();
      for ($i = 0; $i < $numcols; $i++) {
        $wis += $widthcols[$i]['miw'];
        if (!isset($widthcols[$i]['w'])) {
          $list[] = $i;
          $wisa += $widthcols[$i]['miw'];
        }
      }
      if ($table['w'] > $wis) {
        if (!count($list)) { //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
          //http://www.ksvn.com/anhviet_new.htm - translating comments...
          //bent shrink essence move size measure automatic => divide against give as a whole
          //$wi = $table['w'] - $wis;
          if ($numcols != 0) {
            $wi = ($table['w'] - $wis) / $numcols;
          }
          for ($k = 0; $k < $numcols; $k++)
            //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wis)*$wi;
            $widthcols[$k]['miw'] += $wi;
        } else { //Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
          //$wi = $table['w'] - $wis;
          $wi = ($table['w'] - $wis) / count($list);
          foreach ($list as $k)
            //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wisa)*$wi;
            $widthcols[$k]['miw'] += $wi;
        }
      }
      for ($i = 0; $i < $numcols; $i++) {
        $tablewidth = $widthcols[$i]['miw'];
        unset($widthcols[$i]);
        $widthcols[$i] = $tablewidth;
      }
    } else //table has no width defined
    {
      $table['w'] = $tablewidth;
      for ($i = 0; $i < $numcols; $i++) {
        $tablewidth = isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
        unset($widthcols[$i]);
        $widthcols[$i] = $tablewidth;
      }
    }
  }

  function _tableHeight(&$table)
  {
    //! @return void
    //! @desc Calculates the Table Height
    $cells = &$table['cells'];
    $numcols = $table['nc'];
    $numrows = $table['nr'];
    $listspan = array();
    for ($i = 0; $i < $numrows; $i++) //rows
    {
      $heightrow = &$table['hr'][$i];
      for ($j = 0; $j < $numcols; $j++) //columns
      {
        if (isset($cells[$i][$j]) && $cells[$i][$j]) {
          $c = &$cells[$i][$j];
          list($x, $cw) = $this->_tableGetWidth($table, $i, $j);
          //Check whether width is enough for this cells' text
          $auxtext = implode("", $c['text']);
          $auxtext2 = $auxtext; //in case we have text with styles
          $nostyles_size = $this->GetStringWidth($auxtext) + 3; // +3 == margin
          $linesneeded = $this->WordWrap($auxtext, $cw - 2); // -2 == margin
          if ($c['s'] > $nostyles_size and !isset($c['form'])) //Text with styles
          {
            $auxtext = $auxtext2; //recover original characteristics (original /n placements)
            $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char
            if ($linesneeded == 0) $linesneeded = 1; //to avoid division by zero
            $diffsize /= $linesneeded;
            $linesneeded = $this->WordWrap($auxtext, $cw - 2 - $diffsize); //diffsize used to wrap text correctly
          }
          if (isset($c['form'])) {
            $linesneeded = ceil(($c['s'] - 3) / ($cw - 2)); //Text + form in a cell
            //Presuming the use of styles
            if (($this->GetStringWidth($auxtext) + 3) > ($cw - 2)) $linesneeded++;
          }
          $ch = $linesneeded * 1.1 * $this->lineheight;
          //If height is bigger than page height...
          if ($ch > ($this->fh - $this->bMargin - $this->tMargin)) $ch = ($this->fh - $this->bMargin - $this->tMargin);
          //If height is defined and it is bigger than calculated $ch then update values
          if (isset($c['h']) && $c['h'] > $ch) {
            $c['mih'] = $ch; //in order to keep valign working
            $ch = $c['h'];
          } else $c['mih'] = $ch;
          if (isset($c['rowspan']))  $listspan[] = array($i, $j);
          elseif ($heightrow < $ch) $heightrow = $ch;
          if (isset($c['form'])) $c['mih'] = $ch;
        }
      } //end of columns
    } //end of rows
    $heightrow = &$table['hr'];
    foreach ($listspan as $span) {
      list($i, $j) = $span;
      $c = &$cells[$i][$j];
      $lr = $i + $c['rowspan'];
      if ($lr > $numrows) $lr = $numrows;
      $hs = $hsa = 0;
      $list = array();
      for ($k = $i; $k < $lr; $k++) {
        $hs += $heightrow[$k];
        if (!isset($c['h'])) {
          $list[] = $k;
          $hsa += $heightrow[$k];
        }
      }
      if ($c['mih'] > $hs) {
        if (!$hs) { //Cac dong chua co kich thuoc => chia deu
          for ($k = $i; $k < $lr; $k++) $heightrow[$k] = $c['mih'] / $c['rowspan'];
        } elseif (!count($list)) { //Khong co dong nao co kich thuoc auto => chia deu phan du cho tat ca
          $hi = $c['mih'] - $hs;
          for ($k = $i; $k < $lr; $k++) $heightrow[$k] += ($heightrow[$k] / $hs) * $hi;
        } else { //Co mot so dong co kich thuoc auto => chia deu phan du cho cac dong auto
          $hi = $c['mih'] - $hsa;
          foreach ($list as $k) $heightrow[$k] += ($heightrow[$k] / $hsa) * $hi;
        }
      }
    }
  }

  function _tableGetWidth(&$table, $i, $j)
  {
    //! @return array(x,w)
    // @desc Xac dinh toa do va do rong cua mot cell

    $cell = &$table['cells'][$i][$j];
    if ($cell) {
      if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
      $x = 0;
      $widthcols = &$table['wc'];
      for ($k = 0; $k < $j; $k++) $x += $widthcols[$k];
      $w = $widthcols[$j];
      if (isset($cell['colspan'])) {
        for ($k = $j + $cell['colspan'] - 1; $k > $j; $k--)  $w += $widthcols[$k];
      }
      $cell['x0'] = $x;
      $cell['w0'] = $w;
      return array($x, $w);
    }
    return array(0, 0);
  }

  function _tableGetHeight(&$table, $i, $j)
  {
    //! @return array(y,h)
    $cell = &$table['cells'][$i][$j];
    if ($cell) {
      if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
      $y = 0;
      $heightrow = &$table['hr'];
      for ($k = 0; $k < $i; $k++) $y += $heightrow[$k];
      $h = $heightrow[$i];
      if (isset($cell['rowspan'])) {
        for ($k = $i + $cell['rowspan'] - 1; $k > $i; $k--)
          $h += $heightrow[$k];
      }
      $cell['y0'] = $y;
      $cell['h0'] = $h;
      return array($y, $h);
    }
    return array(0, 0);
  }

  function _tableRect($x, $y, $w, $h, $type = 1)
  {
    //! @return void
    if ($type == 1)  $this->Rect($x, $y, $w, $h);
    elseif (strlen($type) == 4) {
      $x2 = $x + $w;
      $y2 = $y + $h;
      if (intval($type{
      0})) $this->Line($x, $y, $x2, $y);
      if (intval($type{
      1})) $this->Line($x2, $y, $x2, $y2);
      if (intval($type{
      2})) $this->Line($x, $y2, $x2, $y2);
      if (intval($type{
      3})) $this->Line($x, $y, $x, $y2);
    }
  }

  function _tableWrite(&$table)
  {
    //! @desc Main table function
    //! @return void
    $cells = &$table['cells'];
    $numcols = $table['nc'];
    $numrows = $table['nr'];
    $x0 = $this->x;
    $y0 = $this->y;
    $right = $this->pgwidth - $this->rMargin;
    if (isset($table['a']) and ($table['w'] != $this->pgwidth)) {
      if ($table['a'] == 'C') $x0 += (($right - $x0) - $table['w']) / 2;
      elseif ($table['a'] == 'R')  $x0 = $right - $table['w'];
    }
    $returny = 0;
    $tableheader = array();
    //Draw Table Contents and Borders
    for ($i = 0; $i < $numrows; $i++) //Rows
    {
      $skippage = false;
      for ($j = 0; $j < $numcols; $j++) //Columns
      {
        if (isset($cells[$i][$j]) && $cells[$i][$j]) {
          $cell = &$cells[$i][$j];
          list($x, $w) = $this->_tableGetWidth($table, $i, $j);
          list($y, $h) = $this->_tableGetHeight($table, $i, $j);
          $x += $x0;
          $y += $y0;
          $y -= $returny;
          if ((($y + $h) > ($this->fh - $this->bMargin)) && ($y0 > 0 || $x0 > 0)) {
            if (!$skippage) {
              $y -= $y0;
              $returny += $y;
              $this->AddPage();
              if ($this->usetableheader) $this->Header($tableheader);
              if ($this->usetableheader) $y0 = $this->y;
              else $y0 = $this->tMargin;
              $y = $y0;
            }
            $skippage = true;
          }
          //Align
          $this->x = $x;
          $this->y = $y;
          $align = isset($cell['a']) ? $cell['a'] : 'L';
          //Vertical align
          if (!isset($cell['va']) || $cell['va'] == 'M') $this->y += ($h - $cell['mih']) / 2;
          elseif (isset($cell['va']) && $cell['va'] == 'B') $this->y += $h - $cell['mih'];
          //Fill
          $fill = isset($cell['bgcolor']) ? $cell['bgcolor']
            : (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i]
              : (isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0));
          if ($fill) {
            $color = ConvertColor($fill);
            $this->SetFillColor($color['R'], $color['G'], $color['B']);
            $this->Rect($x, $y, $w, $h, 'F');
          }
          //Border
          if (isset($cell['border'])) $this->_tableRect($x, $y, $w, $h, $cell['border']);
          elseif (isset($table['border']) && $table['border']) $this->Rect($x, $y, $w, $h);
          $this->divalign = $align;
          $this->divwidth = $w - 2;
          //Get info of first row == table header
          if ($this->usetableheader and $i == 0) {
            $tableheader[$j]['x'] = $x;
            $tableheader[$j]['y'] = $y;
            $tableheader[$j]['h'] = $h;
            $tableheader[$j]['w'] = $w;
            $tableheader[$j]['text'] = $cell['text'];
            $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
            $tableheader[$j]['a'] = isset($cell['a']) ? $cell['a'] : 'L';
            $tableheader[$j]['va'] = $cell['va'];
            $tableheader[$j]['mih'] = $cell['mih'];
            $tableheader[$j]['bgcolor'] = $fill;
            if ($table['border']) $tableheader[$j]['border'] = 'all';
            elseif (isset($cell['border'])) $tableheader[$j]['border'] = $cell['border'];
          }
          if (!empty($cell['textbuffer'])) $this->printbuffer($cell['textbuffer'], false, true/*inside a table*/);
          //Reset values
          $this->Reset();
        } //end of (if isset(cells)...)
      } // end of columns
      if ($i == $numrows - 1) $this->y = $y + $h; //last row jump (update this->y position)
    } // end of rows
  } //END OF FUNCTION _tableWrite()

  /////////////////////////END OF TABLE CODE//////////////////////////////////

}//end of Class

/*
----  JUNK(?)/OLD CODE: ------
// <?php <- this fixes HIGHLIGHT PSPAD bug ... 

*/