[ Indice ]

Riferimento incrociato di Joomla! 1.5.14 - VM 1.1.4

Servizio fornito da VMItalia
Classe:   Funzione:   Variabile:   Costante:  
Storico Ricerche +

titolo

Corpo

[chiudi]

/administrator/components/com_virtuemart/classes/pdf/ -> html2fpdf.php (sorgente)

   1  <?php
   2  if( !defined( '_VALID_MOS' ) && !defined( '_JEXEC' ) ) die( 'Direct Access to '.basename(__FILE__).' is not allowed.' );
   3  /**

   4  * @version $Id: html2fpdf.php 1828 2009-06-25 06:08:11Z Aravot $

   5  * @package VirtueMart

   6  * @subpackage HMTL2PDF

   7  * @author Renato Coelho

   8  * @copyright Copyright (C) 2004-2007 soeren - All rights reserved.

   9  * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php

  10  * VirtueMart is free software. This version may have been modified pursuant

  11  * to the GNU General Public License, and as distributed it includes or

  12  * is derivative of works licensed under the GNU General Public License or

  13  * other free or open source software licenses.

  14  * See /administrator/components/com_virtuemart/COPYRIGHT.php for copyright notices and details.

  15  *

  16  * http://virtuemart.net

  17  */
  18  /*

  19  *** General-use version

  20  

  21  DEBUG HINT:

  22  - Inside function printbuffer make $fill=1

  23  - Inside function Cell make:

  24  if($fill==1 or $border==1)

  25  {

  26  //      if ($fill==1) $op=($border==1) ? 'B' : 'f';

  27  //      else $op='S';

  28  $op='S';

  29  - Following these 2 steps you will be able to see the cell's boundaries

  30  

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

  32  

  33  ODDITIES (?):

  34  . It seems like saved['border'] and saved['bgcolor'] are useless inside the FlowingBlock...

  35  These 2 attributes do the same thing?!?:

  36  . $this->currentfont - mine

  37  . $this->CurrentFont - fpdf's

  38  

  39  TODO (in the future...):

  40  - Make font-family, font-size, lineheight customizable

  41  - Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported

  42  - allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed)

  43  - Improve CSS support

  44  - support image side-by-side or one-below-another or both?

  45  - Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example)

  46  

  47  //////////////////////////////////////////////////////////////////////////////

  48  //////////////DO NOT MODIFY THE CONTENTS OF THIS BOX//////////////////////////

  49  //////////////////////////////////////////////////////////////////////////////

  50  //                                                                          //

  51  // HTML2FPDF is a php script to read a HTML text and generate a PDF file.   //

  52  // Copyright (C) 2004-2005 Renato Coelho                                    //

  53  // This script may be distributed as long as the following files are kept   //

  54  // together:                                                                                //

  55  //                                                                                  //

  56  // fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt //

  57  //                                                                          //

  58  //////////////////////////////////////////////////////////////////////////////

  59  

  60  Misc. Observations:

  61  - CSS + align = bug! (?)

  62  OBS1: para textos de mais de 1 p?gina, talvez tenha que juntar varios $texto_artigo

  63  antes de mandar gerar o PDF, para que o PDF gerado seja completo.

  64  OBS2: there are 2 types of spaces 32 and 160 (ascii values)

  65  OBS3: //! is a special comment to be used with source2doc.php, a script I created

  66  in order to generate the doc on the site html2fpdf.sf.net

  67  OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work

  68  OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block)

  69  OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 )

  70  OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not)

  71  Perl:  '/regexp/x'  where x == option ( x = i:ignore case , x = s: DOT gets \n as well)

  72  ========================END OF INITIAL COMMENTS=================================

  73  */
  74  
  75  define('HTML2FPDF_VERSION','3.0(beta)');
  76  if (!defined('RELATIVE_PATH')) define('RELATIVE_PATH','');
  77  if (!defined('FPDF_FONTPATH')) define('FPDF_FONTPATH','font/');
  78  require_once (RELATIVE_PATH.'fpdf.php');
  79  require_once (RELATIVE_PATH.'htmltoolkit.php');
  80  
  81  class HTML2FPDF extends FPDF
  82  {
  83  //internal attributes

  84  var $HREF; //! string

  85  var $pgwidth; //! float

  86  var $fontlist; //! array 

  87  var $issetfont; //! bool

  88  var $issetcolor; //! bool

  89  var $titulo; //! string

  90  var $oldx; //! float

  91  var $oldy; //! float

  92  var $B; //! int

  93  var $U; //! int

  94  var $I; //! int

  95  
  96  var $tablestart; //! bool

  97  var $tdbegin; //! bool

  98  var $table; //! array

  99  var $cell; //! array 

 100  var $col; //! int

 101  var $row; //! int

 102  
 103  var $divbegin; //! bool

 104  var $divalign; //! char

 105  var $divwidth; //! float

 106  var $divheight; //! float

 107  var $divbgcolor; //! bool

 108  var $divcolor; //! bool

 109  var $divborder; //! int

 110  var $divrevert; //! bool

 111  
 112  var $listlvl; //! int

 113  var $listnum; //! int

 114  var $listtype; //! string

 115  //array(lvl,# of occurrences)

 116  var $listoccur; //! array

 117  //array(lvl,occurrence,type,maxnum)

 118  var $listlist; //! array

 119  //array(lvl,num,content,type)

 120  var $listitem; //! array

 121  
 122  var $buffer_on; //! bool

 123  var $pbegin; //! bool

 124  var $pjustfinished; //! bool

 125  var $blockjustfinished; //! bool

 126  var $SUP; //! bool

 127  var $SUB; //! bool

 128  var $toupper; //! bool

 129  var $tolower; //! bool

 130  var $dash_on; //! bool

 131  var $dotted_on; //! bool

 132  var $strike; //! bool

 133  
 134  var $CSS; //! array

 135  var $cssbegin; //! bool

 136  var $backupcss; //! array

 137  var $textbuffer; //! array

 138  var $currentstyle; //! string

 139  var $currentfont; //! string

 140  var $colorarray; //! array

 141  var $bgcolorarray; //! array

 142  var $internallink; //! array

 143  var $enabledtags; //! string

 144  
 145  var $lineheight; //! int

 146  var $basepath; //! string

 147  // array('COLOR','WIDTH','OLDWIDTH')

 148  var $outlineparam; //! array

 149  var $outline_on; //! bool

 150  
 151  var $specialcontent; //! string

 152  var $selectoption; //! array

 153  
 154  //options attributes

 155  var $usecss; //! bool

 156  var $usepre; //! bool

 157  var $usetableheader; //! bool

 158  var $shownoimg; //! bool

 159  
 160  function HTML2FPDF($orientation='P',$unit='mm',$format='A4')
 161  {
 162  //! @desc Constructor

 163  //! @return An object (a class instance)

 164      //Call parent constructor

 165      $this->FPDF($orientation,$unit,$format);
 166      //To make the function Footer() work properly

 167      $this->AliasNbPages();
 168      //Enable all tags as default

 169      $this->DisableTags();
 170    //Set default display preferences

 171    $this->DisplayPreferences('');
 172      //Initialization of the attributes

 173      $this->SetFont('Arial','',11); // Changeable?(not yet...)

 174    $this->lineheight = 5; // Related to FontSizePt == 11

 175    $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
 176    $this->SetFillColor(255);
 177      $this->HREF='';
 178      $this->titulo='';
 179      $this->oldx=-1;
 180      $this->oldy=-1;
 181      $this->B=0;
 182      $this->U=0;
 183      $this->I=0;
 184  
 185    $this->listlvl=0;
 186    $this->listnum=0; 
 187    $this->listtype='';
 188    $this->listoccur=array();
 189    $this->listlist=array();
 190    $this->listitem=array();
 191  
 192    $this->tablestart=false;
 193    $this->tdbegin=false; 
 194    $this->table=array(); 
 195    $this->cell=array();  
 196    $this->col=-1; 
 197    $this->row=-1; 
 198  
 199      $this->divbegin=false;
 200      $this->divalign="L";
 201      $this->divwidth=0; 
 202      $this->divheight=0; 
 203      $this->divbgcolor=false;
 204      $this->divcolor=false;
 205      $this->divborder=0;
 206      $this->divrevert=false;
 207  
 208      $this->fontlist=array("arial","times","courier","helvetica","symbol","monospace","serif","sans");
 209      $this->issetfont=false;
 210      $this->issetcolor=false;
 211  
 212    $this->pbegin=false;
 213    $this->pjustfinished=false;
 214    $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces

 215    $this->toupper=false;
 216    $this->tolower=false;
 217      $this->dash_on=false;
 218      $this->dotted_on=false;
 219    $this->SUP=false;
 220    $this->SUB=false;
 221    $this->buffer_on=false;
 222    $this->strike=false;
 223  
 224      $this->currentfont='';
 225      $this->currentstyle='';
 226    $this->colorarray=array();
 227    $this->bgcolorarray=array();
 228      $this->cssbegin=false;
 229    $this->textbuffer=array();
 230      $this->CSS=array();
 231      $this->backupcss=array();
 232      $this->internallink=array();
 233  
 234    $this->basepath = "";
 235    
 236    $this->outlineparam = array();
 237    $this->outline_on = false;
 238  
 239    $this->specialcontent = '';
 240    $this->selectoption = array();
 241  
 242    $this->shownoimg=false;
 243    $this->usetableheader=false;
 244    $this->usecss=true;
 245    $this->usepre=true;
 246  }
 247  
 248  function setBasePath($str)
 249  {
 250  //! @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.

 251  //! @return void

 252    $this->basepath = dirname($str) . "/";
 253    $this->basepath = str_replace("\\","/",$this->basepath); //If on Windows

 254  }
 255  
 256  function ShowNOIMG_GIF($opt=true)
 257  {
 258  //! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable

 259  //! @return void

 260    $this->shownoimg=$opt;
 261  }
 262  
 263  function UseCSS($opt=true)
 264  {
 265  //! @desc Enable/Disable CSS recognition. No-Parameter: Enable

 266  //! @return void

 267    $this->usecss=$opt;
 268  }
 269  
 270  function UseTableHeader($opt=true)
 271  {
 272  //! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable

 273  //! @return void

 274    $this->usetableheader=$opt;
 275  }
 276  
 277  function UsePRE($opt=true)
 278  {
 279  //! @desc Enable/Disable pre tag recognition. No-Parameter: Enable

 280  //! @return void

 281    $this->usepre=$opt;
 282  }
 283  
 284  //Page header

 285  function Header($content='')
 286  {
 287  //! @return void

 288  //! @desc The header is printed in every page.

 289    if($this->usetableheader and $content != '')
 290    {
 291      $y = $this->y;
 292      foreach($content as $tableheader)
 293      {
 294        $this->y = $y;
 295        //Set some cell values

 296        $x = $tableheader['x'];
 297        $w = $tableheader['w'];
 298        $h = $tableheader['h'];
 299        $va = $tableheader['va'];
 300        $mih = $tableheader['mih'];
 301        $fill = $tableheader['bgcolor'];
 302        $border = $tableheader['border'];
 303        $align = $tableheader['a'];
 304        //Align

 305        $this->divalign=$align;
 306              $this->x = $x;
 307            //Vertical align

 308            if (!isset($va) || $va=='M') $this->y += ($h-$mih)/2;
 309        elseif (isset($va) && $va=='B') $this->y += $h-$mih;
 310              if ($fill)
 311        {
 312                      $color = ConvertColor($fill);
 313                      $this->SetFillColor($color['R'],$color['G'],$color['B']);
 314                      $this->Rect($x, $y, $w, $h, 'F');
 315              }
 316          //Border

 317          if (isset($border) and $border != 'all') $this->_tableRect($x, $y, $w, $h, $border);
 318          elseif (isset($border) && $border == 'all') $this->Rect($x, $y, $w, $h);
 319          //Print cell content

 320        $this->divwidth = $w-2;
 321        $this->divheight = 1.1*$this->lineheight;
 322        $textbuffer = $tableheader['textbuffer'];
 323        if (!empty($textbuffer)) $this->printbuffer($textbuffer,false,true/*inside a table*/);
 324        $textbuffer = array();
 325      }
 326      $this->y = $y + $h; //Update y coordinate

 327    }//end of 'if usetableheader ...'

 328  }
 329  
 330  //Page footer

 331  function Footer()
 332  {
 333  //! @return void

 334  //! @desc The footer is printed in every page!

 335      //Position at 1.0 cm from bottom

 336      $this->SetY(-10);
 337      //Copyright //especial para esta vers?o

 338      $this->SetFont('Arial','B',9);
 339      $this->SetTextColor(0);
 340      //Arial italic 9

 341      $this->SetFont('Arial','I',9);
 342      //Page number

 343      $this->Cell(0,10,$this->PageNo().'/{nb}',0,0,'C');
 344      //Return Font to normal

 345      $this->SetFont('Arial','',11);
 346  }
 347  
 348  ///////////////////

 349  /// HTML parser ///

 350  ///////////////////

 351  function WriteHTML($html)
 352  {
 353  //! @desc HTML parser

 354  //! @return void

 355  /* $e == content */

 356  
 357    $this->ReadMetaTags($html);
 358    $html = AdjustHTML($html,$this->usepre); //Try to make HTML look more like XHTML

 359  
 360    if ($this->usecss) $html = $this->ReadCSS($html);
 361      //Add new supported tags in the DisableTags function

 362      $html=str_replace('<?php','< ',$html); //Fix '<?XML' bug from HTML code generated by MS Word

 363      //$html = str_replace ("%2", "/", $html);

 364      $html=strip_tags($html,$this->enabledtags); //remove all unsupported tags, but the ones inside the 'enabledtags' string

 365    //Explode the string in order to parse the HTML code

 366  
 367      $a=preg_split('/<(.*?)>/ms',$html,-1,PREG_SPLIT_DELIM_CAPTURE);
 368  
 369      foreach($a as $i => $e)
 370      {
 371           if($i%2==0)
 372          {
 373              //TEXT

 374  
 375              //Adjust lineheight

 376        //            $this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer?

 377              //Adjust text, if needed

 378              if (strpos($e,"&") !== false) //HTML-ENTITIES decoding
 379              {
 380          if (strpos($e,"#") !== false) $e = value_entity_decode($e); // Decode value entities

 381  
 382          //Avoid crashing the script on PHP 4.0

 383          $version = phpversion();
 384          $version = str_replace('.','',$version);
 385          if ($version >= 430) $e = html_entity_decode($e,ENT_QUOTES,'cp1252'); // changes &nbsp; and the like by their respective char

 386  
 387          else $e = lesser_entity_decode($e);
 388        }
 389  
 390        $e = str_replace(chr(160),chr(32),$e); //unify ascii code of spaces (in order to recognize all of them correctly)

 391  
 392        if (strlen($e) == 0) continue;
 393              if ($this->divrevert) $e = strrev($e);
 394              if ($this->toupper) $e = strtoupper($e);
 395              if ($this->tolower) $e = strtolower($e);
 396        //Start of 'if/elseif's

 397              if($this->titulo) $this->SetTitle($e);
 398          elseif($this->specialcontent)
 399              {
 400                  if ($this->specialcontent == "type=select" and $this->selectoption['ACTIVE'] == true) //SELECT tag (form element)
 401            {
 402               $stringwidth = $this->GetStringWidth($e);
 403               if (!isset($this->selectoption['MAXWIDTH']) or $stringwidth > $this->selectoption['MAXWIDTH']) $this->selectoption['MAXWIDTH'] = $stringwidth;
 404               if (!isset($this->selectoption['SELECTED']) or $this->selectoption['SELECTED'] == '') $this->selectoption['SELECTED'] = $e;
 405            }
 406            else $this->textbuffer[] = array("???"/*identifier*/.$this->specialcontent."???".$e);
 407        }
 408              elseif($this->tablestart)
 409              {
 410            if($this->tdbegin)
 411            {
 412                      $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);
 413                      $this->cell[$this->row][$this->col]['text'][] = $e;
 414              $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth($e);
 415                      }
 416                      //Ignore content between <table>,<tr> and a <td> tag (this content is usually only a bunch of spaces)

 417              }
 418              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

 419              else
 420              {
 421                  if ($this->blockjustfinished) $e = ltrim($e);
 422                  if ($e != '')
 423                  {
 424                 $this->Write($this->lineheight,$e); //Write text directly in the PDF

 425                 if ($this->pjustfinished) $this->pjustfinished = false;
 426            }
 427        }
 428          }
 429          else
 430          {
 431              //Tag

 432              if($e{0}=='/') $this->CloseTag(strtoupper(substr($e,1)));
 433              else
 434              {
 435          $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any

 436          $e = preg_replace($regexp,"=\"\$1\"",$e);
 437                  $regexp = '| (\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)

 438          $e = preg_replace($regexp," \$1=\"\$2\"",$e);
 439  
 440          //Fix path values, if needed

 441          if ((stristr($e,"href=") !== false) or (stristr($e,"src=") !== false) )
 442          {
 443              $regexp = '/ (href|src)="(.*?)"/i';
 444              preg_match($regexp,$e,$auxiliararray);
 445              $path = $auxiliararray[2];
 446              $path = str_replace("\\","/",$path); //If on Windows

 447              //Get link info and obtain its absolute path

 448              $regexp = '|^./|';
 449              $path = preg_replace($regexp,'',$path);
 450              if($path{0} != '#') //It is not an Internal Link
 451              { 
 452                if (strpos($path,"../") !== false ) //It is a Relative Link
 453                {
 454                    $backtrackamount = substr_count($path,"../");
 455                    $maxbacktrack = substr_count($this->basepath,"/") - 1;
 456                    $filepath = str_replace("../",'',$path);
 457                    $path = $this->basepath;
 458                    //If it is an invalid relative link, then make it go to directory root

 459                    if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
 460                    //Backtrack some directories

 461                    for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
 462                    $path = $path . "/" . $filepath; //Make it an absolute path

 463                }
 464                elseif( strpos($path,":/") === false) //It is a Local Link
 465                {
 466                  $path = $this->basepath . $path; 
 467                }
 468                //Do nothing if it is an Absolute Link

 469              }
 470              $regexp = '/ (href|src)="(.*?)"/i';
 471              $e = preg_replace($regexp,' \\1="'.$path.'"',$e);
 472          }//END of Fix path values

 473                  //Extract attributes

 474                  $contents=array();
 475          preg_match_all('/\\S*=["\'][^"\']*["\']/',$e,$contents);
 476          preg_match('/\\S+/',$e,$a2);
 477  
 478          $tag=strtoupper($a2[0]);
 479                  $attr=array();
 480                  if (!empty($contents))
 481                  {
 482                  foreach($contents[0] as $v)
 483                  {
 484                      if(ereg('^([^=]*)=["\']?([^"\']*)["\']?$',$v,$a3))
 485                          {
 486                              $attr[strtoupper($a3[1])]=$a3[2];
 487  
 488                          }
 489                  }
 490                  }
 491                  $this->OpenTag($tag,$attr);
 492              }
 493          }
 494      }//end of   foreach($a as $i=>$e)

 495      //Create Internal Links, if needed

 496    if (!empty($this->internallink) )
 497    {
 498      foreach($this->internallink as $k=>$v)
 499      {
 500        if (strpos($k,"#") !== false ) continue; //ignore

 501        $ypos = $v['Y'];
 502        $pagenum = $v['PAGE'];
 503        $sharp = "#";
 504        while (array_key_exists($sharp.$k,$this->internallink))
 505        {
 506           $internallink = $this->internallink[$sharp.$k];
 507           $this->SetLink($internallink,$ypos,$pagenum);
 508           $sharp .= "#";
 509        }
 510      }
 511    }
 512  }
 513  
 514  function OpenTag($tag,$attr)
 515  {
 516  //! @return void

 517  // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>

 518  
 519    $align = array('left'=>'L','center'=>'C','right'=>'R','top'=>'T','middle'=>'M','bottom'=>'B','justify'=>'J');
 520  
 521    $this->blockjustfinished=false;
 522      //Opening tag

 523      switch($tag){
 524        case 'PAGE_BREAK': //custom-tag
 525        case 'NEWPAGE': //custom-tag
 526              $this->blockjustfinished = true;
 527          $this->AddPage();
 528          break;
 529        case 'OUTLINE': //custom-tag (CSS2 property - browsers don't support it yet - Jan2005)
 530        //Usage: (default: width=normal color=white)

 531        //<outline width="(thin|medium|thick)" color="(usualcolorformat)" >Text</outline>

 532        //Mix this tag with the <font color="(usualcolorformat)"> tag to get mixed colors on outlined text!

 533          $this->buffer_on = true;
 534          if (isset($attr['COLOR'])) $this->outlineparam['COLOR'] = ConvertColor($attr['COLOR']);
 535          else $this->outlineparam['COLOR'] = array('R'=>255,'G'=>255,'B'=>255); //white

 536        $this->outlineparam['OLDWIDTH'] = $this->LineWidth;
 537          if (isset($attr['WIDTH']))
 538          {
 539             switch(strtoupper($attr['WIDTH']))
 540             {
 541                 case 'THIN': $this->outlineparam['WIDTH'] = 0.75*$this->LineWidth; break;
 542                 case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth; break;
 543                 case 'THICK': $this->outlineparam['WIDTH'] = 1.75*$this->LineWidth; break;
 544           }
 545        }
 546        else $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth

 547          break;
 548        case 'BDO':
 549        if (isset($attr['DIR']) and (strtoupper($attr['DIR']) == 'RTL' )) $this->divrevert = true;
 550          break;
 551        case 'S':
 552        case 'STRIKE':
 553        case 'DEL':
 554          $this->strike=true;
 555          break;
 556          case 'SUB':
 557            $this->SUB=true;
 558            break;
 559          case 'SUP':
 560            $this->SUP=true;
 561        break;
 562      case 'CENTER':
 563        $this->buffer_on = true;
 564        if ($this->tdbegin)   $this->cell[$this->row][$this->col]['a'] = $align['center'];
 565        else 
 566        {
 567              $this->divalign = $align['center'];
 568          if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
 569        }
 570        break;
 571      case 'ADDRESS': 
 572        $this->buffer_on = true;
 573          $this->SetStyle('I',true);
 574        if (!$this->tdbegin and $this->x != $this->lMargin) $this->Ln($this->lineheight);
 575        break;
 576          case 'TABLE': // TABLE-BEGIN
 577          if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
 578        $this->tablestart = true;
 579          $this->table['nc'] = $this->table['nr'] = 0;
 580          if (isset($attr['REPEAT_HEADER']) and $attr['REPEAT_HEADER'] == true) $this->UseTableHeader(true);
 581              if (isset($attr['WIDTH'])) $this->table['w']    = ConvertSize($attr['WIDTH'],$this->pgwidth);
 582              if (isset($attr['HEIGHT'])) $this->table['h']   = ConvertSize($attr['HEIGHT'],$this->pgwidth);
 583              if (isset($attr['ALIGN']))  $this->table['a']   = $align[strtolower($attr['ALIGN'])];
 584              if (isset($attr['BORDER'])) $this->table['border']  = $attr['BORDER'];
 585              if (isset($attr['BGCOLOR'])) $this->table['bgcolor'][-1]    = $attr['BGCOLOR'];
 586              break;
 587          case 'TR':
 588              $this->row++;
 589              $this->table['nr']++;
 590              $this->col = -1;
 591              if (isset($attr['BGCOLOR']))$this->table['bgcolor'][$this->row] = $attr['BGCOLOR'];
 592          break;
 593          case 'TH':
 594              $this->SetStyle('B',true);
 595          if (!isset($attr['ALIGN'])) $attr['ALIGN'] = "center";
 596          case 'TD':
 597            $this->tdbegin = true;
 598              $this->col++;
 599        while (isset($this->cell[$this->row][$this->col])) $this->col++;
 600              //Update number column

 601          if ($this->table['nc'] < $this->col+1) $this->table['nc'] = $this->col+1;
 602              $this->cell[$this->row][$this->col] = array();
 603              $this->cell[$this->row][$this->col]['text'] = array();
 604              $this->cell[$this->row][$this->col]['s'] = 3;
 605              if (isset($attr['WIDTH'])) $this->cell[$this->row][$this->col]['w'] = ConvertSize($attr['WIDTH'],$this->pgwidth);
 606              if (isset($attr['HEIGHT'])) $this->cell[$this->row][$this->col]['h']    = ConvertSize($attr['HEIGHT'],$this->pgwidth);
 607              if (isset($attr['ALIGN'])) $this->cell[$this->row][$this->col]['a'] = $align[strtolower($attr['ALIGN'])];
 608              if (isset($attr['VALIGN'])) $this->cell[$this->row][$this->col]['va'] = $align[strtolower($attr['VALIGN'])];
 609              if (isset($attr['BORDER'])) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
 610              if (isset($attr['BGCOLOR'])) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR'];
 611              $cs = $rs = 1;
 612              if (isset($attr['COLSPAN']) && $attr['COLSPAN']>1)  $cs = $this->cell[$this->row][$this->col]['colspan']    = $attr['COLSPAN'];
 613              if (isset($attr['ROWSPAN']) && $attr['ROWSPAN']>1)  $rs = $this->cell[$this->row][$this->col]['rowspan']    = $attr['ROWSPAN'];
 614              //Chiem dung vi tri de danh cho cell span (?mais hein?)

 615              for ($k=$this->row ; $k < $this->row+$rs ;$k++)
 616          for($l=$this->col; $l < $this->col+$cs ;$l++)
 617          {
 618                  if ($k-$this->row || $l-$this->col) $this->cell[$k][$l] = 0;
 619              }
 620              if (isset($attr['NOWRAP'])) $this->cell[$this->row][$this->col]['nowrap']= 1;
 621          break;
 622          case 'OL':
 623        if ( !isset($attr['TYPE']) or $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1'

 624        else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here

 625          case 'UL':
 626        if ( (!isset($attr['TYPE']) or $attr['TYPE'] == '') and $tag=='UL')
 627        {
 628           //Insert UL defaults

 629           if ($this->listlvl == 0) $this->listtype = 'disc';
 630           elseif ($this->listlvl == 1) $this->listtype = 'circle';
 631           else $this->listtype = 'square';
 632        }
 633        elseif (isset($attr['TYPE']) and $tag=='UL') $this->listtype = $attr['TYPE'];
 634        $this->buffer_on = false;
 635        if ($this->listlvl == 0)
 636        {
 637          //First of all, skip a line

 638          if (!$this->pjustfinished)
 639          {
 640              if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
 641              $this->Ln($this->lineheight);
 642          }
 643          $this->oldx = $this->x;
 644          $this->listlvl++; // first depth level

 645          $this->listnum = 0; // reset

 646          $this->listoccur[$this->listlvl] = 1;
 647          $this->listlist[$this->listlvl][1] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
 648        }
 649        else
 650        {
 651          if (!empty($this->textbuffer))
 652          {
 653            $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
 654            $this->listnum++;
 655          }
 656            $this->textbuffer = array();
 657            $occur = $this->listoccur[$this->listlvl];
 658          $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum

 659          $this->listlvl++;
 660          $this->listnum = 0; // reset

 661  
 662          if ($this->listoccur[$this->listlvl] == 0) $this->listoccur[$this->listlvl] = 1;
 663          else $this->listoccur[$this->listlvl]++;
 664            $occur = $this->listoccur[$this->listlvl];
 665          $this->listlist[$this->listlvl][$occur] = array('TYPE'=>$this->listtype,'MAXNUM'=>$this->listnum);
 666        }
 667        break;
 668          case 'LI':
 669            //Observation: </LI> is ignored

 670        if ($this->listlvl == 0) //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
 671        {
 672          //First of all, skip a line

 673          if (!$this->pjustfinished and $this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
 674          $this->oldx = $this->x;
 675          $this->listlvl++; // first depth level

 676          $this->listnum = 0; // reset

 677          $this->listoccur[$this->listlvl] = 1;
 678          $this->listlist[$this->listlvl][1] = array('TYPE'=>'disc','MAXNUM'=>$this->listnum);
 679        }
 680        if ($this->listnum == 0)
 681        {
 682          $this->buffer_on = true; //activate list 'bufferization'

 683          $this->listnum++;
 684            $this->textbuffer = array();
 685        }
 686        else
 687        {
 688          $this->buffer_on = true; //activate list 'bufferization'

 689          if (!empty($this->textbuffer))
 690          {
 691            $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
 692            $this->listnum++;
 693          }
 694            $this->textbuffer = array();
 695        }
 696        break;
 697          case 'H1': // 2 * fontsize
 698          case 'H2': // 1.5 * fontsize
 699          case 'H3': // 1.17 * fontsize
 700          case 'H4': // 1 * fontsize
 701          case 'H5': // 0.83 * fontsize
 702          case 'H6': // 0.67 * fontsize
 703          //Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html

 704            if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
 705        $this->buffer_on = true;
 706              if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
 707              elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
 708              $this->SetStyle('B',true);
 709        switch($tag)
 710        {
 711            case 'H1': 
 712                $this->SetFontSize(2*$this->FontSizePt); 
 713                $this->lineheight *= 2;
 714                break;
 715            case 'H2': 
 716                $this->SetFontSize(1.5*$this->FontSizePt); 
 717                $this->lineheight *= 1.5;
 718                break;
 719            case 'H3':
 720                $this->SetFontSize(1.17*$this->FontSizePt);
 721                $this->lineheight *= 1.17;
 722                break;
 723            case 'H4':
 724                $this->SetFontSize($this->FontSizePt); 
 725                break;
 726            case 'H5': 
 727                $this->SetFontSize(0.83*$this->FontSizePt); 
 728                $this->lineheight *= 0.83;
 729                break;
 730            case 'H6': 
 731                $this->SetFontSize(0.67*$this->FontSizePt); 
 732                $this->lineheight *= 0.67;
 733                break;
 734        }
 735            break;
 736          case 'HR': //Default values: width=100% align=center color=gray
 737            //Skip a line, if needed

 738              if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
 739              $this->Ln(0.2*$this->lineheight);
 740            $hrwidth = $this->pgwidth;
 741            $hralign = 'C';
 742            $hrcolor = array('R'=>200,'G'=>200,'B'=>200);
 743            if($attr['WIDTH'] != '') $hrwidth = ConvertSize($attr['WIDTH'],$this->pgwidth);
 744            if($attr['ALIGN'] != '') $hralign = $align[strtolower($attr['ALIGN'])];
 745            if($attr['COLOR'] != '') $hrcolor = ConvertColor($attr['COLOR']);
 746        $this->SetDrawColor($hrcolor['R'],$hrcolor['G'],$hrcolor['B']);
 747        $x = $this->x;
 748        $y = $this->y;
 749        switch($hralign)
 750        {
 751            case 'L':
 752            case 'J':
 753                break;
 754            case 'C':
 755                $empty = $this->pgwidth - $hrwidth;
 756                $empty /= 2;
 757                $x += $empty;
 758                break;
 759            case 'R':
 760                $empty = $this->pgwidth - $hrwidth;
 761                $x += $empty;
 762                break;
 763        }
 764        $oldlinewidth = $this->LineWidth;
 765              $this->SetLineWidth(0.3);
 766              $this->Line($x,$y,$x+$hrwidth,$y);
 767              $this->SetLineWidth($oldlinewidth);
 768              $this->Ln(0.2*$this->lineheight);
 769            $this->SetDrawColor(0);
 770        $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

 771              break;
 772          case 'INS':
 773              $this->SetStyle('U',true);
 774            break;
 775          case 'SMALL':
 776            $newsize = $this->FontSizePt - 1;
 777            $this->SetFontSize($newsize);
 778            break;
 779          case 'BIG':
 780            $newsize = $this->FontSizePt + 1;
 781            $this->SetFontSize($newsize);
 782          case 'STRONG':
 783              $this->SetStyle('B',true);
 784              break;
 785          case 'CITE':
 786          case 'EM':
 787              $this->SetStyle('I',true);
 788              break;
 789          case 'TITLE':
 790              $this->titulo = true;
 791              break;
 792          case 'B':
 793          case 'I':
 794          case 'U':
 795              if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
 796        {
 797              $this->cssbegin=true;
 798                  if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
 799                  elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
 800                  //Read Inline CSS

 801                  if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
 802                  //Look for name in the $this->CSS array

 803                  $this->backupcss = $properties;
 804                  if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!

 805            }
 806              $this->SetStyle($tag,true);
 807              break;
 808          case 'A':
 809        if (isset($attr['NAME']) and $attr['NAME'] != '') $this->textbuffer[] = array('','','',array(),'',false,false,$attr['NAME']); //an internal link (adds a space for recognition)

 810              if (isset($attr['HREF'])) $this->HREF=$attr['HREF'];
 811              break;
 812          case 'DIV':
 813        //in case of malformed HTML code. Example:(...)</div><li>Content</li><div>DIV1</div>(...)

 814        if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
 815        {
 816              $this->buffer_on = false;
 817            if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
 818              $this->textbuffer = array();
 819              $this->listlvl--;
 820              $this->printlistbuffer();
 821              $this->pjustfinished = true; //act as if a paragraph just ended

 822        }
 823              $this->divbegin=true;
 824        if ($this->x != $this->lMargin)   $this->Ln($this->lineheight);
 825              if( isset($attr['ALIGN']) and  $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower($attr['ALIGN'])];
 826              if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
 827        {
 828              $this->cssbegin=true;
 829                  if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
 830                  elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
 831                  //Read Inline CSS

 832                  if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
 833                  //Look for name in the $this->CSS array

 834                  if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!

 835            }
 836              break;
 837          case 'IMG':
 838  
 839                     if(!empty($this->textbuffer) and !$this->tablestart)
 840            {
 841              //Output previously buffered content and output image below

 842          //Set some default values

 843  
 844          $olddivwidth = $this->divwidth;
 845          $olddivheight = $this->divheight;
 846          if ( $this->divwidth == 0) $this->divwidth = $this->pgwidth - $x + $this->lMargin;
 847          if ( $this->divheight == 0) $this->divheight = $this->lineheight;
 848          //Print content

 849            $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
 850          $this->textbuffer=array(); 
 851          //Reset values

 852          $this->divwidth = $olddivwidth;
 853          $this->divheight = $olddivheight;
 854              $this->textbuffer=array();
 855              $this->Ln($this->lineheight);
 856        }
 857              if(isset($attr['SRC']))
 858        {
 859            $srcpath = $attr['SRC'];
 860  
 861                      $srcpath = str_replace ("resized%2F", "", $srcpath);
 862                  if(!isset($attr['WIDTH'])) $attr['WIDTH'] = 0;
 863                    else $attr['WIDTH'] = ConvertSize($attr['WIDTH'],$this->pgwidth);//$attr['WIDTH'] /= 4;

 864                    if(!isset($attr['HEIGHT']))   $attr['HEIGHT'] = 0;
 865                    else $attr['HEIGHT'] = ConvertSize($attr['HEIGHT'],$this->pgwidth);//$attr['HEIGHT'] /= 4;

 866                    if ($this->tdbegin) 
 867                    {
 868                    $bak_x = $this->x;
 869              $bak_y = $this->y;
 870  
 871              //Check whether image exists locally or on the URL

 872              $f_exists = @fopen($srcpath,"rb");
 873  
 874              if (!$f_exists) //Show 'image not found' icon instead
 875              {
 876                  if(!$this->shownoimg) break;
 877                  $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
 878                  $srcpath .= 'no_img.gif';
 879              }
 880              $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
 881  
 882              $this->y = $bak_y;
 883              $this->x = $bak_x;
 884            }
 885                    elseif($this->pbegin or $this->divbegin)
 886                    {
 887              //In order to support <div align='center'><img ...></div>

 888              $ypos = 0;
 889                    $bak_x = $this->x;
 890              $bak_y = $this->y;
 891              //Check whether image exists locally or on the URL

 892              $f_exists = @fopen($srcpath,"rb");
 893  
 894              if (!$f_exists) //Show 'image not found' icon instead
 895              {
 896                  if(!$this->shownoimg) break;
 897                  $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
 898                  $srcpath .= 'no_img.gif';
 899              }
 900              $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'','',false);
 901              $this->y = $bak_y;
 902              $this->x = $bak_x;
 903              $xpos = '';
 904              switch($this->divalign)
 905              {
 906                  case "C":
 907                       $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
 908                       $empty = ($this->pgwidth - $sizesarray['WIDTH'])/2;
 909                       $xpos = 'xpos='.$empty.',';
 910                       break;
 911                  case "R":
 912                       $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
 913                       $empty = ($this->pgwidth - $sizesarray['WIDTH']);
 914                       $xpos = 'xpos='.$empty.',';
 915                       break;
 916                  default: break;
 917              }
 918                      $numberoflines = (integer)ceil($sizesarray['HEIGHT']/$this->lineheight) ;
 919                      $ypos = $numberoflines * $this->lineheight;
 920                      $this->textbuffer[] = array("???"/*identifier*/."type=image,ypos=$ypos,{$xpos}width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."???".$sizesarray['OUTPUT']);
 921              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--;}
 922            }
 923            else
 924            {
 925              $imgborder = 0;
 926              if (isset($attr['BORDER'])) $imgborder = ConvertSize($attr['BORDER'],$this->pgwidth);
 927              //Check whether image exists locally or on the URL

 928              $f_exists = @fopen($srcpath,"rb");
 929  
 930              if (!$f_exists) //Show 'image not found' icon instead
 931              {
 932                  $srcpath = str_replace("\\","/",dirname(__FILE__)) . "/";
 933                  $srcpath .= 'no_img.gif';
 934              }
 935              $sizesarray = $this->Image($srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'],'',$this->HREF); //Output Image

 936                    $ini_x = $sizesarray['X'];
 937              $ini_y = $sizesarray['Y'];
 938              if ($imgborder)
 939              {
 940                  $oldlinewidth = $this->LineWidth;
 941                        $this->SetLineWidth($imgborder);
 942                  $this->Rect($ini_x,$ini_y,$sizesarray['WIDTH'],$sizesarray['HEIGHT']);
 943                        $this->SetLineWidth($oldlinewidth);
 944              }
 945            }
 946                  if ($sizesarray['X'] < $this->x) $this->x = $this->lMargin;
 947                  if ($this->tablestart)
 948                  {
 949                      $this->cell[$this->row][$this->col]['textbuffer'][] = array("???"/*identifier*/."type=image,width=".$sizesarray['WIDTH'].",height=".$sizesarray['HEIGHT']."???".$sizesarray['OUTPUT']);
 950              $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1;// +1 == margin

 951              $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later

 952              if (!isset($this->cell[$this->row][$this->col]['w'])) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
 953              if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
 954                  }
 955              }
 956              break;
 957          case 'BLOCKQUOTE':
 958          case 'BR':
 959            if($this->tablestart)
 960            {
 961              $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);
 962          $this->cell[$this->row][$this->col]['text'][] = "\n";
 963          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

 964          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

 965          $this->cell[$this->row][$this->col]['s'] = 0;// reset

 966        }
 967              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);
 968              else {$this->Ln($this->lineheight);$this->blockjustfinished = true;}
 969              break;
 970          case 'P':
 971        //in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)

 972        if ($this->listlvl > 0) // We are closing (omitted) OL/UL tag(s)
 973        {
 974              $this->buffer_on = false;
 975            if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
 976              $this->textbuffer = array();
 977              $this->listlvl--;
 978              $this->printlistbuffer();
 979              $this->pjustfinished = true; //act as if a paragraph just ended

 980        }
 981        if ($this->tablestart)
 982        {
 983            $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);
 984            $this->cell[$this->row][$this->col]['text'][] = "\n";
 985            break;
 986        }
 987            $this->pbegin=true;
 988              if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
 989              elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
 990            //Save x,y coords in case we need to print borders...

 991            $this->oldx = $this->x;
 992            $this->oldy = $this->y;
 993              if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
 994              if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
 995        {
 996              $this->cssbegin=true;
 997                  if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
 998                  elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
 999                  //Read Inline CSS

1000                  if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
1001                  //Look for name in the $this->CSS array

1002                  $this->backupcss = $properties;
1003                  if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!

1004            }
1005              break;
1006          case 'SPAN':
1007            $this->buffer_on = true;
1008            //Save x,y coords in case we need to print borders...

1009            $this->oldx = $this->x;
1010            $this->oldy = $this->y;
1011              if( isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
1012        {
1013              $this->cssbegin=true;
1014                  if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
1015                  elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
1016                  //Read Inline CSS

1017                  if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
1018                  //Look for name in the $this->CSS array

1019                  $this->backupcss = $properties;
1020                  if (!empty($properties)) $this->setCSS($properties); //name found in the CSS array!

1021            }
1022        break;
1023          case 'PRE':
1024            if($this->tablestart)
1025            {
1026              $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);
1027          $this->cell[$this->row][$this->col]['text'][] = "\n";
1028        }
1029              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);
1030        else
1031        {
1032          if ($this->x != $this->lMargin) $this->Ln(2*$this->lineheight);
1033                elseif (!$this->pjustfinished) $this->Ln($this->lineheight);
1034              $this->buffer_on = true;
1035              //Save x,y coords in case we need to print borders...

1036              $this->oldx = $this->x;
1037              $this->oldy = $this->y;
1038                if(isset($attr['ALIGN'])) $this->divalign = $align[strtolower($attr['ALIGN'])];
1039                if(isset($attr['CLASS']) or isset($attr['ID']) or isset($attr['STYLE']) )
1040          {
1041                  $this->cssbegin=true;
1042              if (isset($attr['CLASS'])) $properties = $this->CSS[$attr['CLASS']];
1043                      elseif (isset($attr['ID'])) $properties = $this->CSS[$attr['ID']];
1044                      //Read Inline CSS

1045                      if (isset($attr['STYLE'])) $properties = $this->readInlineCSS($attr['STYLE']);
1046                      //Look for name in the $this->CSS array

1047                      $this->backupcss = $properties;
1048                      if (!empty($properties)) $this->setCSS($properties); //name(id/class/style) found in the CSS array!

1049            }
1050              }
1051      case 'TT':
1052      case 'KBD':
1053      case 'SAMP':
1054          case 'CODE':
1055              $this->SetFont('courier');
1056          $this->currentfont='courier';
1057            break;
1058          case 'TEXTAREA':
1059            $this->buffer_on = true;
1060        $colsize = 20; //HTML default value 

1061        $rowsize = 2; //HTML default value

1062          if (isset($attr['COLS'])) $colsize = $attr['COLS'];
1063          if (isset($attr['ROWS'])) $rowsize = $attr['ROWS'];
1064          if (!$this->tablestart)
1065          {
1066              if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
1067              $this->col = $colsize;
1068              $this->row = $rowsize;
1069            }
1070            else //it is inside a table
1071            {
1072            $this->specialcontent = "type=textarea,lines=$rowsize,width=".((2.2*$colsize) + 3); //Activate form info in order to paint FORM elements within table

1073          $this->cell[$this->row][$this->col]['s'] += (2.2*$colsize) + 6;// +6 == margin

1074          if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = 1.1*$this->lineheight*$rowsize + 2.5;
1075        }
1076            break;
1077          case 'SELECT':
1078            $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table

1079            break;
1080          case 'OPTION':
1081        $this->selectoption['ACTIVE'] = true;
1082            if (empty($this->selectoption))
1083        {
1084            $this->selectoption['MAXWIDTH'] = '';
1085          $this->selectoption['SELECTED'] = '';
1086        }
1087        if (isset($attr['SELECTED'])) $this->selectoption['SELECTED'] = '';
1088            break;
1089          case 'FORM':
1090            if($this->tablestart)
1091            {
1092              $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);
1093          $this->cell[$this->row][$this->col]['text'][] = "\n";
1094        }
1095            elseif ($this->x != $this->lMargin) $this->Ln($this->lineheight); //Skip a line, if needed

1096            break;
1097      case 'INPUT':
1098        if (!isset($attr['TYPE'])) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)

1099        if (!$this->tablestart)
1100        {
1101          switch(strtoupper($attr['TYPE'])){
1102            case 'CHECKBOX': //Draw Checkbox
1103                  $checked = false;
1104                  if (isset($attr['CHECKED'])) $checked = true;
1105                        $this->SetFillColor(235,235,235);
1106                        $this->x += 3;
1107                  $this->Rect($this->x,$this->y+1,3,3,'DF');
1108                  if ($checked) 
1109                  {
1110                    $this->Line($this->x,$this->y+1,$this->x+3,$this->y+1+3);
1111                    $this->Line($this->x,$this->y+1+3,$this->x+3,$this->y+1);
1112                  }
1113                        $this->SetFillColor(255);
1114                        $this->x += 3.5;
1115                  break;
1116            case 'RADIO': //Draw Radio button
1117                  $checked = false;
1118                  if (isset($attr['CHECKED'])) $checked = true;
1119                  $this->x += 4;
1120                  $this->Circle($this->x,$this->y+2.2,1,'D');
1121                  $this->_out('0.000 g');
1122                  if ($checked) $this->Circle($this->x,$this->y+2.2,0.4,'DF');
1123                  $this->Write(5,$texto,$this->x);
1124                  $this->x += 2;
1125                  break;
1126            case 'BUTTON': // Draw a button
1127            case 'SUBMIT':
1128            case 'RESET':
1129                  $texto='';
1130                  if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
1131                  $nihil = 2.5;
1132                  $this->x += 2;
1133                        $this->SetFillColor(190,190,190);
1134                  $this->Rect($this->x,$this->y,$this->GetStringWidth($texto)+2*$nihil,4.5,'DF'); // 4.5 in order to avoid overlapping

1135                        $this->x += $nihil;
1136                  $this->Write(5,$texto,$this->x);
1137                        $this->x += $nihil;
1138                        $this->SetFillColor(255);
1139                  break;
1140            case 'PASSWORD':
1141                  if (isset($attr['VALUE']))
1142                  {
1143                      $num_stars = strlen($attr['VALUE']);
1144                      $attr['VALUE'] = str_repeat('*',$num_stars);
1145                  }
1146            case 'TEXT': //Draw TextField
1147            default: //default == TEXT
1148                  $texto='';
1149                  if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
1150                  $tamanho = 20;
1151                  if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
1152                        $this->SetFillColor(235,235,235);
1153                  $this->x += 2;
1154                  $this->Rect($this->x,$this->y,2*$tamanho,4.5,'DF');// 4.5 in order to avoid overlapping

1155                  if ($texto != '')
1156                  {
1157                    $this->x += 1;
1158                    $this->Write(5,$texto,$this->x);
1159                    $this->x -= $this->GetStringWidth($texto);
1160                  }
1161                      $this->SetFillColor(255);
1162                      $this->x += 2*$tamanho;
1163                  break;
1164          }
1165        }
1166        else //we are inside a table
1167        {
1168          $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later

1169          $type = '';
1170          $text = '';
1171          $height = 0;
1172          $width = 0;
1173          switch(strtoupper($attr['TYPE'])){
1174            case 'CHECKBOX': //Draw Checkbox
1175                  $checked = false;
1176                  if (isset($attr['CHECKED'])) $checked = true;
1177                  $text = $checked;
1178                  $type = 'CHECKBOX';
1179                  $width = 4;
1180                      $this->cell[$this->row][$this->col]['textbuffer'][] = array("???"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."???".$text);
1181                  $this->cell[$this->row][$this->col]['s'] += $width;
1182                  if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
1183                  break;
1184            case 'RADIO': //Draw Radio button
1185                  $checked = false;
1186                  if (isset($attr['CHECKED'])) $checked = true;
1187                  $text = $checked;
1188                  $type = 'RADIO';
1189                  $width = 3;
1190                  $this->cell[$this->row][$this->col]['textbuffer'][] = array("???"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."???".$text);
1191                  $this->cell[$this->row][$this->col]['s'] += $width;
1192                  if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
1193                  break;
1194            case 'BUTTON': $type = 'BUTTON'; // Draw a button

1195            case 'SUBMIT': if ($type == '') $type = 'SUBMIT';
1196            case 'RESET': if ($type == '') $type = 'RESET';
1197                  $texto='';
1198                  if (isset($attr['VALUE'])) $texto = " " . $attr['VALUE'] . " ";
1199                  $text = $texto;
1200                  $width = $this->GetStringWidth($texto)+3;
1201                  $this->cell[$this->row][$this->col]['textbuffer'][] = array("???"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."???".$text);
1202                  $this->cell[$this->row][$this->col]['s'] += $width;
1203                  if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1204                  break;
1205            case 'PASSWORD':
1206                  if (isset($attr['VALUE']))
1207                  {
1208                      $num_stars = strlen($attr['VALUE']);
1209                      $attr['VALUE'] = str_repeat('*',$num_stars);
1210                  }
1211                  $type = 'PASSWORD';
1212            case 'TEXT': //Draw TextField
1213            default: //default == TEXT
1214                  $texto='';
1215                  if (isset($attr['VALUE'])) $texto = $attr['VALUE'];
1216                  $tamanho = 20;
1217                  if (isset($attr['SIZE']) and ctype_digit($attr['SIZE']) ) $tamanho = $attr['SIZE'];
1218                  $text = $texto;
1219                  $width = 2*$tamanho;
1220                  if ($type == '') $type = 'TEXT';
1221                  $this->cell[$this->row][$this->col]['textbuffer'][] = array("???"/*identifier*/."type=input,subtype=$type,width=$width,height=$height"."???".$text);
1222                  $this->cell[$this->row][$this->col]['s'] += $width;
1223                  if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1224                  break;
1225          }
1226        }
1227        break;
1228          case 'FONT':
1229  //Font size is ignored for now

1230              if (isset($attr['COLOR']) and $attr['COLOR']!='')
1231        {
1232                  $cor = ConvertColor($attr['COLOR']);
1233                  //If something goes wrong switch color to black

1234                $cor['R'] = (isset($cor['R'])?$cor['R']:0);
1235          $cor['G'] = (isset($cor['G'])?$cor['G']:0);
1236          $cor['B'] = (isset($cor['B'])?$cor['B']:0);
1237                $this->colorarray = $cor;
1238                  $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
1239                  $this->issetcolor = true;
1240              }
1241              if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist))
1242        {
1243                  $this->SetFont(strtolower($attr['FACE']));
1244                  $this->issetfont=true;
1245              }
1246              //'If' disabled in this version due lack of testing (you may enable it if you want)

1247  //          if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') {

1248  //              $this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);

1249  //              $this->issetfont=true;

1250  //          }

1251              break;
1252      }//end of switch

1253    $this->pjustfinished=false;
1254  }
1255  
1256  function CloseTag($tag)
1257  {
1258  //! @return void

1259      //Closing tag

1260      if($tag=='OPTION') $this->selectoption['ACTIVE'] = false;
1261      if($tag=='BDO') $this->divrevert = false;
1262      if($tag=='INS') $tag='U';
1263      if($tag=='STRONG') $tag='B';
1264      if($tag=='EM' or $tag=='CITE') $tag='I';
1265    if($tag=='OUTLINE')
1266    {
1267        if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1268        {
1269        //Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer

1270        //if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']);

1271        $this->SetTextOutline(false);
1272        $this->outlineparam=array();
1273        //Save x,y coords ???

1274        $x = $this->x;
1275        $y = $this->y;
1276        //Set some default values

1277        $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1278        //Print content

1279        $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
1280        $this->textbuffer=array(); 
1281          //Reset values

1282          $this->Reset();
1283        $this->buffer_on=false;
1284      }
1285      $this->SetTextOutline(false);
1286      $this->outlineparam=array();
1287    }
1288      if($tag=='A')
1289      {
1290        if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on)
1291        {
1292         //Deactivate $this->HREF for its info is already stored inside $this->textbuffer

1293         $this->HREF='';
1294         //Save x,y coords ???

1295         $x = $this->x;
1296         $y = $this->y;
1297         //Set some default values

1298         $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1299         //Print content

1300         $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
1301         $this->textbuffer=array();
1302         //Reset values

1303         $this->Reset();
1304      }
1305      $this->HREF=''; 
1306    }
1307      if($tag=='TH') $this->SetStyle('B',false);
1308      if($tag=='TH' or $tag=='TD') $this->tdbegin = false;
1309      if($tag=='SPAN')
1310      {
1311      if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1312      {
1313        if($this->cssbegin)
1314        {
1315            //Check if we have borders to print

1316            if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
1317            {
1318                $texto=''; 
1319                foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
1320                $tempx = $this->x;
1321                if($this->divbgcolor) $this->Cell($this->GetStringWidth($texto),$this->lineheight,'',$this->divborder,'','L',$this->divbgcolor);
1322                if ($this->dash_on) $this->Rect($this->oldx,$this->oldy,$this->GetStringWidth($texto),$this->lineheight);
1323                    if ($this->dotted_on) $this->DottedRect($this->x - $this->GetStringWidth($texto),$this->y,$this->GetStringWidth($texto),$this->lineheight);
1324                $this->x = $tempx;
1325                $this->x -= 1; //adjust alignment

1326            }
1327                $this->cssbegin=false;
1328                $this->backupcss=array();
1329        }
1330        //Save x,y coords ???

1331        $x = $this->x;
1332        $y = $this->y;
1333        //Set some default values

1334        $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1335        //Print content

1336        $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
1337        $this->textbuffer=array(); 
1338          //Reset values

1339          $this->Reset();
1340      }
1341      $this->buffer_on=false;
1342    }
1343      if($tag=='P' or $tag=='DIV') //CSS in BLOCK mode
1344      {
1345     $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1346       if(!$this->tablestart)
1347     {
1348      if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
1349      if ($tag=='P') 
1350      {
1351        $this->pbegin=false;
1352        $this->pjustfinished=true;
1353      }
1354      else $this->divbegin=false;
1355      $content='';
1356      foreach($this->textbuffer as $aux) $content .= $aux[0];
1357      $numlines = $this->WordWrap($content,$this->divwidth);
1358      if ($this->divheight == 0) $this->divheight = $numlines * 5;
1359      //Print content

1360        $this->printbuffer($this->textbuffer);
1361      $this->textbuffer=array();
1362      if ($tag=='P') $this->Ln($this->lineheight);
1363     }//end of 'if (!this->tablestart)'

1364     //Reset values

1365       $this->Reset();
1366       $this->cssbegin=false;
1367       $this->backupcss=array();
1368    }
1369      if($tag=='TABLE') { // TABLE-END 
1370      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1371          $this->table['cells'] = $this->cell;
1372          $this->table['wc'] = array_pad(array(),$this->table['nc'],array('miw'=>0,'maw'=>0));
1373          $this->table['hr'] = array_pad(array(),$this->table['nr'],0);
1374          $this->_tableColumnWidth($this->table);
1375          $this->_tableWidth($this->table);
1376          $this->_tableHeight($this->table);
1377  
1378      //Output table on PDF

1379          $this->_tableWrite($this->table);
1380          
1381      //Reset values

1382      $this->tablestart=false; //bool

1383      $this->table=array(); //array

1384      $this->cell=array(); //array 

1385      $this->col=-1; //int

1386      $this->row=-1; //int

1387      $this->Reset();
1388          $this->Ln(0.5*$this->lineheight);
1389      }
1390      if(($tag=='UL') or ($tag=='OL')) {
1391     if ($this->buffer_on == false) $this->listnum--;//Adjust minor BUG (this happens when there are two </OL> together)

1392        if ($this->listlvl == 1) // We are closing the last OL/UL tag
1393        {
1394         $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1395           $this->buffer_on = false;
1396         if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
1397           $this->textbuffer = array();
1398           $this->listlvl--;
1399           $this->printlistbuffer();
1400      }
1401      else // returning one level
1402      {
1403         if (!empty($this->textbuffer)) $this->listitem[] = array($this->listlvl,$this->listnum,$this->textbuffer,$this->listoccur[$this->listlvl]);
1404           $this->textbuffer = array();
1405           $occur = $this->listoccur[$this->listlvl]; 
1406         $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum

1407           $this->listlvl--;
1408           $occur = $this->listoccur[$this->listlvl];
1409           $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number

1410           $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type

1411         $this->buffer_on = false;
1412      }
1413    }
1414      if($tag=='H1' or $tag=='H2' or $tag=='H3' or $tag=='H4' or $tag=='H5' or $tag=='H6')
1415        {
1416        $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1417        if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1418        {
1419          //These 2 codelines are useless?

1420          $texto=''; 
1421          foreach($this->textbuffer as $vetor) $texto.=$vetor[0];
1422          //Save x,y coords ???

1423          $x = $this->x;
1424          $y = $this->y;
1425          //Set some default values

1426          $this->divwidth = $this->pgwidth;
1427          //Print content

1428            $this->printbuffer($this->textbuffer);
1429          $this->textbuffer=array(); 
1430              if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
1431          //Reset values

1432          $this->Reset();
1433        }
1434      $this->buffer_on=false;
1435      $this->lineheight = 5;
1436          $this->Ln($this->lineheight);
1437      $this->SetFontSize(11);
1438          $this->SetStyle('B',false);
1439    }
1440      if($tag=='TITLE')   {$this->titulo=false; $this->blockjustfinished = true;}
1441      if($tag=='FORM') $this->Ln($this->lineheight);
1442      if($tag=='PRE')
1443    {
1444        if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1445        {
1446          if ($this->divwidth == 0) $this->divwidth = $this->pgwidth;
1447          $content='';
1448          foreach($this->textbuffer as $aux) $content .= $aux[0];
1449          $numlines = $this->WordWrap($content,$this->divwidth);
1450          if ($this->divheight == 0) $this->divheight = $numlines * 5;
1451          //Print content

1452          $this->textbuffer[0][0] = ltrim($this->textbuffer[0][0]); //Remove exceeding left-side space

1453          $this->printbuffer($this->textbuffer);
1454          $this->textbuffer=array();
1455              if ($this->x != $this->lMargin) $this->Ln($this->lineheight);
1456          //Reset values

1457          $this->Reset();
1458          $this->Ln(1.1*$this->lineheight);
1459        }
1460            if($this->tablestart)
1461            {
1462              $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);
1463          $this->cell[$this->row][$this->col]['text'][] = "\n";
1464        }
1465              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);
1466        $this->cssbegin=false;
1467          $this->backupcss=array();
1468        $this->buffer_on = false;
1469        $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1470        $this->pjustfinished = true; //behaves the same way

1471    }
1472      if($tag=='CODE' or $tag=='PRE' or $tag=='TT' or $tag=='KBD' or $tag=='SAMP')
1473    {
1474       $this->currentfont='';
1475       $this->SetFont('arial');
1476      }
1477      if($tag=='B' or $tag=='I' or $tag=='U') 
1478      {
1479        $this->SetStyle($tag,false);
1480        if ($this->cssbegin and !$this->divbegin and !$this->pbegin and !$this->buffer_on)
1481        {
1482        //Reset values

1483          $this->Reset();
1484            $this->cssbegin=false;
1485          $this->backupcss=array();
1486          }
1487      }
1488      if($tag=='TEXTAREA')
1489      {
1490        if (!$this->tablestart) //not inside a table
1491        {
1492        //Draw arrows too?

1493        $texto = '';
1494        foreach($this->textbuffer as $v) $texto .= $v[0];
1495          $this->SetFillColor(235,235,235);
1496              $this->SetFont('courier');
1497        $this->x +=3;
1498        $linesneeded = $this->WordWrap($texto,($this->col*2.2)+3);
1499        if ( $linesneeded > $this->row ) //Too many words inside textarea
1500        {
1501            $textoaux = explode("\n",$texto);
1502            $texto = '';
1503            for($i=0;$i < $this->row;$i++)
1504            {
1505                 if ($i == $this->row-1) $texto .= $textoaux[$i];
1506                 else $texto .= $textoaux[$i] . "\n";
1507            }
1508            //Inform the user that some text has been truncated

1509            $texto{strlen($texto)-1} = ".";
1510            $texto{strlen($texto)-2} = ".";
1511            $texto{strlen($texto)-3} = ".";
1512        }
1513        $backup_y = $this->y;
1514        $this->Rect($this->x,$this->y,(2.2*$this->col)+6,5*$this->row,'DF');
1515        if ($texto != '') $this->MultiCell((2.2*$this->col)+6,$this->lineheight,$texto);
1516        $this->y = $backup_y + $this->row*$this->lineheight;
1517              $this->SetFont('arial');
1518      }
1519      else //inside a table
1520      {
1521                  $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
1522                  $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
1523          $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later

1524          $this->specialcontent = '';
1525      }
1526      $this->SetFillColor(255);
1527      $this->textbuffer=array(); 
1528      $this->buffer_on = false;
1529    }
1530      if($tag=='SELECT')
1531      {
1532        $texto = '';
1533        $tamanho = 0;
1534      if (isset($this->selectoption['MAXWIDTH'])) $tamanho = $this->selectoption['MAXWIDTH'];
1535      if ($this->tablestart)
1536      {
1537          $texto = "???".$this->specialcontent."???".$this->selectoption['SELECTED'];
1538          $aux = explode("???",$texto);
1539          $texto = $aux[2];
1540          $texto = "???".$aux[1].",width=$tamanho,height=".($this->lineheight + 2)."???".$texto;
1541          $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box

1542          $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later

1543  
1544          if (!isset($this->cell[$this->row][$this->col]['h'])) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1545                  $this->cell[$this->row][$this->col]['textbuffer'][] = array($texto);
1546                  $this->cell[$this->row][$this->col]['text'][] = '';
1547  
1548      }
1549      else //not inside a table
1550      {
1551        $texto = $this->selectoption['SELECTED'];
1552          $this->SetFillColor(235,235,235);
1553        $this->x += 2;
1554        $this->Rect($this->x,$this->y,$tamanho+2,5,'DF');//+2 margin

1555        $this->x += 1;
1556        if ($texto != '') $this->Write(5,$texto,$this->x);
1557        $this->x += $tamanho - $this->GetStringWidth($texto) + 2;
1558        $this->SetFillColor(190,190,190);
1559        $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box

1560        $this->SetFont('zapfdingbats');
1561        $this->Write(5,chr(116),$this->x); //Down arrow

1562        $this->SetFont('arial');
1563        $this->SetFillColor(255);
1564        $this->x += 1;
1565      }
1566      $this->selectoption = array();
1567      $this->specialcontent = '';
1568      $this->textbuffer = array(); 
1569    }
1570      if($tag=='SUB' or $tag=='SUP')  //subscript or superscript
1571      {
1572        if(!$this->pbegin and !$this->divbegin and !$this->tablestart and !$this->buffer_on and !$this->strike)
1573        {
1574         //Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer

1575         $this->SUB=false;
1576         $this->SUP=false;
1577         //Save x,y coords ???

1578         $x = $this->x;
1579         $y = $this->y;
1580         //Set some default values

1581         $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1582         //Print content

1583         $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
1584         $this->textbuffer=array();
1585         //Reset values

1586         $this->Reset();
1587      }
1588        $this->SUB=false;
1589        $this->SUP=false;
1590      }
1591      if($tag=='S' or $tag=='STRIKE' or $tag=='DEL')
1592      {
1593      if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1594      {
1595        //Deactivate $this->strike for its info is already stored inside $this->textbuffer

1596        $this->strike=false;
1597        //Save x,y coords ???

1598        $x = $this->x;
1599        $y = $this->y;
1600        //Set some default values

1601        $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1602        //Print content

1603        $this->printbuffer($this->textbuffer,true/*is out of a block (e.g. DIV,P etc.)*/);
1604        $this->textbuffer=array(); 
1605        //Reset values

1606          $this->Reset();
1607      }
1608      $this->strike=false;
1609    }
1610      if($tag=='ADDRESS' or $tag=='CENTER') // <ADDRESS> or <CENTER> tag
1611      {
1612      $this->blockjustfinished = true; //Eliminate exceeding left-side spaces

1613      if(!$this->pbegin and !$this->divbegin and !$this->tablestart)
1614      {
1615        //Save x,y coords ???

1616        $x = $this->x;
1617        $y = $this->y;
1618        //Set some default values

1619        $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1620        //Print content

1621        $this->printbuffer($this->textbuffer);
1622        $this->textbuffer=array(); 
1623          //Reset values

1624          $this->Reset();
1625      }
1626      $this->buffer_on=false;
1627        if ($tag == 'ADDRESS') $this->SetStyle('I',false);
1628    }
1629    if($tag=='BIG')
1630    {
1631        $newsize = $this->FontSizePt - 1;
1632        $this->SetFontSize($newsize);
1633          $this->SetStyle('B',false);
1634    }
1635    if($tag=='SMALL')
1636    {
1637        $newsize = $this->FontSizePt + 1;
1638        $this->SetFontSize($newsize);
1639    }
1640      if($tag=='FONT')
1641    {
1642          if ($this->issetcolor == true)
1643      {
1644        $this->colorarray = array();
1645              $this->SetTextColor(0);
1646              $this->issetcolor = false;
1647          }
1648          if ($this->issetfont)
1649      {
1650              $this->SetFont('arial');
1651              $this->issetfont=false;
1652          }
1653          if ($this->cssbegin)
1654          {
1655            //Get some attributes back!

1656            $this->setCSS($this->backupcss);
1657      }
1658      }
1659  }
1660  
1661  function printlistbuffer()
1662  {
1663  //! @return void

1664  //! @desc Prints all list-related buffered info

1665  
1666      //Save x coordinate

1667      $x = $this->oldx;
1668      foreach($this->listitem as $item)
1669      {
1670          //Set default width & height values

1671          $this->divwidth = $this->pgwidth;
1672          $this->divheight = $this->lineheight;
1673          //Get list's buffered data

1674          $lvl = $item[0];
1675          $num = $item[1];
1676          $this->textbuffer = $item[2];
1677          $occur = $item[3];
1678          $type = $this->listlist[$lvl][$occur]['TYPE'];
1679          $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
1680          switch($type) //Format type
1681          {
1682            case 'A':
1683                $num = dec2alpha($num,true);
1684                $maxnum = dec2alpha($maxnum,true);
1685                $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
1686                break;
1687            case 'a':
1688                $num = dec2alpha($num,false);
1689                $maxnum = dec2alpha($maxnum,false);
1690                $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
1691                break;
1692            case 'I':
1693                $num = dec2roman($num,true);
1694                $maxnum = dec2roman($maxnum,true);
1695                $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
1696                break;
1697            case 'i':
1698                $num = dec2roman($num,false);
1699                $maxnum = dec2roman($maxnum,false);
1700                $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
1701                break;
1702            case '1':
1703                $type = str_pad($num,strlen($maxnum),' ',STR_PAD_LEFT) . ".";
1704                break;
1705            case 'disc':
1706                $type = chr(149);
1707                break;
1708            case 'square':
1709                $type = chr(110); //black square on Zapfdingbats font

1710                break;
1711            case 'circle':
1712                $type = chr(186);
1713                break;
1714            default: break;
1715          }
1716          $this->x = (5*$lvl) + $x; //Indent list

1717          //Get bullet width including margins

1718          $oldsize = $this->FontSize * $this->k;
1719          if ($type == chr(110)) $this->SetFont('zapfdingbats','',5);
1720          $type .= ' ';
1721          $blt_width = $this->GetStringWidth($type)+$this->cMargin*2;
1722          //Output bullet

1723          $this->Cell($blt_width,5,$type,'','','L');
1724          $this->SetFont('arial','',$oldsize);
1725          $this->divwidth = $this->divwidth + $this->lMargin - $this->x;
1726          //Print content

1727          $this->printbuffer($this->textbuffer);
1728          $this->textbuffer=array();
1729      }
1730      //Reset all used values

1731      $this->listoccur = array();
1732      $this->listitem = array();
1733      $this->listlist = array();
1734      $this->listlvl = 0;
1735      $this->listnum = 0;
1736      $this->listtype = '';
1737      $this->textbuffer = array();
1738      $this->divwidth = 0;
1739      $this->divheight = 0;
1740      $this->oldx = -1;
1741      //At last, but not least, skip a line

1742      $this->Ln($this->lineheight);
1743  }
1744  
1745  function printbuffer($arrayaux,$outofblock=false,$is_table=false)
1746  {
1747  //! @return headache

1748  //! @desc Prepares buffered text to be printed with FlowingBlock()

1749  
1750      //Save some previous parameters

1751      $save = array();
1752      $save['strike'] = $this->strike;
1753      $save['SUP'] = $this->SUP;
1754      $save['SUB'] = $this->SUB;
1755      $save['DOTTED'] = $this->dotted_on;
1756      $save['DASHED'] = $this->dash_on;
1757        $this->SetDash(); //restore to no dash

1758        $this->dash_on = false;
1759      $this->dotted_on = false;
1760  
1761      $bak_y = $this->y;
1762        $bak_x = $this->x;
1763        $align = $this->divalign;
1764        $oldpage = $this->page;
1765  
1766        //Overall object size == $old_height

1767        //Line height == $this->divheight

1768        $old_height = $this->divheight;
1769      if ($is_table)
1770      {
1771        $this->divheight = 1.1*$this->lineheight;
1772        $fill = 0;
1773      }
1774      else
1775      {
1776        $this->divheight = $this->lineheight;
1777        if ($this->FillColor == '1.000 g') $fill = 0; //avoid useless background painting (1.000 g == white background color)

1778        else $fill = 1;
1779      }
1780  
1781      $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table);
1782  
1783      $array_size = count($arrayaux);
1784      for($i=0;$i < $array_size; $i++)
1785      {
1786        $vetor = $arrayaux[$i];
1787        if ($i == 0 and $vetor[0] != "\n") $vetor[0] = ltrim($vetor[0]);
1788        if (empty($vetor[0]) and empty($vetor[7])) continue; //Ignore empty text and not carrying an internal link

1789        //Activating buffer properties

1790        if(isset($vetor[10]) and !empty($vetor[10])) //Background color
1791        {
1792            $cor = $vetor[10];
1793                    $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
1794                    $this->divbgcolor = true;
1795        }
1796        if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
1797        {
1798            $cor = $vetor[9]['COLOR'];
1799            $outlinewidth = $vetor[9]['WIDTH'];
1800            $this->SetTextOutline($outlinewidth,$cor['R'],$cor['G'],$cor['B']);
1801            $this->outline_on = true;
1802        }
1803        if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
1804        {
1805            $this->strike = true;
1806        }
1807        if(isset($vetor[7]) and $vetor[7] != '') // internal link: <a name="anyvalue">
1808        {
1809          $this->internallink[$vetor[7]] = array("Y"=>$this->y,"PAGE"=>$this->page );
1810          $this->Bookmark($vetor[7]." (pg. $this->page)",0,$this->y);
1811          if (empty($vetor[0])) continue; //Ignore empty text

1812        }
1813        if(isset($vetor[6]) and $vetor[6] === true) // Subscript 
1814        {
1815             $this->SUB = true;
1816           $this->SetFontSize(6);
1817        }
1818        if(isset($vetor[5]) and $vetor[5] === true) // Superscript
1819        {
1820           $this->SUP = true;
1821           $this->SetFontSize(6);
1822        }
1823        if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont($vetor[4]); // Font Family

1824        if (!empty($vetor[3])) //Font Color
1825        {
1826          $cor = $vetor[3];
1827                $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
1828        }
1829        if(isset($vetor[2]) and $vetor[2] != '') //Bold,Italic,Underline styles
1830        {
1831            if (strpos($vetor[2],"B") !== false) $this->SetStyle('B',true);
1832            if (strpos($vetor[2],"I") !== false) $this->SetStyle('I',true);
1833            if (strpos($vetor[2],"U") !== false) $this->SetStyle('U',true);
1834        }
1835        if(isset($vetor[1]) and $vetor[1] != '') //LINK
1836        {
1837          if (strpos($vetor[1],".") === false) //assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.) 
1838          {
1839            //Repeated reference to same anchor?

1840            while(array_key_exists($vetor[1],$this->internallink)) $vetor[1]="#".$vetor[1];
1841            $this->internallink[$vetor[1]] = $this->AddLink();
1842            $vetor[1] = $this->internallink[$vetor[1]];
1843          }
1844          $this->HREF = $vetor[1];
1845          $this->SetTextColor(0,0,255);
1846          $this->SetStyle('U',true);
1847        }
1848        //Print-out special content

1849        if (isset($vetor[0]) and $vetor[0]{0} == '?' and $vetor[0]{1} == '?' and $vetor[0]{2} == '?') //identifier has been identified!
1850        {
1851          $content = explode("???",$vetor[0]);
1852          $texto = $content[2];
1853          $content = explode(",",$content[1]);
1854          foreach($content as $value)
1855          {
1856            $value = explode("=",$value);
1857            $specialcontent[$value[0]] = $value[1];
1858          }
1859          if ($this->flowingBlockAttr[ 'contentWidth' ] > 0) // Print out previously accumulated content
1860          {
1861              $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k;
1862              //Restart Flowing Block

1863              $this->finishFlowingBlock($outofblock);
1864              $this->x = $bak_x + ($width_used % $this->divwidth) + 0.5;// 0.5 == margin

1865              $this->y -= ($this->lineheight + 0.5);
1866              $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)

1867              if ($specialcontent['type'] == 'select') $extrawidth = 7; //arrow box + margin

1868              if(($this->x - $bak_x) + $specialcontent['width'] + $extrawidth > $this->divwidth )
1869              {
1870                $this->x = $bak_x;
1871                $this->y += $this->lineheight - 1;
1872              }
1873              $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
1874          }
1875          switch(strtoupper($specialcontent['type']))
1876          {
1877            case 'IMAGE':
1878                        //xpos and ypos used in order to support: <div align='center'><img ...></div>

1879                        $xpos = 0;
1880                        $ypos = 0;
1881                        if (isset($specialcontent['ypos']) and $specialcontent['ypos'] != '') $ypos = (float)$specialcontent['ypos']; 
1882                        if (isset($specialcontent['xpos']) and $specialcontent['xpos'] != '') $xpos = (float)$specialcontent['xpos'];
1883                        $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later

1884                        //Is this the best way of fixing x,y coordinates?

1885                        $fix_x = ($this->x+2) * $this->k + ($xpos*$this->k); //+2 margin

1886                        $fix_y = ($this->h - (($this->y+2) + $specialcontent['height'])) * $this->k;//+2 margin

1887                        $imgtemp = explode(" ",$texto);
1888                        $imgtemp[5]=$fix_x; // x

1889                        $imgtemp[6]=$fix_y; // y

1890                        $texto = implode(" ",$imgtemp);
1891                        $this->_out($texto);
1892                        //Readjust x coordinate in order to allow text to be placed after this form element

1893                        $this->x = $bak_x;
1894                        $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1895                        $spacenum = (integer)ceil(($width_used / $spacesize));
1896                        //Consider the space used so far in this line as a bunch of spaces

1897                        if ($ypos != 0) $this->Ln($ypos);
1898                        else $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
1899                        break;
1900            case 'INPUT':
1901                        switch($specialcontent['subtype'])
1902                        {
1903                                case 'PASSWORD':
1904                                case 'TEXT': //Draw TextField
1905                                            $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later

1906                                              $this->SetFillColor(235,235,235);
1907                                            $this->x += 1;
1908                                            $this->y += 1;
1909                                            $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF');// 4.5 in order to avoid overlapping

1910                                            if ($texto != '')
1911                                            {
1912                                                 $this->x += 1;
1913                                                 $this->Write(5,$texto,$this->x);
1914                                                 $this->x -= $this->GetStringWidth($texto);
1915                                            }
1916                                            $this->SetFillColor(255);
1917                                            $this->y -= 1;
1918                                            //Readjust x coordinate in order to allow text to be placed after this form element

1919                                            $this->x = $bak_x;
1920                                            $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1921                                            $spacenum = (integer)ceil(($width_used / $spacesize));
1922                                            //Consider the space used so far in this line as a bunch of spaces

1923                                            $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
1924                                            break;
1925                                case 'CHECKBOX': //Draw Checkbox
1926                                            $width_used = (($this->x - $bak_x) + $specialcontent['width'])*$this->k; //in order to adjust x coordinate later

1927                                            $checked = $texto;
1928                                            $this->SetFillColor(235,235,235);
1929                                            $this->y += 1;
1930                                            $this->x += 1;
1931                                            $this->Rect($this->x,$this->y,3,3,'DF');
1932                                            if ($checked)
1933                                            {
1934                                               $this->Line($this->x,$this->y,$this->x+3,$this->y+3);
1935                                               $this->Line($this->x,$this->y+3,$this->x+3,$this->y);
1936                                            }
1937                                            $this->SetFillColor(255);
1938                                            $this->y -= 1;
1939                                            //Readjust x coordinate in order to allow text to be placed after this form element

1940                                            $this->x = $bak_x;
1941                                            $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1942                                            $spacenum = (integer)ceil(($width_used / $spacesize));
1943                                            //Consider the space used so far in this line as a bunch of spaces

1944                                            $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
1945                                            break;
1946                                case 'RADIO': //Draw Radio button
1947                                            $width_used = (($this->x - $bak_x) + $specialcontent['width']+0.5)*$this->k; //in order to adjust x coordinate later

1948                                            $checked = $texto;
1949                                            $this->x += 2;
1950                                            $this->y += 1.5;
1951                                            $this->Circle($this->x,$this->y+1.2,1,'D');
1952                                            $this->_out('0.000 g');
1953                                            if ($checked) $this->Circle($this->x,$this->y+1.2,0.4,'DF');
1954                                            $this->y -= 1.5;
1955                                            //Readjust x coordinate in order to allow text to be placed after this form element

1956                                            $this->x = $bak_x;
1957                                            $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1958                                            $spacenum = (integer)ceil(($width_used / $spacesize));
1959                                            //Consider the space used so far in this line as a bunch of spaces

1960                                            $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
1961                                            break;
1962                                case 'BUTTON': // Draw a button
1963                                case 'SUBMIT':
1964                                case 'RESET':
1965                                            $nihil = ($specialcontent['width']-$this->GetStringWidth($texto))/2;
1966                                            $this->x += 1.5;
1967                                            $this->y += 1;
1968                                                $this->SetFillColor(190,190,190);
1969                                            $this->Rect($this->x,$this->y,$specialcontent['width'],4.5,'DF'); // 4.5 in order to avoid overlapping

1970                                            $this->x += $nihil;
1971                                            $this->Write(5,$texto,$this->x);
1972                                            $this->x += $nihil;
1973                                            $this->SetFillColor(255);
1974                                            $this->y -= 1;
1975                                            break;
1976                                default: break;
1977                        }
1978                        break;
1979            case 'SELECT':
1980                        $width_used = (($this->x - $bak_x) + $specialcontent['width'] + 8)*$this->k; //in order to adjust x coordinate later

1981                        $this->SetFillColor(235,235,235); //light gray

1982                        $this->x += 1.5;
1983                        $this->y += 1;
1984                        $this->Rect($this->x,$this->y,$specialcontent['width']+2,$this->lineheight,'DF'); // +2 == margin

1985                        $this->x += 1;
1986                        if ($texto != '') $this->Write($this->lineheight,$texto,$this->x); //the combobox content

1987                        $this->x += $specialcontent['width'] - $this->GetStringWidth($texto) + 2;
1988                        $this->SetFillColor(190,190,190); //dark gray

1989                        $this->Rect($this->x-1,$this->y,5,5,'DF'); //Arrow Box

1990                        $this->SetFont('zapfdingbats');
1991                        $this->Write($this->lineheight,chr(116),$this->x); //Down arrow

1992                        $this->SetFont('arial');
1993                        $this->SetFillColor(255);
1994                        //Readjust x coordinate in order to allow text to be placed after this form element

1995                        $this->x = $bak_x;
1996                        $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1997                        $spacenum = (integer)ceil(($width_used / $spacesize));
1998                        //Consider the space used so far in this line as a bunch of spaces

1999                        $this->WriteFlowingBlock(str_repeat(' ',$spacenum));
2000                        break;
2001            case 'TEXTAREA':
2002                        //Setup TextArea properties

2003                        $this->SetFillColor(235,235,235);
2004                              $this->SetFont('courier');
2005                          $this->currentfont='courier';
2006                        $ta_lines = $specialcontent['lines'];
2007                        $ta_height = 1.1*$this->lineheight*$ta_lines;
2008                        $ta_width = $specialcontent['width'];
2009                        //Adjust x,y coordinates

2010                        $this->x += 1.5;
2011                        $this->y += 1.5;
2012                        $linesneeded = $this->WordWrap($texto,$ta_width);
2013                        if ( $linesneeded > $ta_lines ) //Too many words inside textarea
2014                        {
2015                          $textoaux = explode("\n",$texto);
2016                          $texto = '';
2017                          for($i=0;$i<$ta_lines;$i++)
2018                          {
2019                            if ($i == $ta_lines-1) $texto .= $textoaux[$i];
2020                            else $texto .= $textoaux[$i] . "\n";
2021                          }
2022                          //Inform the user that some text has been truncated

2023                          $texto{strlen($texto)-1} = ".";
2024                          $texto{strlen($texto)-2} = ".";
2025                          $texto{strlen($texto)-3} = ".";
2026                        }
2027                        $backup_y = $this->y;
2028                        $backup_x = $this->x;
2029                        $this->Rect($this->x,$this->y,$ta_width+3,$ta_height,'DF');
2030                        if ($texto != '') $this->MultiCell($ta_width+3,$this->lineheight,$texto);
2031                        $this->y = $backup_y - 1.5;
2032                        $this->x = $backup_x + $ta_width + 2.5;
2033                          $this->SetFillColor(255);
2034                              $this->SetFont('arial');
2035                          $this->currentfont='';
2036                        break;
2037            default: break;
2038          }
2039        }
2040        else //THE text
2041        {
2042          if ($vetor[0] == "\n") //We are reading a <BR> now turned into newline ("\n")
2043          {
2044              //Restart Flowing Block

2045              $this->finishFlowingBlock($outofblock);
2046              if($outofblock) $this->Ln($this->lineheight);
2047              $this->x = $bak_x;
2048              $this->newFlowingBlock( $this->divwidth,$this->divheight,$this->divborder,$align,$fill,$is_table );
2049          }
2050          else $this->WriteFlowingBlock( $vetor[0] , $outofblock );
2051        }
2052        //Check if it is the last element. If so then finish printing the block

2053        if ($i == ($array_size-1)) $this->finishFlowingBlock($outofblock);
2054        //Now we must deactivate what we have used

2055        if( (isset($vetor[1]) and $vetor[1] != '') or $this->HREF != '')
2056        {
2057          $this->SetTextColor(0);
2058          $this->SetStyle('U',false);
2059          $this->HREF = '';
2060        }
2061        if(isset($vetor[2]) and $vetor[2] != '')
2062        {
2063          $this->SetStyle('B',false);
2064          $this->SetStyle('I',false);
2065          $this->SetStyle('U',false);
2066        }
2067        if(isset($vetor[3]) and $vetor[3] != '')
2068        {
2069          unset($cor);
2070              $this->SetTextColor(0);
2071        }
2072        if(isset($vetor[4]) and $vetor[4] != '') $this->SetFont('arial');
2073        if(isset($vetor[5]) and $vetor[5] === true)
2074        {
2075          $this->SUP = false;
2076          $this->SetFontSize(11);
2077        }
2078        if(isset($vetor[6]) and $vetor[6] === true)
2079        {
2080          $this->SUB = false;
2081          $this->SetFontSize(11);
2082        }
2083        //vetor7-internal links

2084        if(isset($vetor[8]) and $vetor[8] === true) // strike-through the text
2085        {
2086          $this->strike = false;
2087        }
2088        if(isset($vetor[9]) and !empty($vetor[9])) // Outline parameters
2089        {
2090            $this->SetTextOutline(false);
2091            $this->outline_on = false;
2092        }
2093        if(isset($vetor[10]) and !empty($vetor[10])) //Background color
2094        {
2095                    $this->SetFillColor(255);
2096                    $this->divbgcolor = false;
2097        }
2098      }//end of for(i=0;i<arraysize;i++)

2099  
2100      //Restore some previously set parameters

2101      $this->strike = $save['strike'];
2102      $this->SUP = $save['SUP'];
2103      $this->SUB = $save['SUB'];
2104      $this->dotted_on = $save['DOTTED'];
2105      $this->dash_on = $save['DASHED'];
2106        if ($this->dash_on) $this->SetDash(2,2);
2107      //Check whether we have borders to paint or not

2108      //(only works 100% if whole content spans only 1 page)

2109      if ($this->cssbegin and ($this->divborder or $this->dash_on or $this->dotted_on or $this->divbgcolor))
2110      {
2111          if ($oldpage != $this->page)
2112          {
2113             //Only border on last page is painted (known bug)

2114             $x = $this->lMargin;
2115             $y = $this->tMargin;
2116             $old_height = $this->y - $y;
2117          }
2118          else
2119          {
2120             if ($this->oldx < 0) $x  = $this->x;
2121             else $x = $this->oldx;
2122             if ($this->oldy < 0) $y  = $this->y - $old_height;
2123             else $y = $this->oldy;
2124          }
2125          if ($this->divborder) $this->Rect($x,$y,$this->divwidth,$old_height);
2126          if ($this->dash_on) $this->Rect($x,$y,$this->divwidth,$old_height);
2127              if ($this->dotted_on) $this->DottedRect($x,$y,$this->divwidth,$old_height);
2128          $this->x = $bak_x;
2129      }
2130  }
2131  
2132  function Reset()
2133  {
2134  //! @return void

2135  //! @desc Resets several class attributes

2136  
2137  //  if ( $this->issetcolor !== true )

2138  //  {

2139          $this->SetTextColor(0);
2140          $this->SetDrawColor(0);
2141          $this->SetFillColor(255);
2142        $this->colorarray = array();
2143        $this->bgcolorarray = array();
2144  $this->issetcolor = false;
2145  //  }

2146  $this->HREF = '';
2147  $this->SetTextOutline(false);
2148  
2149  //$this->strike = false;

2150  
2151    $this->SetFontSize(11);
2152      $this->SetStyle('B',false);
2153      $this->SetStyle('I',false);
2154      $this->SetStyle('U',false);
2155      $this->SetFont('arial');
2156      $this->divwidth = 0;
2157      $this->divheight = 0;
2158      $this->divalign = "L";
2159    $this->divrevert = false;
2160      $this->divborder = 0;
2161      $this->divbgcolor = false;
2162    $this->toupper = false;
2163    $this->tolower = false;
2164      $this->SetDash(); //restore to no dash

2165      $this->dash_on = false;
2166    $this->dotted_on = false;
2167    $this->oldx = -1;
2168    $this->oldy = -1;
2169  }
2170  
2171  function ReadMetaTags($html)
2172  {
2173  //! @return void

2174  //! @desc Pass meta tag info to PDF file properties

2175      $regexp = '/ (\\w+?)=([^\\s>"]+)/si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)

2176      $html = preg_replace($regexp," \$1=\"\$2\"",$html);
2177    $regexp = '/<meta .*?(name|content)="(.*?)" .*?(name|content)="(.*?)".*?>/si';
2178    preg_match_all($regexp,$html,$aux);
2179    
2180    $firstattr = $aux[1];
2181    $secondattr = $aux[3];
2182    for( $i = 0 ; $i < count($aux[0]) ; $i++)
2183    {
2184  
2185       $name = ( strtoupper($firstattr[$i]) == "NAME" )? strtoupper($aux[2][$i]) : strtoupper($aux[4][$i]);
2186       $content = ( strtoupper($firstattr[$i]) == "CONTENT" )? $aux[2][$i] : $aux[4][$i];
2187       switch($name)
2188       {
2189         case "KEYWORDS": $this->SetKeywords($content); break;
2190         case "AUTHOR": $this->SetAuthor($content); break;
2191         case "DESCRIPTION": $this->SetSubject($content); break;
2192       }
2193    }
2194    //Comercial do Aplicativo usado (no caso um script):

2195    $this->SetCreator("HTML2FPDF >> http://html2fpdf.sf.net");
2196  }
2197  
2198  //////////////////

2199  /// CSS parser ///

2200  //////////////////

2201  function ReadCSS($html)
2202  {
2203  //! @desc CSS parser

2204  //! @return string

2205  
2206  /*

2207  * This version ONLY supports:  .class {...} / #id { .... }

2208  * It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names

2209  * This function must read the CSS code (internal or external) and order its value inside $this->CSS. 

2210  */
2211  
2212      $match = 0; // no match for instance

2213      $regexp = ''; // This helps debugging: showing what is the REAL string being processed

2214      
2215      //CSS inside external files

2216      $regexp = '/<link rel="stylesheet".*?href="(.+?)"\\s*?\/?>/si'; 
2217      $match = preg_match_all($regexp,$html,$CSSext);
2218    $ind = 0;
2219  
2220      while($match){
2221      //Fix path value

2222      $path = $CSSext[1][$ind];
2223      $path = str_replace("\\","/",$path); //If on Windows

2224      //Get link info and obtain its absolute path

2225      $regexp = '|^./|';
2226      $path = preg_replace($regexp,'',$path);
2227      if (strpos($path,"../") !== false ) //It is a Relative Link
2228      {
2229         $backtrackamount = substr_count($path,"../");
2230         $maxbacktrack = substr_count($this->basepath,"/") - 1;
2231         $filepath = str_replace("../",'',$path);
2232         $path = $this->basepath;
2233         //If it is an invalid relative link, then make it go to directory root

2234         if ($backtrackamount > $maxbacktrack) $backtrackamount = $maxbacktrack;
2235         //Backtrack some directories

2236         for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ ) $path = substr( $path, 0 , strrpos($path,"/") );
2237         $path = $path . "/" . $filepath; //Make it an absolute path

2238      }
2239      elseif( strpos($path,":/") === false) //It is a Local Link
2240      {
2241          $path = $this->basepath . $path; 
2242      }
2243      //Do nothing if it is an Absolute Link

2244      //END of fix path value

2245      $CSSextblock = file_get_contents($path);    
2246  
2247      //Get class/id name and its characteristics from $CSSblock[1]

2248        $regexp = '/[.# ]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n

2249        preg_match_all( $regexp, $CSSextblock, $extstyle);
2250  
2251        //Make CSS[Name-of-the-class] = array(key => value)

2252        $regexp = '/\\s*?(\\S+?):(.+?);/si';
2253  
2254        for($i=0; $i < count($extstyle[1]) ; $i++)
2255        {
2256          preg_match_all( $regexp, $extstyle[2][$i], $extstyleinfo);
2257          $extproperties = $extstyleinfo[1];
2258          $extvalues = $extstyleinfo[2];
2259          for($j = 0; $j < count($extproperties) ; $j++) 
2260          {
2261              //Array-properties and Array-values must have the SAME SIZE!

2262              $extclassproperties[strtoupper($extproperties[$j])] = trim($extvalues[$j]);
2263          }
2264          $this->CSS[$extstyle[1][$i]] = $extclassproperties;
2265          $extproperties = array();
2266          $extvalues = array();
2267          $extclassproperties = array();
2268      }
2269        $match--;
2270        $ind++;
2271      } //end of match

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

2274  
2275      //CSS internal

2276      //Get content between tags and order it, using regexp

2277      $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css"> 

2278      $match = preg_match($regexp,$html,$CSSblock);
2279  
2280      if ($match) {
2281      //Get class/id name and its characteristics from $CSSblock[1]

2282      $regexp = '/[.#]([^.]+?)\\s*?\{(.+?)\}/s'; // '/s' PCRE_DOTALL including \n

2283      preg_match_all( $regexp, $CSSblock[1], $style);
2284  
2285        //Make CSS[Name-of-the-class] = array(key => value)

2286        $regexp = '/\\s*?(\\S+?):(.+?);/si';
2287  
2288        for($i=0; $i < count($style[1]) ; $i++)
2289        {
2290          preg_match_all( $regexp, $style[2][$i], $styleinfo);
2291          $properties = $styleinfo[1];
2292          $values = $styleinfo[2];
2293          for($j = 0; $j < count($properties) ; $j++) 
2294          {
2295              //Array-properties and Array-values must have the SAME SIZE!

2296              $classproperties[strtoupper($properties[$j])] = trim($values[$j]);
2297          }
2298          $this->CSS[$style[1][$i]] = $classproperties;
2299          $properties = array();
2300          $values = array();
2301          $classproperties = array();
2302      }
2303      } // end of match

2304  
2305      //Remove CSS (tags and content), if any

2306      $regexp = '/<style.*?>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css"> 

2307      $html = preg_replace($regexp,'',$html);
2308  
2309      return $html;
2310  }
2311  
2312  function readInlineCSS($html)
2313  {
2314  //! @return array

2315  //! @desc Reads inline CSS and returns an array of properties

2316  
2317    //Fix incomplete CSS code

2318    $size = strlen($html)-1;
2319    if ($html{$size} != ';') $html .= ';';
2320    //Make CSS[Name-of-the-class] = array(key => value)

2321    $regexp = '|\\s*?(\\S+?):(.+?);|i';
2322      preg_match_all( $regexp, $html, $styleinfo);
2323      $properties = $styleinfo[1];
2324      $values = $styleinfo[2];
2325      //Array-properties and Array-values must have the SAME SIZE!

2326      $classproperties = array();
2327      for($i = 0; $i < count($properties) ; $i++) $classproperties[strtoupper($properties[$i])] = trim($values[$i]);
2328      
2329    return $classproperties;
2330  }
2331  
2332  function setCSS($arrayaux)
2333  {
2334  //! @return void

2335  //! @desc Change some class attributes according to CSS properties

2336    if (!is_array($arrayaux)) return; //Removes PHP Warning

2337      foreach($arrayaux as $k => $v)
2338    {
2339      switch($k){
2340              case 'WIDTH':
2341                      $this->divwidth = ConvertSize($v,$this->pgwidth);
2342                      break;
2343              case 'HEIGHT':
2344                      $this->divheight = ConvertSize($v,$this->pgwidth);
2345                      break;
2346              case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
2347                      $prop = explode(' ',$v);
2348                      if ( count($prop) != 3 ) break; // Not supported: borders not fully declared

2349              //style: dashed dotted none (anything else => solid )

2350                      if (strnatcasecmp($prop[1],"dashed") == 0) //found "dashed"! (ignores case)
2351              {
2352                 $this->dash_on = true;
2353                 $this->SetDash(2,2); //2mm on, 2mm off

2354              }
2355                      elseif (strnatcasecmp($prop[1],"dotted") == 0) //found "dotted"! (ignores case)
2356              {
2357                 $this->dotted_on = true;
2358              }
2359                        elseif (strnatcasecmp($prop[1],"none") == 0) $this->divborder = 0;
2360                        else $this->divborder = 1;
2361                        //color

2362                      $coul = ConvertColor($prop[2]);
2363                      $this->SetDrawColor($coul['R'],$coul['G'],$coul['B']);
2364                      $this->issetcolor=true;
2365                        break;
2366                case 'FONT-FAMILY': // one of the $this->fontlist fonts
2367              //If it is a font list, get all font types

2368              $aux_fontlist = explode(",",$v);
2369              $fontarraysize = count($aux_fontlist);
2370              for($i=0;$i<$fontarraysize;$i++)
2371              {
2372                 $fonttype = $aux_fontlist[$i];
2373                 $fonttype = trim($fonttype);
2374                 //If font is found, set it, and exit loop

2375                 if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
2376                 //If font = "courier new" for example, try simply looking for "courier"

2377                 $fonttype = explode(" ",$fonttype);
2378                 $fonttype = $fonttype[0];
2379                 if ( in_array(strtolower($fonttype), $this->fontlist) ) {$this->SetFont(strtolower($fonttype));break;}
2380              }
2381                        break;
2382                case 'FONT-SIZE': //Does not support: smaller, larger
2383                    if(is_numeric($v{0}))
2384                    {
2385                       $mmsize = ConvertSize($v,$this->pgwidth);
2386                       $this->SetFontSize( $mmsize*(72/25.4) ); //Get size in points (pt)

2387              }
2388                    else{
2389                    $v = strtoupper($v);
2390                    switch($v)
2391                    {
2392                       //Values obtained from http://www.w3schools.com/html/html_reference.asp

2393                       case 'XX-SMALL': $this->SetFontSize( (0.7)* 11);
2394                           break;
2395                   case 'X-SMALL': $this->SetFontSize( (0.77) * 11);
2396                             break;
2397                         case 'SMALL': $this->SetFontSize( (0.86)* 11);
2398                           break;
2399                       case 'MEDIUM': $this->SetFontSize(11);
2400                           break;
2401                       case 'LARGE': $this->SetFontSize( (1.2)*11);
2402                           break;
2403                       case 'X-LARGE': $this->SetFontSize( (1.5)*11);
2404                           break;
2405                       case 'XX-LARGE': $this->SetFontSize( 2*11);
2406                             break;
2407                }
2408              }
2409                    break;
2410                  case 'FONT-STYLE': // italic normal oblique
2411                      switch (strtoupper($v))
2412                      {
2413                        case 'ITALIC': 
2414                        case 'OBLIQUE': 
2415                              $this->SetStyle('I',true);
2416                          break;
2417                        case 'NORMAL': break;
2418                      }
2419                        break;
2420                  case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
2421                      switch (strtoupper($v))
2422                      {
2423                        case 'BOLD': 
2424                              $this->SetStyle('B',true);
2425                          break;
2426                        case 'NORMAL': break;
2427                      }
2428                        break;
2429                  case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
2430                      switch (strtoupper($v))
2431                      {
2432                        case 'LINE-THROUGH':
2433                          $this->strike = true;
2434                                  break;
2435                        case 'UNDERLINE':
2436                              $this->SetStyle('U',true);
2437                                  break;
2438                        case 'NONE': break;
2439                      }
2440                  case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
2441                      switch (strtoupper($v)) //Not working 100%
2442                      { 
2443                        case 'UPPERCASE':
2444                                  $this->toupper=true;
2445                                  break;
2446                        case 'LOWERCASE':
2447                                  $this->tolower=true;
2448                                  break;
2449                        case 'NONE': break;
2450                      }
2451                  case 'TEXT-ALIGN': //left right center justify
2452                      switch (strtoupper($v))
2453                      {
2454                        case 'LEFT': 
2455                          $this->divalign="L";
2456                          break;
2457                        case 'CENTER': 
2458                          $this->divalign="C";
2459                          break;
2460                        case 'RIGHT': 
2461                          $this->divalign="R";
2462                          break;
2463                        case 'JUSTIFY': 
2464                          $this->divalign="J";
2465                          break;
2466                      }
2467                        break;
2468                  case 'DIRECTION': //ltr(default) rtl
2469                      if (strtolower($v) == 'rtl') $this->divrevert = true;
2470                        break;
2471                  case 'BACKGROUND': // bgcolor only
2472                        $cor = ConvertColor($v);
2473                        $this->bgcolorarray = $cor;
2474                        $this->SetFillColor($cor['R'],$cor['G'],$cor['B']);
2475                        $this->divbgcolor = true;
2476                        break;
2477                  case 'COLOR': // font color
2478                        $cor = ConvertColor($v);
2479                        $this->colorarray = $cor;
2480                        $this->SetTextColor($cor['R'],$cor['G'],$cor['B']);
2481                        $this->issetcolor=true;
2482                        break;
2483          }//end of switch($k)

2484     }//end of foreach

2485  }
2486  
2487  function SetStyle($tag,$enable)
2488  {
2489  //! @return void

2490  //! @desc Enables/Disables B,I,U styles

2491      //Modify style and select corresponding font

2492      $this->$tag+=($enable ? 1 : -1);
2493      $style='';
2494    //Fix some SetStyle misuse

2495      if ($this->$tag < 0) $this->$tag = 0;
2496      if ($this->$tag > 1) $this->$tag = 1;
2497      foreach(array('B','I','U') as $s)
2498          if($this->$s>0)
2499              $style.=$s;
2500              
2501      $this->currentstyle=$style;
2502      $this->SetFont('',$style);
2503  }
2504  
2505  function DisableTags($str='')
2506  {
2507  //! @return void

2508  //! @desc Disable some tags using ',' as separator. Enable all tags calling this function without parameters.

2509    if ($str == '') //enable all tags
2510    {
2511      //Insert new supported tags in the long string below.

2512      $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>";
2513    }
2514    else
2515    {
2516      $str = explode(",",$str);
2517      foreach($str as $v) $this->enabledtags = str_replace(trim($v),'',$this->enabledtags);
2518    }
2519  }
2520  
2521  ////////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////

2522  //Thanks to vietcom (vncommando at yahoo dot com)

2523  /*     Modified by Renato Coelho

2524     in order to print tables that span more than 1 page and to allow 

2525     bold,italic and the likes inside table cells (and alignment now works with styles!)

2526  */
2527  
2528  //table     Array of (w, h, bc, nr, wc, hr, cells)

2529  //w         Width of table

2530  //h         Height of table

2531  //nc        Number column

2532  //nr        Number row

2533  //hr        List of height of each row

2534  //wc        List of width of each column

2535  //cells     List of cells of each rows, cells[i][j] is a cell in the table

2536  function _tableColumnWidth(&$table){
2537  //! @return void

2538      $cs = &$table['cells'];
2539      $mw = $this->getStringWidth('W');
2540      $nc = $table['nc'];
2541      $nr = $table['nr'];
2542      $listspan = array();
2543      //Xac dinh do rong cua cac cell va cac cot tuong ung

2544      for($j = 0 ; $j < $nc ; $j++ ) //columns
2545    {
2546          $wc = &$table['wc'][$j];
2547          for($i = 0 ; $i < $nr ; $i++ ) //rows
2548      {
2549              if (isset($cs[$i][$j]) && $cs[$i][$j])
2550        {
2551                  $c = &$cs[$i][$j];
2552                  $miw = $mw;
2553                  if (isset($c['maxs']) and $c['maxs'] != '') $c['s'] = $c['maxs'];
2554                  $c['maw']   = $c['s'];
2555                  if (isset($c['nowrap'])) $miw = $c['maw'];
2556                  if (isset($c['w']))
2557          {
2558                      if ($miw<$c['w'])   $c['miw'] = $c['w'];
2559                      if ($miw>$c['w'])   $c['miw'] = $c['w']   = $miw;
2560                      if (!isset($wc['w'])) $wc['w'] = 1;
2561                  }
2562          else $c['miw'] = $miw;
2563                  if ($c['maw']  < $c['miw']) $c['maw'] = $c['miw'];
2564                  if (!isset($c['colspan']))
2565          {
2566                      if ($wc['miw'] < $c['miw'])     $wc['miw']  = $c['miw'];
2567                      if ($wc['maw'] < $c['maw'])     $wc['maw']  = $c['maw'];
2568                  }
2569          else $listspan[] = array($i,$j);
2570          //Check if minimum width of the whole column is big enough for a huge word to fit

2571          $auxtext = implode("",$c['text']);
2572          $minwidth = $this->WordWrap($auxtext,$wc['miw']-2);// -2 == margin

2573          if ($minwidth < 0 and (-$minwidth) > $wc['miw']) $wc['miw'] = (-$minwidth) +2; //increase minimum width

2574          if ($wc['miw'] > $wc['maw']) $wc['maw'] = $wc['miw']; //update maximum width, if needed

2575              }
2576          }//rows

2577      }//columns

2578      //Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai

2579      $wc = &$table['wc'];
2580      foreach ($listspan as $span)
2581    {
2582          list($i,$j) = $span;
2583          $c = &$cs[$i][$j];
2584          $lc = $j + $c['colspan'];
2585          if ($lc > $nc) $lc = $nc;
2586          
2587          $wis = $wisa = 0;
2588          $was = $wasa = 0;
2589          $list = array();
2590          for($k=$j;$k<$lc;$k++)
2591      {
2592              $wis += $wc[$k]['miw'];
2593              $was += $wc[$k]['maw'];
2594              if (!isset($c['w']))
2595        {
2596                  $list[] = $k;
2597                  $wisa += $wc[$k]['miw'];
2598                  $wasa += $wc[$k]['maw'];
2599              }
2600          }
2601          if ($c['miw'] > $wis)
2602      {
2603              if (!$wis)
2604        {//Cac cot chua co kich thuoc => chia deu
2605                  for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] = $c['miw']/$c['colspan'];
2606              }
2607        elseif(!count($list))
2608        {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
2609                  $wi = $c['miw'] - $wis;
2610                  for($k=$j;$k<$lc;$k++) $wc[$k]['miw'] += ($wc[$k]['miw']/$wis)*$wi;
2611              }
2612        else
2613        {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2614                  $wi = $c['miw'] - $wis;
2615                  foreach ($list as $k)   $wc[$k]['miw'] += ($wc[$k]['miw']/$wisa)*$wi;
2616              }
2617          }
2618          if ($c['maw'] > $was)
2619      {
2620              if (!$wis)
2621        {//Cac cot chua co kich thuoc => chia deu
2622                  for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] = $c['maw']/$c['colspan'];
2623              }
2624        elseif (!count($list))
2625        {
2626        //Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca

2627                  $wi = $c['maw'] - $was;
2628                  for($k=$j;$k<$lc;$k++) $wc[$k]['maw'] += ($wc[$k]['maw']/$was)*$wi;
2629              }
2630        else
2631        {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2632                  $wi = $c['maw'] - $was;
2633                  foreach ($list as $k)   $wc[$k]['maw'] += ($wc[$k]['maw']/$wasa)*$wi;
2634              }
2635          }
2636      }
2637  }
2638  
2639  function _tableWidth(&$table){
2640  //! @return void

2641  //! @desc Calculates the Table Width

2642  // @desc Xac dinh chieu rong cua table

2643      $widthcols = &$table['wc'];
2644      $numcols = $table['nc'];
2645      $tablewidth = 0;
2646      for ( $i = 0 ; $i < $numcols ; $i++ )
2647    {
2648          $tablewidth += isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
2649      }
2650      if ($tablewidth > $this->pgwidth) $table['w'] = $this->pgwidth;
2651      if (isset($table['w']))
2652    {
2653          $wis = $wisa = 0;
2654          $list = array();
2655          for( $i = 0 ; $i < $numcols ; $i++ )
2656      {
2657              $wis += $widthcols[$i]['miw'];
2658              if (!isset($widthcols[$i]['w'])){ $list[] = $i;$wisa += $widthcols[$i]['miw'];}
2659          }
2660          if ($table['w'] > $wis)
2661      {
2662              if (!count($list))
2663        {//Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
2664        //http://www.ksvn.com/anhviet_new.htm - translating comments...

2665        //bent shrink essence move size measure automatic => divide against give as a whole

2666                  //$wi = $table['w'] - $wis;

2667                  $wi = ($table['w'] - $wis)/$numcols;
2668                  for($k=0;$k<$numcols;$k++) 
2669                      //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wis)*$wi;

2670                      $widthcols[$k]['miw'] += $wi;
2671              }
2672        else
2673        {//Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2674                  //$wi = $table['w'] - $wis;

2675                  $wi = ($table['w'] - $wis)/count($list);
2676                  foreach ($list as $k)
2677                      //$widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wisa)*$wi;

2678                      $widthcols[$k]['miw'] += $wi;
2679              }
2680          }
2681          for ($i=0;$i<$numcols;$i++)
2682      {
2683              $tablewidth = $widthcols[$i]['miw'];
2684              unset($widthcols[$i]);
2685              $widthcols[$i] = $tablewidth;
2686          }
2687      }
2688    else //table has no width defined
2689    {
2690          $table['w'] = $tablewidth;
2691          for ( $i = 0 ; $i < $numcols ; $i++)
2692      {
2693              $tablewidth = isset($widthcols[$i]['w']) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
2694              unset($widthcols[$i]);
2695              $widthcols[$i] = $tablewidth;
2696          }
2697      }
2698  }
2699      
2700  function _tableHeight(&$table){
2701  //! @return void

2702  //! @desc Calculates the Table Height

2703      $cells = &$table['cells'];
2704      $numcols = $table['nc'];
2705      $numrows = $table['nr'];
2706      $listspan = array();
2707      for( $i = 0 ; $i < $numrows ; $i++ )//rows
2708    {
2709          $heightrow = &$table['hr'][$i];
2710          for( $j = 0 ; $j < $numcols ; $j++ ) //columns
2711      {
2712              if (isset($cells[$i][$j]) && $cells[$i][$j])
2713        {
2714                  $c = &$cells[$i][$j];
2715                  list($x,$cw) = $this->_tableGetWidth($table, $i,$j);
2716          //Check whether width is enough for this cells' text

2717          $auxtext = implode("",$c['text']);
2718          $auxtext2 = $auxtext; //in case we have text with styles

2719          $nostyles_size = $this->GetStringWidth($auxtext) + 3; // +3 == margin

2720          $linesneeded = $this->WordWrap($auxtext,$cw-2);// -2 == margin

2721                  if ($c['s'] > $nostyles_size and !isset($c['form'])) //Text with styles
2722                  {
2723             $auxtext = $auxtext2; //recover original characteristics (original /n placements)

2724             $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char

2725             if ($linesneeded == 0) $linesneeded = 1; //to avoid division by zero

2726             $diffsize /= $linesneeded;
2727             $linesneeded = $this->WordWrap($auxtext,$cw-2-$diffsize);//diffsize used to wrap text correctly

2728          }
2729          if (isset($c['form']))
2730          {
2731             $linesneeded = ceil(($c['s']-3)/($cw-2)); //Text + form in a cell

2732             //Presuming the use of styles

2733             if ( ($this->GetStringWidth($auxtext) + 3) > ($cw-2) ) $linesneeded++;
2734          }
2735          $ch = $linesneeded * 1.1 * $this->lineheight;
2736          //If height is bigger than page height...

2737          if ($ch > ($this->fh - $this->bMargin - $this->tMargin)) $ch = ($this->fh - $this->bMargin - $this->tMargin);
2738          //If height is defined and it is bigger than calculated $ch then update values

2739                  if (isset($c['h']) && $c['h'] > $ch)
2740                  {
2741             $c['mih'] = $ch; //in order to keep valign working

2742             $ch = $c['h'];
2743          }
2744          else $c['mih'] = $ch;
2745                  if (isset($c['rowspan']))   $listspan[] = array($i,$j);
2746                  elseif ($heightrow < $ch) $heightrow = $ch;
2747          if (isset($c['form'])) $c['mih'] = $ch;
2748        }
2749          }//end of columns

2750      }//end of rows

2751      $heightrow = &$table['hr'];
2752      foreach ($listspan as $span)
2753    {
2754          list($i,$j) = $span;
2755          $c = &$cells[$i][$j];
2756          $lr = $i + $c['rowspan'];
2757          if ($lr > $numrows) $lr = $numrows;
2758          $hs = $hsa = 0;
2759          $list = array();
2760          for($k=$i;$k<$lr;$k++)
2761      {
2762              $hs += $heightrow[$k];
2763              if (!isset($c['h']))
2764        {
2765                  $list[] = $k;
2766                  $hsa += $heightrow[$k];
2767              }
2768          }
2769          if ($c['mih'] > $hs)
2770      {
2771              if (!$hs)
2772        {//Cac dong chua co kich thuoc => chia deu
2773                  for($k=$i;$k<$lr;$k++) $heightrow[$k] = $c['mih']/$c['rowspan'];
2774              }
2775        elseif (!count($list))
2776        {//Khong co dong nao co kich thuoc auto => chia deu phan du cho tat ca
2777                  $hi = $c['mih'] - $hs;
2778                  for($k=$i;$k<$lr;$k++) $heightrow[$k] += ($heightrow[$k]/$hs)*$hi;
2779              }
2780        else
2781        {//Co mot so dong co kich thuoc auto => chia deu phan du cho cac dong auto
2782                  $hi = $c['mih'] - $hsa;
2783                  foreach ($list as $k) $heightrow[$k] += ($heightrow[$k]/$hsa)*$hi;
2784              }
2785          }
2786      }
2787  }
2788  
2789  function _tableGetWidth(&$table, $i,$j){
2790  //! @return array(x,w)

2791  // @desc Xac dinh toa do va do rong cua mot cell

2792  
2793      $cell = &$table['cells'][$i][$j];
2794      if ($cell)
2795    {
2796          if (isset($cell['x0'])) return array($cell['x0'], $cell['w0']);
2797          $x = 0;
2798          $widthcols = &$table['wc'];
2799          for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
2800          $w = $widthcols[$j];
2801          if (isset($cell['colspan']))
2802      {
2803               for ( $k = $j+$cell['colspan']-1 ; $k > $j ; $k-- )    $w += $widthcols[$k];
2804          }
2805          $cell['x0'] = $x;
2806          $cell['w0'] = $w;
2807          return array($x, $w);
2808      }
2809      return array(0,0);
2810  }
2811  
2812  function _tableGetHeight(&$table, $i,$j){
2813  //! @return array(y,h)

2814      $cell = &$table['cells'][$i][$j];
2815      if ($cell){
2816          if (isset($cell['y0'])) return array($cell['y0'], $cell['h0']);
2817          $y = 0;
2818          $heightrow = &$table['hr'];
2819          for ($k=0;$k<$i;$k++) $y += $heightrow[$k];
2820          $h = $heightrow[$i];
2821          if (isset($cell['rowspan'])){
2822              for ($k=$i+$cell['rowspan']-1;$k>$i;$k--)
2823                  $h += $heightrow[$k];
2824          }
2825          $cell['y0'] = $y;
2826          $cell['h0'] = $h;
2827          return array($y, $h);
2828      }
2829      return array(0,0);
2830  }
2831  
2832  function _tableRect($x, $y, $w, $h, $type=1){
2833  //! @return void

2834      if ($type==1)   $this->Rect($x, $y, $w, $h);
2835      elseif (strlen($type)==4){
2836          $x2 = $x + $w; $y2 = $y + $h;
2837          if (intval($type{0})) $this->Line($x , $y , $x2, $y );
2838          if (intval($type{1})) $this->Line($x2, $y , $x2, $y2);
2839          if (intval($type{2})) $this->Line($x , $y2, $x2, $y2);
2840          if (intval($type{3})) $this->Line($x , $y , $x , $y2);
2841      }
2842  }
2843  
2844  function _tableWrite(&$table){
2845  //! @desc Main table function

2846  //! @return void

2847      $cells = &$table['cells'];
2848      $numcols = $table['nc'];
2849      $numrows = $table['nr'];
2850      $x0 = $this->x;
2851      $y0 = $this->y;
2852      $right = $this->pgwidth - $this->rMargin;
2853      if (isset($table['a']) and ($table['w'] != $this->pgwidth))
2854    {
2855          if ($table['a']=='C') $x0 += (($right-$x0) - $table['w'])/2;
2856          elseif ($table['a']=='R')   $x0 = $right - $table['w'];
2857      }
2858    $returny = 0;
2859    $tableheader = array();
2860      //Draw Table Contents and Borders

2861      for( $i = 0 ; $i < $numrows ; $i++ ) //Rows
2862    { 
2863      $skippage = false;
2864      for( $j = 0 ; $j < $numcols ; $j++ ) //Columns
2865      {
2866              if (isset($cells[$i][$j]) && $cells[$i][$j])
2867          {
2868                    $cell = &$cells[$i][$j];
2869                    list($x,$w) = $this->_tableGetWidth($table, $i, $j);
2870                    list($y,$h) = $this->_tableGetHeight($table, $i, $j);
2871                    $x += $x0;
2872                $y += $y0;
2873            $y -= $returny;
2874            if ((($y + $h) > ($this->fh - $this->bMargin)) && ($y0 >0 || $x0 > 0))
2875            {
2876              if (!$skippage)
2877              {
2878                 $y -= $y0;
2879                 $returny += $y;
2880                 $this->AddPage();
2881                 if ($this->usetableheader) $this->Header($tableheader);
2882                 if ($this->usetableheader) $y0 = $this->y;
2883                 else $y0 = $this->tMargin;
2884                 $y = $y0;
2885              }
2886              $skippage = true;
2887            }
2888                    //Align

2889                    $this->x = $x; $this->y = $y;
2890                    $align = isset($cell['a'])? $cell['a'] : 'L';
2891                    //Vertical align

2892                    if (!isset($cell['va']) || $cell['va']=='M') $this->y += ($h-$cell['mih'])/2;
2893            elseif (isset($cell['va']) && $cell['va']=='B') $this->y += $h-$cell['mih'];
2894                    //Fill

2895                    $fill = isset($cell['bgcolor']) ? $cell['bgcolor']
2896                      : (isset($table['bgcolor'][$i]) ? $table['bgcolor'][$i]
2897                      : (isset($table['bgcolor'][-1]) ? $table['bgcolor'][-1] : 0));
2898                  if ($fill)
2899            {
2900                      $color = ConvertColor($fill);
2901                      $this->SetFillColor($color['R'],$color['G'],$color['B']);
2902                      $this->Rect($x, $y, $w, $h, 'F');
2903                  }
2904                  //Border

2905                  if (isset($cell['border'])) $this->_tableRect($x, $y, $w, $h, $cell['border']);
2906                  elseif (isset($table['border']) && $table['border']) $this->Rect($x, $y, $w, $h);
2907            $this->divalign=$align;
2908            $this->divwidth=$w-2;
2909            //Get info of first row == table header

2910            if ($this->usetableheader and $i == 0 )
2911            {
2912                $tableheader[$j]['x'] = $x;
2913                $tableheader[$j]['y'] = $y;
2914                $tableheader[$j]['h'] = $h;
2915                $tableheader[$j]['w'] = $w;
2916                $tableheader[$j]['text'] = $cell['text'];
2917                $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
2918                $tableheader[$j]['a'] = isset($cell['a'])? $cell['a'] : 'L';
2919                $tableheader[$j]['va'] = $cell['va'];
2920                $tableheader[$j]['mih'] = $cell['mih'];
2921                $tableheader[$j]['bgcolor'] = $fill;
2922                if ($table['border']) $tableheader[$j]['border'] = 'all';
2923                elseif (isset($cell['border'])) $tableheader[$j]['border'] = $cell['border'];
2924            }
2925            if (!empty($cell['textbuffer'])) $this->printbuffer($cell['textbuffer'],false,true/*inside a table*/);
2926            //Reset values

2927            $this->Reset();
2928          }//end of (if isset(cells)...)

2929      }// end of columns

2930      if ($i == $numrows-1) $this->y = $y + $h; //last row jump (update this->y position)

2931    }// end of rows

2932  }//END OF FUNCTION _tableWrite()

2933  
2934  /////////////////////////END OF TABLE CODE//////////////////////////////////

2935  
2936  }//end of Class

2937  
2938  /*

2939  ----  JUNK(?)/OLD CODE: ------

2940  // <?php <- this fixes HIGHLIGHT PSPAD bug ... 

2941  

2942  */
2943  
2944  ?>


Generato il: Mon Oct 19 20:29:27 2009 Generato con PHPXref 0.7