[ Index ]

PHP Cross Reference of phpwcms V1.4.3 _r380 (23.11.09)

title

Body

[close]

/include/inc_ext/html2fpdf/ -> html2fpdf.php (source)

   1  <?php
   2  /*
   3  *** General-use version
   4  
   5  DEBUG HINT:
   6  - Inside function printbuffer make $fill=1
   7  - Inside function Cell make:
   8  - Make call to debug_out() of this class to put the debug information on the output.
   9  if($fill==1 or $border==1)
  10  {
  11  //        if ($fill==1) $op=($border==1) ? 'B' : 'f';
  12  //        else $op='S';
  13  $op='S';
  14  - Following these 2 steps you will be able to see the cell's boundaries
  15  
  16  WARNING: When adding a new tag support, also add its name inside the function DisableTags()'s very long string
  17  
  18  ODDITIES (?):
  19  . It seems like saved['border'] and saved['bgcolor'] are useless inside the FlowingBlock...
  20  These 2 attributes do the same thing?!?:
  21  . $this->currentfont - mine
  22  . $this->CurrentFont - fpdf's
  23  
  24  TODO (in the future...):
  25  - Make font-family, font-size, lineheight customizable
  26  - Increase number of HTML/CSS tags/properties, Image/Font Types, recognized/supported
  27  - allow BMP support? (tried with http://phpthumb.sourceforge.net/ but failed)
  28  - Improve CSS support
  29  - support image side-by-side or one-below-another or both?
  30  - Improve code clarity even more (modularize and get better var names like on textbuffer array's indexes for example)
  31  
  32  //////////////////////////////////////////////////////////////////////////////
  33  //////////////DO NOT MODIFY THE CONTENTS OF THIS BOX//////////////////////////
  34  //////////////////////////////////////////////////////////////////////////////
  35  //                                                                          //
  36  // HTML2FPDF is a php script to read a HTML text and generate a PDF file.   //
  37  // Copyright (C) 2004-2005 Renato Coelho                                    //
  38  // This script may be distributed as long as the following files are kept   //
  39  // together:                                                                                 //
  40  //                                                                                      //
  41  // fpdf.php, html2fpdf.php, gif.php,htmltoolkit.php,license.txt,credits.txt //
  42  //                                                                          //
  43  //////////////////////////////////////////////////////////////////////////////
  44  
  45  Misc. Observations:
  46  - CSS + align = bug! (?)
  47  OBS1: para textos de mais de 1 página, talvez tenha que juntar varios $texto_artigo
  48  antes de mandar gerar o PDF, para que o PDF gerado seja completo.
  49  OBS2: there are 2 types of spaces 32 and 160 (ascii values)
  50  OBS3: //! is a special comment to be used with source2doc.php, a script I created
  51  in order to generate the doc on the site html2fpdf.sf.net
  52  OBS4: var $LineWidth; // line width in user unit - use this to make css thin/medium/thick work
  53  OBS5: Images and Textareas: when they are inserted you can only type below them (==display:block)
  54  OBS6: Optimized to 'A4' paper (default font: Arial , normal , size 11 )
  55  OBS7: Regexp + Perl ([preg]accepts non-greedy quantifiers while PHP[ereg] does not)
  56  Perl:  '/regexp/x'  where x == option ( x = i:ignore case , x = s: DOT gets \n as well)
  57  ========================END OF INITIAL COMMENTS=================================
  58  */
  59  
  60  define( 'HTML2FPDF_VERSION', '3.0(beta)' );
  61  if ( !defined( 'RELATIVE_PATH' ) ) define( 'RELATIVE_PATH', '' );
  62  if ( !defined( 'FPDF_FONTPATH' ) ) define( 'FPDF_FONTPATH', 'font/' );
  63  if ( !defined( 'REGEXP_NOENDTAG' ) ) define( 'REGEXP_NOENDTAG', '^(BR|INPUT|IMG|HR)$' );
  64  require_once ( RELATIVE_PATH . 'fpdf.php' );
  65  require_once ( RELATIVE_PATH . 'htmltoolkit.php' );
  66  
  67  class HTML2FPDF extends FPDF {
  68      // internal attributes
  69      var $HREF; //! string
  70      var $pgwidth; //! float
  71      var $fontlist; //! array
  72      var $issetfont; //! bool
  73      var $issetcolor; //! bool
  74      var $titulo; //! string
  75      var $oldx; //! float
  76      var $oldy; //! float
  77      var $B; //! int
  78      var $U; //! int
  79      var $I; //! int
  80  
  81      var $tablestart; //! bool
  82      var $tdbegin; //! bool
  83      var $table; //! array
  84      var $cell; //! array
  85      var $col; //! int
  86      var $row; //! int
  87  
  88      var $divbegin; //! bool
  89      var $divalign; //! char
  90      var $divwidth; //! float
  91      var $divheight; //! float
  92      var $divbgcolor; //! bool
  93      var $divcolor; //! bool
  94      var $divborder; //! int
  95      var $divrevert; //! bool
  96  
  97      var $listlvl; //! int
  98      var $listnum; //! int
  99      var $listtype; //! string
 100      // array(lvl,# of occurrences)
 101      var $listoccur; //! array
 102      // array(lvl,occurrence,type,maxnum)
 103      var $listlist; //! array
 104      // array(lvl,num,content,type)
 105      var $listitem; //! array
 106  
 107      var $buffer_on; //! bool
 108      var $pbegin; //! bool
 109      var $pjustfinished; //! bool
 110      var $blockjustfinished; //! bool
 111      var $SUP; //! bool
 112      var $SUB; //! bool
 113      var $toupper; //! bool
 114      var $tolower; //! bool
 115      var $dash_on; //! bool
 116      var $dotted_on; //! bool
 117      var $strike; //! bool
 118  
 119      var $CSS; //! array
 120      var $CSSbackup; //! array
 121      var $CSSbackupTag; //! array
 122      var $CSSbackupChanged; //! array
 123      var $CSSproperties; //! array
 124      var $textbuffer; //! array
 125      var $currentstyle; //! string
 126      var $currentfont; //! string
 127      var $colorarray; //! array
 128      var $bgcolorarray; //! array
 129      var $internallink; //! array
 130      var $enabledtags; //! string
 131      var $isdisplay; //! bool  When false, do not display current tags.
 132  
 133      var $lineheight; //! int
 134      var $urlbasepath; //! string
 135      var $urllevels; // !int The URL depth to the filebasepath
 136      var $filebasepath; //! string
 137      var $basepath; //! string
 138      // array('COLOR','WIDTH','OLDWIDTH')
 139      var $outlineparam; //! array
 140      var $outline_on; //! bool
 141  
 142      var $specialcontent; //! string
 143      var $selectoption; //! array
 144  
 145      // options attributes
 146      var $usecss; //! bool
 147      var $usepre; //! bool
 148      var $usetableheader; //! bool
 149      var $shownoimg; //! bool
 150      var $debug_str; //! string
 151  
 152  	function HTML2FPDF( $orientation = 'P', $unit = 'mm', $format = 'A4' )
 153      {
 154          // ! @desc Constructor
 155          // ! @return An object (a class instance)
 156          // Call parent constructor
 157          $this->FPDF( $orientation, $unit, $format );
 158          // To make the function Footer() work properly
 159          $this->AliasNbPages();
 160          // Enable all tags as default
 161          $this->DisableTags();
 162          // Set default display preferences
 163          $this->DisplayPreferences( '' );
 164          // Initialization of the attributes
 165          $this->SetFont( 'Helvetica', '', 11 ); // Changeable?(not yet...)
 166          $this->lineheight = 5; // Related to FontSizePt == 11
 167          $this->pgwidth = $this->fw - $this->lMargin - $this->rMargin ;
 168          $this->SetFillColor( 255 );
 169          $this->HREF = '';
 170          $this->titulo = '';
 171          $this->oldx = -1;
 172          $this->oldy = -1;
 173          $this->B = 0;
 174          $this->U = 0;
 175          $this->I = 0;
 176          $this->listlvl = 0;
 177          $this->listnum = 0;
 178          $this->listtype = '';
 179          $this->listoccur = array();
 180          $this->listlist = array();
 181          $this->listitem = array();
 182  
 183          $this->tablestart = false;
 184          $this->tdbegin = false;
 185          $this->table = array();
 186          $this->cell = array();
 187          $this->col = -1;
 188          $this->row = -1;
 189  
 190          $this->divbegin = false;
 191          $this->divalign = "L";
 192          $this->divwidth = 0;
 193          $this->divheight = 0;
 194          $this->divbgcolor = false;
 195          $this->divcolor = false;
 196          $this->divborder = 0;
 197          $this->divrevert = false;
 198          $this->fontlist = array( "arial", "times", "courier", "helvetica", "symbol", "monospace", "serif", "sans" );
 199          $this->issetfont = false;
 200          $this->issetcolor = false;
 201          $this->isdisplay = true;
 202  
 203          $this->pbegin = false;
 204          $this->pjustfinished = false;
 205          $this->blockjustfinished = true; //in order to eliminate exceeding left-side spaces
 206          $this->toupper = false;
 207          $this->tolower = false;
 208          $this->dash_on = false;
 209          $this->dotted_on = false;
 210          $this->SUP = false;
 211          $this->SUB = false;
 212          $this->buffer_on = false;
 213          $this->strike = false;
 214  
 215          $this->currentfont = '';
 216          $this->currentstyle = '';
 217          $this->colorarray = array();
 218          $this->bgcolorarray = array();
 219          $this->textbuffer = array();
 220          $this->CSS = array();
 221          $this->CSSbackup = array();
 222          $this->CSSbackupTag = array();
 223          $this->CSSbackupChanged = array();
 224          $this->CSSproperties = array();
 225          $this->internallink = array();
 226  
 227          $this->urlbasepath = "";
 228          $this->filebasepath = "";
 229  
 230          $this->outlineparam = array();
 231          $this->outline_on = false;
 232  
 233          $this->specialcontent = '';
 234          $this->selectoption = array();
 235  
 236          $this->shownoimg = false;
 237          $this->usetableheader = false;
 238          $this->usecss = true;
 239          $this->usepre = true;
 240          $this->debug_str = "";
 241      }
 242  
 243  	function debug( $msg )
 244      {
 245          // ! @desc Add a message to the debug messages
 246          // ! @return void
 247          $this->debug_str .= $msg;
 248      }
 249  
 250  	function debug_out()
 251      {
 252          // ! @desc Send debug information to the output
 253          // ! @return void
 254          print $this->debug_str;
 255      }
 256  
 257  	function setURLBasePath( $str )
 258      {
 259          // ! @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.
 260          // ! @return void
 261          $this->urlbasepath = $str . "/";
 262          if ( $this->filebasepath == '' ) {
 263              $this->basepath = str_replace( "\\", "/", $this->urlbasepath ); //If on Windows
 264              $urllevels = substr_count( '/', ereg_replace( '^.*?://', $this->urlbasepath ) );
 265          } ;
 266      }
 267  
 268  	function setBasePath( $str )
 269      {
 270          // legacy implementation
 271          if ( ereg( '^(http|https|ftp|file):\\/\\/', $str ) ) {
 272              $this->filebasepath = '';
 273              $this->setURLBasePath( dirname( $str ) );
 274          } else {
 275              $this->urlfilebasepath = '';
 276              $this->setFileBasePath( dirname( $str ) );
 277          }
 278      }
 279  
 280  	function setFileBasePath( $str )
 281      {
 282          // ! @desc Inform the script where the html file is (full file path) in order to adjust HREF and SRC links. No-Parameter: The directory where this script is.
 283          // ! @return void
 284          $this->filebasepath = $str . "/";
 285          $this->filebasepath = str_replace( "\\", "/", $this->filebasepath ); //If on Windows
 286          if ( $this->urlbasepath == '' ) {
 287              $this->basepath = $this->filebasepath;
 288          }
 289      }
 290  
 291  	function setURLLevels( $levels )
 292      {
 293          $this->urllevels = $levels;
 294      }
 295  
 296  	function ShowNOIMG_GIF( $opt = true )
 297      {
 298          // ! @desc Enable/Disable Displaying the no_img.gif when an image is not found. No-Parameter: Enable
 299          // ! @return void
 300          $this->shownoimg = $opt;
 301      }
 302  
 303  	function UseCSS( $opt = true )
 304      {
 305          // ! @desc Enable/Disable CSS recognition. No-Parameter: Enable
 306          // ! @return void
 307          $this->usecss = $opt;
 308      }
 309  
 310  	function UseTableHeader( $opt = true )
 311      {
 312          // ! @desc Enable/Disable Table Header to appear every new page. No-Parameter: Enable
 313          // ! @return void
 314          $this->usetableheader = $opt;
 315      }
 316  
 317  	function UsePRE( $opt = true )
 318      {
 319          // ! @desc Enable/Disable pre tag recognition. No-Parameter: Enable
 320          // ! @return void
 321          $this->usepre = $opt;
 322      }
 323  
 324  	function RevertCSSproperties( $tag )
 325      {
 326          // ! @desc Restore previous properties from stack
 327          // ! @return void
 328          // revert until the matching opening tag is found
 329          $this->debug( "End of $tag}<br>" );
 330          $found = false;
 331          while ( !empty( $this->CSSbackupTag ) && !$found ) {
 332              $found = ( ( $ltag = array_pop( $this->CSSbackupTag ) ) == $tag );
 333              // $this->debug("End of ${tag}: $ltag<br>");
 334              // As long as the corresponding opening tag is not found
 335              if ( empty( $this->CSSbackupTag ) ) {
 336                  array_pop( $this->CSSbackup );
 337                  $this->CSSproperties = array();
 338                  $this->Reset();
 339                  $this->SetCSS( array() );
 340                  $this->debug( "Empty list -> Empty CSS end $tag}<br>" );
 341              } elseif ( $change = array_pop( $this->CSSbackupChanged ) ) {
 342                  $this->CSSproperties = array();
 343                  $this->Reset();
 344                  $this->SetCSS( array_pop( $this->CSSbackup ) );
 345                  $this->debug( "Revert CSS $ltag} on end of $tag}<br>" );
 346              } else {
 347                  array_pop( $this->CSSbackup );
 348                  $this->debug( "Popped $ltag} (changed=$change) on end of $tag}<br>" );
 349              }
 350          }
 351      }
 352  
 353  	function StoreCSSproperties( $tag )
 354      {
 355          // ! @desc Store current properties on stack
 356          // ! @return void
 357          // if(count($this->CSSbackupTag)>0) {
 358          // $ltag=$this->CSSbackupTag[count($this->CSSbackupTag)-1];
 359          // //      $this->debug("Test old:${ltag} <br>");
 360          // //////////////////////////////////////////////////
 361          // // TODO: May need this for tags in which a CSS is specified up to the next boundary (<p>??)
 362          // //////////////////////////////////////////////////
 363          // if(ereg(REGEXP_NOENDTAG, $ltag)) {
 364          // // Previous tag does not have CloseTag.
 365          // // Restore CSS
 366          // $this->debug("Forced revert of ${ltag}<br>");
 367          // $this->RevertCSSproperties($ltag);
 368          // }
 369          // }
 370          $this->debug( "Start of $tag}<br>" );
 371          $this->CSSbackup[] = $this->CSSproperties;
 372          $this->CSSbackupTag[] = $tag;
 373          // $this->debug("Count".count($this->CSSbackupTag)."<br>");
 374          $this->CSSbackupChanged[] = 0; // Indicate that there is no change on the CSS (yet)
 375      }
 376  
 377  	function SetCSSonEndOfOpenTag( $tag )
 378      {
 379          // ! @desc Check if the Tag just opened should be closed immediately.
 380          // ! @return void
 381          if ( count( $this->CSSbackupTag ) > 0 ) {
 382              $ltag = $this->CSSbackupTag[count( $this->CSSbackupTag )-1];
 383              // $this->debug("Test old:${ltag} <br>");
 384              // ////////////////////////////////////////////////
 385              // TODO: Verify this list of tags without endtags
 386              // ////////////////////////////////////////////////
 387              if ( ereg( REGEXP_NOENDTAG, $ltag ) ) {
 388                  // Previous tag does not have CloseTag.
 389                  // Restore CSS
 390                  $this->debug( "Forced revert of $ltag}<br>" );
 391                  $this->RevertCSSproperties( $ltag );
 392              }
 393          }
 394      }
 395  
 396  	function SetCSSchanged( $properties )
 397      {
 398          // ! @desc Indicate that the CSS changed and a revert will be needed
 399          // ! @return void
 400          $this->debug( "Change of CSS<br>" );
 401          $this->CSSbackupChanged[count( $this->CSSbackupChanged )-1] = 1;
 402          $this->SetCSS( $properties );
 403      }
 404      // Page header
 405  	function Header( $content = '' )
 406      {
 407          // ! @return void
 408          // ! @desc The header is printed in every page.
 409          if ( $this->usetableheader && $content != '' ) {
 410              $y = $this->y;
 411              foreach( $content as $tableheader ) {
 412                  $this->y = $y;
 413                  // Set some cell values
 414                  $x = $tableheader['x'];
 415                  $w = $tableheader['w'];
 416                  $h = $tableheader['h'];
 417                  $va = $tableheader['va'];
 418                  $mih = $tableheader['mih'];
 419                  $fill = $tableheader['bgcolor'];
 420                  $border = $tableheader['border'];
 421                  $align = $tableheader['a'];
 422                  // Align
 423                  $this->divalign = $align;
 424                  $this->x = $x;
 425                  // Vertical align
 426                  if ( !isset( $va ) || $va == 'M' ) $this->y += ( $h - $mih ) / 2;
 427                  elseif ( isset( $va ) && $va == 'B' ) $this->y += $h - $mih;
 428                  if ( $fill ) {
 429                      $color = ConvertColor( $fill );
 430                      $this->SetFillColor( $color['R'], $color['G'], $color['B'] );
 431                      $this->Rect( $x, $y, $w, $h, 'F' );
 432                  }
 433                  // Border
 434                  if ( isset( $border ) && $border != 'all' ) $this->_tableRect( $x, $y, $w, $h, $border );
 435                  elseif ( isset( $border ) && $border == 'all' ) $this->Rect( $x, $y, $w, $h );
 436                  // Print cell content
 437                  $this->divwidth = $w-2;
 438                  $this->divheight = 1.1 * $this->lineheight;
 439                  $textbuffer = $tableheader['textbuffer'];
 440                  if ( !empty( $textbuffer ) ) $this->printbuffer( $textbuffer, false, true/*inside a table*/ );
 441                  $textbuffer = array();
 442              }
 443              $this->y = $y + $h; //Update y coordinate
 444          } //end of 'if usetableheader ...'
 445      }
 446      // Page footer
 447  	function Footer()
 448      {
 449          // ! @return void
 450          // ! @desc The footer is printed in every page!
 451          // Position at 1.0 cm from bottom
 452          $this->SetY( -10 );
 453          // Copyright //especial para esta versăo
 454          $this->SetFont( 'Helvetica', 'B', 9 );
 455          $this->SetTextColor( 0 );
 456          // Arial italic 9
 457          $this->SetFont( 'Helvetica', 'I', 9 );
 458          // Page number
 459          $this->Cell( 0, 10, $this->PageNo() . '/{nb}', 0, 0, 'C' );
 460          // Return Font to normal
 461          $this->SetFont( 'Helvetica', '', 11 );
 462      }
 463  
 464  	function GetAbsPath( $orgpath )
 465      {
 466          // Get link info and obtain its absolute path
 467          $path = str_replace( "\\", "/", $orgpath ); //If on Windows
 468          $regexp = '|^(\\./)+|';
 469          $path = preg_replace( $regexp, '', $path ); // Remove useless leading ./
 470          if ( $path{0} != '#' ) { // It is not an Internal Link
 471              if ( strpos( $path, "../" ) !== false ) { // It is a Relative Link
 472                  $backtrackamount = substr_count( $path, "../" );
 473                  $maxbacktrack = $this->urllevels - 1;
 474                  $filepath = str_replace( "../", '', $path );
 475                  $path = $this->basepath;
 476                  // If it is an invalid relative link, then make it go to directory root
 477                  if ( $backtrackamount > $maxbacktrack )
 478                      $backtrackamount = $maxbacktrack;
 479                  // Backtrack some directories
 480                  for( $i = 0 ; $i < $backtrackamount + 1 ; $i++ )
 481                  $path = substr( $path, 0 , strrpos( $path, "/" ) );
 482                  $path = $path . "/" . $filepath; //Make it an absolute path
 483              } elseif ( strpos( $path, ":/" ) === false ) { // It is a Local Link
 484                  $path = $this->basepath . ereg_replace( "^/([^/]*/){" . $this->urllevels . "}", '', $path );
 485                  $this->debug( "^/([^/]*/){" . $this->urllevels . "}" );
 486              }
 487              $this->debug( "GetAbsPath $orgpath -> $path<br>" );
 488              return $path;
 489          }
 490      }
 491      // /////////////////
 492      // / HTML parser ///
 493      // /////////////////
 494  	function getTagAndAttrs( $element, &$tag, &$attr )
 495      {
 496          $regexp = '|=\'(.*?)\'|s'; // eliminate single quotes, if any
 497          $element = preg_replace( $regexp, "=\"\$1\"", $element );
 498          $regexp = '|\\s(\\w+?)=([^\\s>"]+)|si'; // changes anykey=anyvalue to anykey="anyvalue" (only do this when this happens inside tags)
 499          $element = preg_replace( $regexp, " \$1=\"\$2\"", $element );
 500  
 501          preg_match_all( '/\\S*=["\'][^"\']*["\']/', $element, $contents );
 502          preg_match( '/\\S+/', $element, $a2 );
 503          $tag = strtoupper( $a2[0] );
 504          $attr = array();
 505          if ( !empty( $contents ) ) {
 506              foreach( $contents[0] as $v ) {
 507                  if ( ereg( '^([^=]*)=["\']?([^"\']*)["\']?$', $v, $a3 ) ) {
 508                      $attr[strtoupper( $a3[1] )] = $a3[2];
 509                  }
 510              }
 511          }
 512          // Fix path values, if needed
 513          if ( isset( $attr['HREF'] ) ) {
 514              $attr['HREF'] = $this->GetAbsPath( $attr['HREF'] );
 515          } ;
 516          if ( isset( $attr['SRC'] ) ) {
 517              $attr['SRC'] = $this->GetAbsPath( $attr['SRC'] );
 518          } ;
 519      }
 520  
 521  	function WriteHTML( $html )
 522      {
 523          // ! @desc HTML parser
 524          // ! @return void
 525          /* $e == content */
 526  
 527          $this->ReadMetaTags( $html );
 528          $html = AdjustHTML( $html, $this->usepre ); //Try to make HTML look more like XHTML
 529          if ( $this->usecss ) $html = $this->ReadCSS( $html );
 530          // Add new supported tags in the DisableTags function
 531          $html = str_replace( '<?', '< ', $html ); //Fix '<?XML' bug from HTML code generated by MS Word
 532          $html = strip_tags( $html, $this->enabledtags ); //remove all unsupported tags, but the ones inside the 'enabledtags' string
 533          // Explode the string in order to parse the HTML code
 534          $a = preg_split( '/<(.*?)>/ms', $html, -1, PREG_SPLIT_DELIM_CAPTURE );
 535  
 536          foreach( $a as $i => $e ) {
 537              if ( $i % 2 == 0 ) {
 538                  // TEXT
 539                  // Adjust lineheight
 540                  // $this->lineheight = (5*$this->FontSizePt)/11; //should be inside printbuffer?
 541                  // Adjust text, if needed
 542                  if ( strpos( $e, "&" ) !== false ) { // HTML-ENTITIES decoding
 543                      if ( strpos( $e, "#" ) !== false ) $e = value_entity_decode( $e ); // Decode value entities
 544                      // Avoid crashing the script on PHP 4.0
 545                      $version = phpversion();
 546                      $version = str_replace( '.', '', $version );
 547                      /*
 548                      if ( $version >= 430 ) $e = html_entity_decode( $e, ENT_QUOTES, 'cp1252' ); // changes &nbsp; and the like by their respective char
 549                      else $e = lesser_entity_decode( $e );
 550                      */
 551  // EDIT START
 552  // for use in phpwcms and handle given Charset there
 553                       $e = decode_entities( $e );
 554  // EDIT END
 555                  }
 556                  $e = str_replace( chr( 160 ), chr( 32 ), $e ); //unify ascii code of spaces (in order to recognize all of them correctly)
 557                  if ( strlen( $e ) == 0 ) continue;
 558                  if ( $this->divrevert ) $e = strrev( $e );
 559                  if ( $this->toupper ) $e = strtoupper( $e );
 560                  if ( $this->tolower ) $e = strtolower( $e );
 561                  // Start of 'if/elseif's
 562                  if ( $this->titulo ) {
 563                      $this->SetTitle( $e );
 564                  } elseif ( $this->specialcontent ) {
 565                      if ( $this->specialcontent == "type=select" && $this->selectoption['ACTIVE'] == true ) { // SELECT tag (form element)
 566                          $stringwidth = $this->GetStringWidth( $e );
 567                          if ( !isset( $this->selectoption['MAXWIDTH'] ) || $stringwidth > $this->selectoption['MAXWIDTH'] ) $this->selectoption['MAXWIDTH'] = $stringwidth;
 568                          if ( !isset( $this->selectoption['SELECTED'] ) || $this->selectoption['SELECTED'] == '' ) $this->selectoption['SELECTED'] = $e;
 569                      } else {
 570                          $this->textbuffer[] = array( "ť¤Ź"/*identifier*/ . $this->specialcontent . "ť¤Ź" . $e );
 571                      }
 572                  } elseif ( $this->tablestart ) {
 573                      if ( $this->tdbegin ) {
 574                          $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 );
 575                          $this->cell[$this->row][$this->col]['text'][] = $e;
 576                          $this->cell[$this->row][$this->col]['s'] += $this->GetStringWidth( $e );
 577                      }
 578                      // Ignore content between <table>,<tr> and a <td> tag (this content is usually only a bunch of spaces)
 579                  } elseif ( $this->pbegin || $this->HREF || $this->divbegin || $this->SUP || $this->SUB || $this->strike || $this->buffer_on ) {
 580                      $this->textbuffer[] = array( $e, $this->HREF,
 581                          $this->currentstyle, $this->colorarray,
 582                          $this->currentfont, $this->SUP, $this->SUB,
 583                          ''/*internal link*/, $this->strike,
 584                          $this->outlineparam, $this->bgcolorarray
 585                          ); //Accumulate text on buffer
 586                  } else {
 587                      if ( $this->blockjustfinished ) $e = ltrim( $e );
 588                      if ( $e != '' ) {
 589                          $this->Write( $this->lineheight, $e ); //Write text directly in the PDF
 590                          if ( $this->pjustfinished ) $this->pjustfinished = false;
 591                      }
 592                  }
 593              } else {
 594                  // Tag
 595                  if ( $e{0} == '/' ) {
 596                      $this->CloseTag( strtoupper( substr( $e, 1 ) ) );
 597                  } else {
 598                      // Extract attributes
 599                      $this->GetTagAndAttrs( $e, $tag, $attr );
 600                      $this->OpenTag( $tag, $attr );
 601                  }
 602              }
 603          } //end of    foreach($a as $i=>$e)
 604          // Create Internal Links, if needed
 605          if ( !empty( $this->internallink ) ) {
 606              foreach( $this->internallink as $k => $v ) {
 607                  if ( strpos( $k, "#" ) !== false ) continue; //ignore
 608                  $ypos = $v['Y'];
 609                  $pagenum = $v['PAGE'];
 610                  $sharp = "#";
 611                  while ( array_key_exists( $sharp . $k, $this->internallink ) ) {
 612                      $internallink = $this->internallink[$sharp . $k];
 613                      $this->SetLink( $internallink, $ypos, $pagenum );
 614                      $sharp .= "#";
 615                  }
 616              }
 617          }
 618      }
 619      // //////////////////////////////////////
 620  	function get_ID_properties( $tag, $id )
 621      {
 622          // //////////////////////////////////////
 623          // ! @desc get ID properties for tag
 624          // ! @return array
 625          $this->debug( "Check ID $tag#$id <br>" );
 626          if ( isset( $this->CSS_ids[$tag][$id] ) ) {
 627              $this->debug( "GOT ID $tag#$id <br>" );
 628              return $this->CSS_ids[$tag][$id];
 629          } else if ( isset( $this->CSS_ids[''][$id] ) ) {
 630              // foreach($this->CSS_ids[''] as $a => $b) $this->debug("GLOBAL $a <br>");
 631              $this->debug( "GOT ID $tag#$id <br>" );
 632              return $this->CSS_ids[''][$id];
 633          } else {
 634              return array();
 635          }
 636      }
 637      // /////////////////////////////////////////
 638  	function get_CLASS_properties( $tag, $id )
 639      {
 640          // /////////////////////////////////////////
 641          // ! @desc HTML parser
 642          // ! @return array
 643          if ( isset( $this->CSS_classes[$tag][$id] ) ) {
 644              return $this->CSS_classes[$tag][$id];
 645          } else if ( isset( $this->CSS_classes[''][$id] ) ) {
 646              return $this->CSS_classes[''][$id];
 647          } else {
 648              return array();
 649          }
 650      }
 651      // //////////////////////////////////////
 652  	function get_TAG_properties( $tag )
 653      {
 654          // //////////////////////////////////////
 655          // ! @desc get ID properties for tag
 656          // ! @return array
 657          $this->debug( "Check TAG $tag <br>" );
 658          if ( isset( $this->CSS_elements[$tag] ) ) {
 659              $this->debug( "GOT TAG $tag <br>" );
 660              return $this->CSS_elements[$tag][$id];
 661          } else {
 662              return array();
 663          }
 664      }
 665      // /////////////////////////////////////////
 666  	function OpenTag( $tag, $attr )
 667      {
 668          // /////////////////////////////////////////
 669          // ! @return void
 670          // What this gets: < $tag $attr['WIDTH']="90px" > does not get content here </closeTag here>
 671          // $this->debug("OpenTag($tag)<br>");
 672          // Handle CSS
 673          $this->StoreCSSproperties( $tag );
 674          $properties = $this->get_TAG_properties( $tag );
 675          if ( !empty( $properties ) ) {
 676              $this->SetCSSchanged( $properties ); //name found in the CSS array!
 677          }
 678          if ( isset( $attr['CLASS'] ) || isset( $attr['ID'] ) || isset( $attr['STYLE'] ) ) {
 679              if ( isset( $attr['CLASS'] ) ) {
 680                  $properties = $this->get_CLASS_properties( $tag, $attr['CLASS'] );
 681              } elseif ( isset( $attr['ID'] ) ) {
 682                  $properties = $this->get_ID_properties( $tag, $attr['ID'] );
 683              }
 684              // Read Inline CSS
 685              if ( isset( $attr['STYLE'] ) ) $properties = $this->readInlineCSS( $attr['STYLE'] );
 686              // Look for name in the $this->CSS array
 687              if ( !empty( $properties ) ) {
 688                  $this->SetCSSchanged( $properties ); //name found in the CSS array!
 689              }
 690          }
 691  
 692          $align = array( 'left' => 'L', 'center' => 'C', 'right' => 'R', 'top' => 'T', 'middle' => 'M', 'bottom' => 'B', 'justify' => 'J' );
 693  
 694          $this->blockjustfinished = false;
 695          // Opening tag
 696          switch ( $tag ) {
 697              case 'PAGE_BREAK': // custom-tag
 698              case 'NEWPAGE': // custom-tag
 699                  $this->blockjustfinished = true;
 700                  $this->AddPage();
 701                  break;
 702              case 'OUTLINE': // custom-tag (CSS2 property - browsers don't support it yet - Jan2005)
 703                  // Usage: (default: width=normal color=white)
 704                  // <outline width="(thin|medium|thick)" color="(usualcolorformat)" >Text</outline>
 705                  // Mix this tag with the <font color="(usualcolorformat)"> tag to get mixed colors on outlined text!
 706                  $this->buffer_on = true;
 707                  if ( isset( $attr['COLOR'] ) ) $this->outlineparam['COLOR'] = ConvertColor( $attr['COLOR'] );
 708                  else $this->outlineparam['COLOR'] = array( 'R' => 255, 'G' => 255, 'B' => 255 ); //white
 709                  $this->outlineparam['OLDWIDTH'] = $this->LineWidth;
 710                  if ( isset( $attr['WIDTH'] ) ) {
 711                      switch ( strtoupper( $attr['WIDTH'] ) ) {
 712                          case 'THIN': $this->outlineparam['WIDTH'] = 0.75 * $this->LineWidth;
 713                              break;
 714                          case 'MEDIUM': $this->outlineparam['WIDTH'] = $this->LineWidth;
 715                              break;
 716                          case 'THICK': $this->outlineparam['WIDTH'] = 1.75 * $this->LineWidth;
 717                              break;
 718                      }
 719                  } else {
 720                      $this->outlineparam['WIDTH'] = $this->LineWidth; //width == oldwidth
 721                  }
 722                  break;
 723              case 'BDO':
 724                  if ( isset( $attr['DIR'] ) && ( strtoupper( $attr['DIR'] ) == 'RTL' ) ) $this->divrevert = true;
 725                  break;
 726              case 'S':
 727              case 'STRIKE':
 728              case 'DEL':
 729                  $this->strike = true;
 730                  break;
 731              case 'SUB':
 732                  $this->SUB = true;
 733                  break;
 734              case 'SUP':
 735                  $this->SUP = true;
 736                  break;
 737              case 'CENTER':
 738                  $this->buffer_on = true;
 739                  if ( $this->tdbegin ) {
 740                      $this->cell[$this->row][$this->col]['a'] = $align['center'];
 741                  } else {
 742                      $this->divalign = $align['center'];
 743                      if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 744                  }
 745                  break;
 746              case 'ADDRESS':
 747                  $this->buffer_on = true;
 748                  $this->SetStyle( 'I', true );
 749                  if ( !$this->tdbegin && $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 750                  break;
 751              case 'TABLE': // TABLE-BEGIN
 752                  if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 753                  $this->tablestart = true;
 754                  $this->table['nc'] = $this->table['nr'] = 0;
 755                  if ( isset( $attr['REPEAT_HEADER'] ) && $attr['REPEAT_HEADER'] == true ) $this->UseTableHeader( true );
 756                  if ( isset( $attr['WIDTH'] ) ) $this->table['w'] = ConvertSize( $attr['WIDTH'], $this->pgwidth );
 757                  if ( isset( $attr['HEIGHT'] ) ) $this->table['h'] = ConvertSize( $attr['HEIGHT'], $this->pgwidth );
 758                  if ( isset( $attr['ALIGN'] ) ) $this->table['a'] = $align[strtolower( $attr['ALIGN'] )];
 759                  if ( isset( $attr['BORDER'] ) ) $this->table['border'] = $attr['BORDER'];
 760                  if ( isset( $attr['BGCOLOR'] ) ) $this->table['bgcolor'][-1] = $attr['BGCOLOR'];
 761                  break;
 762              case 'TR':
 763                  $this->row++;
 764                  $this->table['nr']++;
 765                  $this->col = -1;
 766                  if ( isset( $attr['BGCOLOR'] ) )$this->table['bgcolor'][$this->row] = $attr['BGCOLOR'];
 767                  break;
 768              case 'TH':
 769                  $this->SetStyle( 'B', true );
 770                  if ( !isset( $attr['ALIGN'] ) ) $attr['ALIGN'] = "center";
 771              case 'TD':
 772                  $this->tdbegin = true;
 773                  $this->col++;
 774                  while ( isset( $this->cell[$this->row][$this->col] ) ) $this->col++;
 775                  // Update number column
 776                  if ( $this->table['nc'] < $this->col + 1 ) $this->table['nc'] = $this->col + 1;
 777                  $this->cell[$this->row][$this->col] = array();
 778                  $this->cell[$this->row][$this->col]['text'] = array();
 779                  $this->cell[$this->row][$this->col]['s'] = 3;
 780                  if ( isset( $attr['WIDTH'] ) ) $this->cell[$this->row][$this->col]['w'] = ConvertSize( $attr['WIDTH'], $this->pgwidth );
 781                  if ( isset( $attr['HEIGHT'] ) ) $this->cell[$this->row][$this->col]['h'] = ConvertSize( $attr['HEIGHT'], $this->pgwidth );
 782                  if ( isset( $attr['ALIGN'] ) ) $this->cell[$this->row][$this->col]['a'] = $align[strtolower( $attr['ALIGN'] )];
 783                  if ( isset( $attr['VALIGN'] ) ) $this->cell[$this->row][$this->col]['va'] = $align[strtolower( $attr['VALIGN'] )];
 784                  if ( isset( $attr['BORDER'] ) ) $this->cell[$this->row][$this->col]['border'] = $attr['BORDER'];
 785                  if ( isset( $attr['BGCOLOR'] ) ) $this->cell[$this->row][$this->col]['bgcolor'] = $attr['BGCOLOR'];
 786                  $cs = $rs = 1;
 787                  if ( isset( $attr['COLSPAN'] ) && $attr['COLSPAN'] > 1 ) $cs = $this->cell[$this->row][$this->col]['colspan'] = $attr['COLSPAN'];
 788                  if ( isset( $attr['ROWSPAN'] ) && $attr['ROWSPAN'] > 1 ) $rs = $this->cell[$this->row][$this->col]['rowspan'] = $attr['ROWSPAN'];
 789                  // Chiem dung vi tri de danh cho cell span (żmais hein?)
 790                  for ( $k = $this->row ; $k < $this->row + $rs ;$k++ )
 791                  for( $l = $this->col; $l < $this->col + $cs ;$l++ ) {
 792                      if ( $k - $this->row || $l - $this->col ) $this->cell[$k][$l] = 0;
 793                  }
 794                  if ( isset( $attr['NOWRAP'] ) ) $this->cell[$this->row][$this->col]['nowrap'] = 1;
 795                  break;
 796              case 'OL':
 797                  if ( !isset( $attr['TYPE'] ) || $attr['TYPE'] == '' ) $this->listtype = '1'; //OL default == '1'
 798                  else $this->listtype = $attr['TYPE']; // ol and ul types are mixed here
 799                  /* fall-through (to case 'UL') */
 800              case 'UL':
 801                  if ( ( !isset( $attr['TYPE'] ) || $attr['TYPE'] == '' ) && $tag == 'UL' ) {
 802                      // Insert UL defaults
 803                      if ( $this->listlvl == 0 ) $this->listtype = 'disc';
 804                      elseif ( $this->listlvl == 1 ) $this->listtype = 'circle';
 805                      else $this->listtype = 'square';
 806                  } elseif ( isset( $attr['TYPE'] ) && $tag == 'UL' ) $this->listtype = $attr['TYPE'];
 807                  $this->buffer_on = false;
 808                  if ( $this->listlvl == 0 ) {
 809                      // First of all, skip a line
 810                      if ( !$this->pjustfinished ) {
 811                          if ( !$this->isdisplay ) if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 812                              if ( !$this->isdisplay ) $this->Ln( $this->lineheight );
 813                          }
 814                          $this->oldx = $this->x;
 815                          if ( !$this->isdisplay ) $this->listlvl++; // first depth level
 816                          $this->listnum = 0; // reset
 817                          if ( !$this->isdisplay ) $this->listoccur[$this->listlvl] = 1;
 818                          $this->listlist[$this->listlvl][1] = array( 'TYPE' => $this->listtype, 'MAXNUM' => $this->listnum );
 819                      } else {
 820                          if ( !empty( $this->textbuffer ) ) {
 821                              if ( !$this->isdisplay ) $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
 822                              if ( !$this->isdisplay ) $this->listnum++;
 823                          }
 824  
 825                          $this->textbuffer = array(); // -> vide buffer de text;
 826                          $occur = $this->listoccur[$this->listlvl];
 827                          $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
 828                          $this->listlvl++;
 829                          $this->listnum = 0; // reset
 830  
 831                          // OG 2007-04-28 check if $this->listoccur[$this->listlvl] empty
 832                          // validation against 0 is not necessary because empty checks against !isset and value=0
 833                          if ( empty($this->listoccur[$this->listlvl]) ) { //|| $this->listoccur[$this->listlvl] == 0
 834                              $this->listoccur[$this->listlvl] = 1;
 835                          } else {
 836                              $this->listoccur[$this->listlvl]++;
 837                          }
 838                          $occur = $this->listoccur[$this->listlvl];
 839                          $this->listlist[$this->listlvl][$occur] = array( 'TYPE' => $this->listtype, 'MAXNUM' => $this->listnum );
 840                      }
 841                      break;
 842              case 'LI':
 843                  if ( !$this->isdisplay ) break;
 844                  // Observation: </LI> is ignored
 845                  if ( $this->listlvl == 0 ) { // in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
 846                      // First of all, skip a line
 847                      if ( !$this->pjustfinished && $this->x != $this->lMargin ) $this->Ln( 2 * $this->lineheight );
 848                      $this->oldx = $this->x;
 849                      $this->listlvl++; // first depth level
 850                      $this->listnum = 0; // reset
 851                      $this->listoccur[$this->listlvl] = 1;
 852                      $this->listlist[$this->listlvl][1] = array( 'TYPE' => 'disc', 'MAXNUM' => $this->listnum );
 853                  }
 854                  if ( $this->listnum == 0 ) {
 855                      $this->buffer_on = true; //activate list 'bufferization'
 856                      $this->listnum++;
 857                      $this->textbuffer = array();
 858                  } else {
 859                      $this->buffer_on = true; //activate list 'bufferization'
 860                      if ( !empty( $this->textbuffer ) ) {
 861                          $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
 862                          $this->listnum++;
 863                      }
 864                      $this->textbuffer = array();
 865                  }
 866                  break;
 867              case 'H1': // 2 * fontsize
 868              case 'H2': // 1.5 * fontsize
 869              case 'H3': // 1.17 * fontsize
 870              case 'H4': // 1 * fontsize
 871              case 'H5': // 0.83 * fontsize
 872              case 'H6': // 0.67 * fontsize
 873                  // Values obtained from: http://www.w3.org/TR/REC-CSS2/sample.html
 874                  if ( isset( $attr['ALIGN'] ) ) $this->divalign = $align[strtolower( $attr['ALIGN'] )];
 875                  $this->buffer_on = true;
 876                  if ( $this->x != $this->lMargin ) $this->Ln( 2 * $this->lineheight );
 877                  elseif ( !$this->pjustfinished ) $this->Ln( $this->lineheight );
 878                  $this->SetStyle( 'B', true );
 879                  switch ( $tag ) {
 880                      case 'H1':
 881                          $this->SetFontSize( 2 * $this->FontSizePt );
 882                          $this->lineheight *= 2;
 883                          break;
 884                      case 'H2':
 885                          $this->SetFontSize( 1.5 * $this->FontSizePt );
 886                          $this->lineheight *= 1.5;
 887                          break;
 888                      case 'H3':
 889                          $this->SetFontSize( 1.17 * $this->FontSizePt );
 890                          $this->lineheight *= 1.17;
 891                          break;
 892                      case 'H4':
 893                          $this->SetFontSize( $this->FontSizePt );
 894                          break;
 895                      case 'H5':
 896                          $this->SetFontSize( 0.83 * $this->FontSizePt );
 897                          $this->lineheight *= 0.83;
 898                          break;
 899                      case 'H6':
 900                          $this->SetFontSize( 0.67 * $this->FontSizePt );
 901                          $this->lineheight *= 0.67;
 902                          break;
 903                  }
 904                  break;
 905              case 'HR': // Default values: width=100% align=center color=gray
 906                  // Skip a line, if needed
 907                  if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 908                  $this->Ln( 0.2 * $this->lineheight );
 909                  $hrwidth = $this->pgwidth;
 910                  $hralign = 'C';
 911                  $hrcolor = array( 'R' => 200, 'G' => 200, 'B' => 200 );
 912                  if ( isset( $attr['WIDTH'] ) ) $hrwidth = ConvertSize( $attr['WIDTH'], $this->pgwidth );
 913                  if ( isset( $attr['ALIGN'] ) ) $hralign = $align[strtolower( $attr['ALIGN'] )];
 914                  if ( isset( $attr['COLOR'] ) ) $hrcolor = ConvertColor( $attr['COLOR'] );
 915                  $this->SetDrawColor( $hrcolor['R'], $hrcolor['G'], $hrcolor['B'] );
 916                  $x = $this->x;
 917                  $y = $this->y;
 918                  switch ( $hralign ) {
 919                      case 'L':
 920                      case 'J':
 921                          break;
 922                      case 'C':
 923                          $empty = $this->pgwidth - $hrwidth;
 924                          $empty /= 2;
 925                          $x += $empty;
 926                          break;
 927                      case 'R':
 928                          $empty = $this->pgwidth - $hrwidth;
 929                          $x += $empty;
 930                          break;
 931                  }
 932                  $oldlinewidth = $this->LineWidth;
 933                  $this->SetLineWidth( 0.3 );
 934                  $this->Line( $x, $y, $x + $hrwidth, $y );
 935                  $this->SetLineWidth( $oldlinewidth );
 936                  $this->Ln( 0.2 * $this->lineheight );
 937                  $this->SetDrawColor( 0 );
 938                  $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
 939                  break;
 940              case 'SMALL':
 941                  $newsize = $this->FontSizePt - 1;
 942                  $this->SetFontSize( $newsize );
 943                  break;
 944              case 'BIG':
 945                  $newsize = $this->FontSizePt + 1;
 946                  $this->SetFontSize( $newsize );
 947              case 'TITLE':
 948                  $this->titulo = true;
 949                  break;
 950              case 'STRONG':
 951                  $this->SetStyle( 'B', true );
 952                  break;
 953              case 'CITE':
 954              case 'EM':
 955                  $this->SetStyle( 'I', true );
 956                  break;
 957              case 'INS':
 958                  $this->SetStyle( 'U', true );
 959                  break;
 960              case 'B':
 961              case 'I':
 962              case 'U':
 963                  $this->SetStyle( $tag, true );
 964                  break;
 965  
 966              case 'A':
 967                  if ( isset( $attr['NAME'] ) && $attr['NAME'] != '' ) $this->textbuffer[] = array( '', '', '', array(), '', false, false, $attr['NAME'] ); //an internal link (adds a space for recognition)
 968                  if ( isset( $attr['HREF'] ) ) $this->HREF = $attr['HREF'];
 969                  break;
 970              case 'DIV':
 971                  // in case of malformed HTML code. Example:(...)</div><li>Content</li><div>DIV1</div>(...)
 972                  if ( $this->listlvl > 0 ) { // We are closing (omitted) OL/UL tag(s)
 973                      $this->buffer_on = false;
 974                      if ( !empty( $this->textbuffer ) ) $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
 975                      $this->textbuffer = array();
 976                      $this->listlvl--;
 977                      $this->printlistbuffer();
 978                      $this->pjustfinished = true; //act as if a paragraph just ended
 979                  }
 980                  $this->divbegin = true;
 981                  if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
 982                  if ( isset( $attr['ALIGN'] ) && $attr['ALIGN'] != '' ) $this->divalign = $align[strtolower( $attr['ALIGN'] )];
 983                  break;
 984              case 'IMG':
 985                  if ( !$this->isdisplay ) break;
 986                  if ( !empty( $this->textbuffer ) && !$this->tablestart ) {
 987                      // Output previously buffered content and output image below
 988                      // Set some default values
 989                      $olddivwidth = $this->divwidth;
 990                      $olddivheight = $this->divheight;
 991                      if ( $this->divwidth == 0 ) $this->divwidth = $this->pgwidth - $this->x + $this->lMargin;
 992                      if ( $this->divheight == 0 ) $this->divheight = $this->lineheight;
 993                      // Print content
 994                      $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
 995                      $this->textbuffer = array();
 996                      // Reset values
 997                      $this->divwidth = $olddivwidth;
 998                      $this->divheight = $olddivheight;
 999                      $this->textbuffer = array();
1000                      $this->Ln( $this->lineheight );
1001                  }
1002                  if ( isset( $attr['SRC'] ) ) {
1003                      $srcpath = $attr['SRC'];
1004                      if ( !isset( $attr['WIDTH'] ) ) {
1005                          $attr['WIDTH'] = 0;
1006                      } else {
1007                          $attr['WIDTH'] = ConvertSize( $attr['WIDTH'], $this->pgwidth ); //$attr['WIDTH'] /= 4;
1008                      }
1009                      if ( !isset( $attr['HEIGHT'] ) ) {
1010                          $attr['HEIGHT'] = 0;
1011                      } else {
1012                          $attr['HEIGHT'] = ConvertSize( $attr['HEIGHT'], $this->pgwidth ); //$attr['HEIGHT'] /= 4;
1013                      }
1014                      
1015                      // Edited by Oliver Georgi, 2007-04-30 to better handle src having NO width
1016                      // you often see file extensions like *.php?do and so on...
1017                      // with old style checking it will always fail
1018                      
1019                      $f_exists = @fopen($srcpath, 'rb');
1020                      
1021                      if($attr['WIDTH'] == 0 || $attr['HEIGHT'] == 0) {
1022                      
1023                          if($f_exists) {
1024                          
1025                              $imgdata = getimagesize($srcpath);
1026  
1027                              if(isset($imgdata[0]) && isset($imgdata[1])) {
1028                                  
1029                                  $attr['WIDTH']    = ConvertSize($imgdata[0], $this->pgwidth);
1030                                  $attr['HEIGHT']    = ConvertSize($imgdata[1], $this->pgwidth );
1031  
1032                              }
1033  
1034                          }
1035                  
1036                      }
1037                      // End OG
1038                      
1039                      
1040                      if ( $this->tdbegin ) {
1041                          $bak_x = $this->x;
1042                          $bak_y = $this->y;
1043                          // Check whether image exists locally or on the URL
1044                          // $f_exists = @fopen( $srcpath, "rb" );    //Edited by Oliver Georgi, 2007-04-30
1045                          if ( !$f_exists ) { // Show 'image not found' icon instead
1046                              if ( !$this->shownoimg ) break;
1047                              $srcpath = str_replace( "\\", "/", dirname( __FILE__ ) ) . "/";
1048                              $srcpath .= 'no_img.gif';
1049                          }
1050                          $sizesarray = $this->Image( $srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'], '', '', false );
1051                          $this->y = $bak_y;
1052                          $this->x = $bak_x;
1053                      } elseif ( $this->pbegin || $this->divbegin ) {
1054                          // In order to support <div align='center'><img ...></div>
1055                          $ypos = 0;
1056                          $bak_x = $this->x;
1057                          $bak_y = $this->y;
1058                          // Check whether image exists locally or on the URL
1059                          //$f_exists = @fopen( $srcpath, "rb" );    //Edited by Oliver Georgi, 2007-04-30
1060                          if ( !$f_exists ) { // Show 'image not found' icon instead
1061                              if ( !$this->shownoimg ) break;
1062                              $srcpath = str_replace( "\\", "/", dirname( __FILE__ ) ) . "/";
1063                              $srcpath .= 'no_img.gif';
1064                          }
1065                          $sizesarray = $this->Image( $srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'], '', '', false );
1066                          $this->y = $bak_y;
1067                          $this->x = $bak_x;
1068                          $xpos = '';
1069                          switch ( $this->divalign ) {
1070                              case "C":
1071                                  $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1072                                  $empty = ( $this->pgwidth - $sizesarray['WIDTH'] ) / 2;
1073                                  $xpos = 'xpos=' . $empty . ',';
1074                                  break;
1075                              case "R":
1076                                  $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1077                                  $empty = ( $this->pgwidth - $sizesarray['WIDTH'] );
1078                                  $xpos = 'xpos=' . $empty . ',';
1079                                  break;
1080                              default: break;
1081                          }
1082                          $numberoflines = ( integer )ceil( $sizesarray['HEIGHT'] / $this->lineheight ) ;
1083                          $ypos = $numberoflines * $this->lineheight;
1084                          $this->textbuffer[] = array( "ť¤Ź"/*identifier*/ . "type=image,ypos=$ypos,{$xpos}width=" . $sizesarray['WIDTH'] . ",height=" . $sizesarray['HEIGHT'] . "ť¤Ź" . $sizesarray['OUTPUT'] );
1085                          while ( $numberoflines ) {
1086                              $this->textbuffer[] = array( "\n", $this->HREF, $this->currentstyle, $this->colorarray, $this->currentfont, $this->SUP, $this->SUB, ''/*internal link*/, $this->strike, $this->outlineparam, $this->bgcolorarray );
1087                              $numberoflines--;
1088                          }
1089                      } else {
1090                          $imgborder = 0;
1091                          if ( isset( $attr['BORDER'] ) ) $imgborder = ConvertSize( $attr['BORDER'], $this->pgwidth );
1092                          // Check whether image exists locally or on the URL
1093                          //$f_exists = @fopen( $srcpath, "rb" );    //Edited by Oliver Georgi, 2007-04-30
1094                          if ( !$f_exists ) { // Show 'image not found' icon instead
1095                              $srcpath = str_replace( "\\", "/", dirname( __FILE__ ) ) . "/";
1096                              $srcpath .= 'no_img.gif';
1097                          }
1098                          $sizesarray = $this->Image( $srcpath, $this->GetX(), $this->GetY(), $attr['WIDTH'], $attr['HEIGHT'], '', $this->HREF ); //Output Image
1099                          $ini_x = $sizesarray['X'];
1100                          $ini_y = $sizesarray['Y'];
1101                          if ( $imgborder ) {
1102                              $oldlinewidth = $this->LineWidth;
1103                              $this->SetLineWidth( $imgborder );
1104                              $this->Rect( $ini_x, $ini_y, $sizesarray['WIDTH'], $sizesarray['HEIGHT'] );
1105                              $this->SetLineWidth( $oldlinewidth );
1106                          }
1107                      }
1108                      if ( $sizesarray['X'] < $this->x ) $this->x = $this->lMargin;
1109                      if ( $this->tablestart ) {
1110                          $this->cell[$this->row][$this->col]['textbuffer'][] = array( "ť¤Ź"/*identifier*/ . "type=image,width=" . $sizesarray['WIDTH'] . ",height=" . $sizesarray['HEIGHT'] . "ť¤Ź" . $sizesarray['OUTPUT'] );
1111                          $this->cell[$this->row][$this->col]['s'] += $sizesarray['WIDTH'] + 1; // +1 == margin
1112                          $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
1113                          if ( !isset( $this->cell[$this->row][$this->col]['w'] ) ) $this->cell[$this->row][$this->col]['w'] = $sizesarray['WIDTH'] + 3;
1114                          if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $sizesarray['HEIGHT'] + 3;
1115                      }
1116                  }
1117                  break;
1118              case 'BLOCKQUOTE':
1119              case 'BR':
1120                  if ( $this->tablestart ) {
1121                      $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 );
1122                      $this->cell[$this->row][$this->col]['text'][] = "\n";
1123                      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
1124                      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
1125                      $this->cell[$this->row][$this->col]['s'] = 0; // reset
1126                  } elseif ( $this->divbegin || $this->pbegin || $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 );
1127                  else {
1128                      $this->Ln( $this->lineheight );
1129                      $this->blockjustfinished = true;
1130                  }
1131                  break;
1132              case 'P':
1133                  // in case of malformed HTML code. Example:(...)</p><li>Content</li><p>Paragraph1</p>(...)
1134                  if ( $this->listlvl > 0 ) { // We are closing (omitted) OL/UL tag(s)
1135                      $this->buffer_on = false;
1136                      if ( !empty( $this->textbuffer ) ) $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
1137                      $this->textbuffer = array();
1138                      $this->listlvl--;
1139                      $this->printlistbuffer();
1140                      $this->pjustfinished = true; //act as if a paragraph just ended
1141                  }
1142                  if ( $this->tablestart ) {
1143                      $this->cell[$this->row][$this->col]['textbuffer'][] = array( ""/* previous: $e, UNDEF:BUG? */ ,
1144                          $this->HREF,
1145                          $this->currentstyle, $this->colorarray,
1146                          $this->currentfont, $this->SUP, $this->SUB,
1147                          ''/*internal link*/,
1148                          $this->strike,
1149                          $this->outlineparam,
1150                          $this->bgcolorarray
1151                          );
1152                      $this->cell[$this->row][$this->col]['text'][] = "\n";
1153                      break;
1154                  }
1155                  $this->pbegin = true;
1156                  if ( $this->x != $this->lMargin ) $this->Ln( 2 * $this->lineheight );
1157                  elseif ( !$this->pjustfinished ) $this->Ln( $this->lineheight );
1158                  // Save x,y coords in case we need to print borders...
1159                  $this->oldx = $this->x;
1160                  $this->oldy = $this->y;
1161                  if ( isset( $attr['ALIGN'] ) ) $this->divalign = $align[strtolower( $attr['ALIGN'] )];
1162                  break;
1163              case 'SPAN':
1164                  $this->buffer_on = true;
1165                  // Save x,y coords in case we need to print borders...
1166                  $this->oldx = $this->x;
1167                  $this->oldy = $this->y;
1168                  break;
1169              case 'PRE':
1170                  if ( $this->tablestart ) {
1171                      $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 );
1172                      $this->cell[$this->row][$this->col]['text'][] = "\n";
1173                  } elseif ( $this->divbegin || $this->pbegin || $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 );
1174                  else {
1175                      if ( $this->x != $this->lMargin ) $this->Ln( 2 * $this->lineheight );
1176                      elseif ( !$this->pjustfinished ) $this->Ln( $this->lineheight );
1177                      $this->buffer_on = true;
1178                      // Save x,y coords in case we need to print borders...
1179                      $this->oldx = $this->x;
1180                      $this->oldy = $this->y;
1181                      if ( isset( $attr['ALIGN'] ) ) $this->divalign = $align[strtolower( $attr['ALIGN'] )];
1182                  }
1183              case 'TT':
1184              case 'KBD':
1185              case 'SAMP':
1186              case 'CODE':
1187                  $this->SetFont( 'courier' );
1188                  $this->currentfont = 'courier';
1189                  break;
1190              case 'TEXTAREA':
1191                  $this->buffer_on = true;
1192                  $colsize = 20; //HTML default value
1193                  $rowsize = 2; //HTML default value
1194                  if ( isset( $attr['COLS'] ) ) $colsize = $attr['COLS'];
1195                  if ( isset( $attr['ROWS'] ) ) $rowsize = $attr['ROWS'];
1196                  if ( !$this->tablestart ) {
1197                      if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
1198                      $this->col = $colsize;
1199                      $this->row = $rowsize;
1200                  } else { // it is inside a table
1201                      $this->specialcontent = "type=textarea,lines=$rowsize,width=" . ( ( 2.2 * $colsize ) + 3 ); //Activate form info in order to paint FORM elements within table
1202                      $this->cell[$this->row][$this->col]['s'] += ( 2.2 * $colsize ) + 6; // +6 == margin
1203                      if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = 1.1 * $this->lineheight * $rowsize + 2.5;
1204                  }
1205                  break;
1206              case 'SELECT':
1207                  $this->specialcontent = "type=select"; //Activate form info in order to paint FORM elements within table
1208                  break;
1209              case 'OPTION':
1210                  $this->selectoption['ACTIVE'] = true;
1211                  if ( empty( $this->selectoption ) ) {
1212                      $this->selectoption['MAXWIDTH'] = '';
1213                      $this->selectoption['SELECTED'] = '';
1214                  }
1215                  if ( isset( $attr['SELECTED'] ) ) $this->selectoption['SELECTED'] = '';
1216                  break;
1217              case 'FORM':
1218                  if ( $this->tablestart ) {
1219                      $this->cell[$this->row][$this->col]['textbuffer'][] = array( ""/*previous $e: UNDEF = BUG?*/ ,
1220                          $this->HREF,
1221                          $this->currentstyle,
1222                          $this->colorarray,
1223                          $this->currentfont,
1224                          $this->SUP,
1225                          $this->SUB,
1226                          ''/*internal link*/,
1227                          $this->strike,
1228                          $this->outlineparam,
1229                          $this->bgcolorarray );
1230                      $this->cell[$this->row][$this->col]['text'][] = "\n";
1231                  } elseif ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight ); //Skip a line, if needed
1232                  break;
1233              case 'INPUT':
1234                  if ( !$this->isdisplay ) break;
1235                  if ( !isset( $attr['TYPE'] ) ) $attr['TYPE'] == ''; //in order to allow default 'TEXT' form (in case of malformed HTML code)
1236                  if ( !$this->tablestart ) {
1237                      switch ( strtoupper( $attr['TYPE'] ) ) {
1238                          case 'CHECKBOX': // Draw Checkbox
1239                              $checked = false;
1240                              if ( isset( $attr['CHECKED'] ) ) $checked = true;
1241                              $this->SetFillColor( 235, 235, 235 );
1242                              $this->x += 3;
1243                              $this->Rect( $this->x, $this->y + 1, 3, 3, 'DF' );
1244                              if ( $checked ) {
1245                                  $this->Line( $this->x, $this->y + 1, $this->x + 3, $this->y + 1 + 3 );
1246                                  $this->Line( $this->x, $this->y + 1 + 3, $this->x + 3, $this->y + 1 );
1247                              }
1248                              $this->SetFillColor( 255 );
1249                              $this->x += 3.5;
1250                              break;
1251                          case 'RADIO': // Draw Radio button
1252                              $checked = false;
1253                              if ( isset( $attr['CHECKED'] ) ) $checked = true;
1254                              $this->x += 4;
1255                              $this->Circle( $this->x, $this->y + 2.2, 1, 'D' );
1256                              $this->_out( '0.000 g' );
1257                              if ( $checked ) $this->Circle( $this->x, $this->y + 2.2, 0.4, 'DF' );
1258                              $this->Write( 5, $texto, $this->x );
1259                              $this->x += 2;
1260                              break;
1261                          case 'BUTTON': // Draw a button
1262                          case 'SUBMIT':
1263                          case 'RESET':
1264                              $texto = '';
1265                              if ( isset( $attr['VALUE'] ) ) $texto = $attr['VALUE'];
1266                              $nihil = 2.5;
1267                              $this->x += 2;
1268                              $this->SetFillColor( 190, 190, 190 );
1269                              $this->Rect( $this->x, $this->y, $this->GetStringWidth( $texto ) + 2 * $nihil, 4.5, 'DF' ); // 4.5 in order to avoid overlapping
1270                              $this->x += $nihil;
1271                              $this->Write( 5, $texto, $this->x );
1272                              $this->x += $nihil;
1273                              $this->SetFillColor( 255 );
1274                              break;
1275                          case 'PASSWORD':
1276                              if ( isset( $attr['VALUE'] ) ) {
1277                                  $num_stars = strlen( $attr['VALUE'] );
1278                                  $attr['VALUE'] = str_repeat( '*', $num_stars );
1279                              }
1280                          case 'TEXT': // Draw TextField
1281                          default: // default == TEXT
1282                              $texto = '';
1283                              if ( isset( $attr['VALUE'] ) ) $texto = $attr['VALUE'];
1284                              $tamanho = 20;
1285                              if ( isset( $attr['SIZE'] ) && ctype_digit( $attr['SIZE'] ) ) $tamanho = $attr['SIZE'];
1286                              $this->SetFillColor( 235, 235, 235 );
1287                              $this->x += 2;
1288                              $this->Rect( $this->x, $this->y, 2 * $tamanho, 4.5, 'DF' ); // 4.5 in order to avoid overlapping
1289                              if ( $texto != '' ) {
1290                                  $this->x += 1;
1291                                  $this->Write( 5, $texto, $this->x );
1292                                  $this->x -= $this->GetStringWidth( $texto );
1293                              }
1294                              $this->SetFillColor( 255 );
1295                              $this->x += 2 * $tamanho;
1296                              break;
1297                      }
1298                  } else { // we are inside a table
1299                      $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
1300                      $type = '';
1301                      $text = '';
1302                      $height = 0;
1303                      $width = 0;
1304                      switch ( strtoupper( $attr['TYPE'] ) ) {
1305                          case 'CHECKBOX': // Draw Checkbox
1306                              $checked = false;
1307                              if ( isset( $attr['CHECKED'] ) ) $checked = true;
1308                              $text = $checked;
1309                              $type = 'CHECKBOX';
1310                              $width = 4;
1311                              $this->cell[$this->row][$this->col]['textbuffer'][] = array( "ť¤Ź"/*identifier*/ . "type=input,subtype=$type,width=$width,height=$height" . "ť¤Ź" . $text );
1312                              $this->cell[$this->row][$this->col]['s'] += $width;
1313                              if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
1314                              break;
1315                          case 'RADIO': // Draw Radio button
1316                              $checked = false;
1317                              if ( isset( $attr['CHECKED'] ) ) $checked = true;
1318                              $text = $checked;
1319                              $type = 'RADIO';
1320                              $width = 3;
1321                              $this->cell[$this->row][$this->col]['textbuffer'][] = array( "ť¤Ź"/*identifier*/ . "type=input,subtype=$type,width=$width,height=$height" . "ť¤Ź" . $text );
1322                              $this->cell[$this->row][$this->col]['s'] += $width;
1323                              if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $this->lineheight;
1324                              break;
1325                          case 'BUTTON': $type = 'BUTTON'; // Draw a button
1326                          case 'SUBMIT': if ( $type == '' ) $type = 'SUBMIT';
1327                          case 'RESET': if ( $type == '' ) $type = 'RESET';
1328                              $texto = '';
1329                              if ( isset( $attr['VALUE'] ) ) $texto = " " . $attr['VALUE'] . " ";
1330                              $text = $texto;
1331                              $width = $this->GetStringWidth( $texto ) + 3;
1332                              $this->cell[$this->row][$this->col]['textbuffer'][] = array( "ť¤Ź"/*identifier*/ . "type=input,subtype=$type,width=$width,height=$height" . "ť¤Ź" . $text );
1333                              $this->cell[$this->row][$this->col]['s'] += $width;
1334                              if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1335                              break;
1336                          case 'PASSWORD':
1337                              if ( isset( $attr['VALUE'] ) ) {
1338                                  $num_stars = strlen( $attr['VALUE'] );
1339                                  $attr['VALUE'] = str_repeat( '*', $num_stars );
1340                              }
1341                              $type = 'PASSWORD';
1342                          case 'TEXT': // Draw TextField
1343                          default: // default == TEXT
1344                              $texto = '';
1345                              if ( isset( $attr['VALUE'] ) ) $texto = $attr['VALUE'];
1346                              $tamanho = 20;
1347                              if ( isset( $attr['SIZE'] ) && ctype_digit( $attr['SIZE'] ) ) $tamanho = $attr['SIZE'];
1348                              $text = $texto;
1349                              $width = 2 * $tamanho;
1350                              if ( $type == '' ) $type = 'TEXT';
1351                              $this->cell[$this->row][$this->col]['textbuffer'][] = array( "ť¤Ź"/*identifier*/ . "type=input,subtype=$type,width=$width,height=$height" . "ť¤Ź" . $text );
1352                              $this->cell[$this->row][$this->col]['s'] += $width;
1353                              if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1354                              break;
1355                      }
1356                  }
1357                  break;
1358              case 'FONT':
1359                  // Font size is ignored for now
1360                  if ( isset( $attr['COLOR'] ) && $attr['COLOR'] != '' ) {
1361                      $cor = ConvertColor( $attr['COLOR'] );
1362                      // If something goes wrong switch color to black
1363                      $cor['R'] = ( isset( $cor['R'] )?$cor['R']:0 );
1364                      $cor['G'] = ( isset( $cor['G'] )?$cor['G']:0 );
1365                      $cor['B'] = ( isset( $cor['B'] )?$cor['B']:0 );
1366                      $this->colorarray = $cor;
1367                      $this->SetTextColor( $cor['R'], $cor['G'], $cor['B'] );
1368                      $this->issetcolor = true;
1369                  }
1370                  if ( isset( $attr['FACE'] ) && in_array( strtolower( $attr['FACE'] ), $this->fontlist ) ) {
1371                      $this->SetFont( strtolower( $attr['FACE'] ) );
1372                      $this->issetfont = true;
1373                  }
1374                  // 'If' disabled in this version due lack of testing (you may enable it if you want)
1375                  // if (isset($attr['FACE']) and in_array(strtolower($attr['FACE']), $this->fontlist) and isset($attr['SIZE']) and $attr['SIZE']!='') {
1376                  // $this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);
1377                  // $this->issetfont=true;
1378                  // }
1379                  break;
1380              default:
1381          } //end of switch
1382          $this->SetCSSonEndOfOpenTag( $tag );
1383          $this->pjustfinished = false;
1384          // $this->debug("OpenTag($tag) END<br>");
1385      }
1386  
1387  	function CloseTag( $tag )
1388      {
1389          // ! @return void
1390          // Closing tag
1391          // $this->debug("CloseTag($tag)<br>");
1392          if ( $tag == 'OPTION' ) $this->selectoption['ACTIVE'] = false;
1393          if ( $tag == 'BDO' ) $this->divrevert = false;
1394          // Renaming tag hurts XXXX
1395          // $eq_tag  means equivalent tag
1396          $eq_tag = $tag; // Default value is actual tag.
1397          if ( $tag == 'INS' ) $eq_tag = 'U';
1398          if ( $tag == 'STRONG' ) $eq_tag = 'B';
1399          if ( $tag == 'EM' || $tag == 'CITE' ) $eq_tag = 'I';
1400  
1401          if ( $tag == 'OUTLINE' ) {
1402              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1403                  // Deactivate $this->outlineparam for its info is already stored inside $this->textbuffer
1404                  // if (isset($this->outlineparam['OLDWIDTH'])) $this->SetTextOutline($this->outlineparam['OLDWIDTH']);
1405                  $this->SetTextOutline( false );
1406                  $this->outlineparam = array();
1407                  // Save x,y coords ???
1408                  $x = $this->x;
1409                  $y = $this->y;
1410                  // Set some default values
1411                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1412                  // Print content
1413                  $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
1414                  $this->textbuffer = array();
1415                  // Reset values
1416                  $this->Reset();
1417                  $this->buffer_on = false;
1418              }
1419              $this->SetTextOutline( false );
1420              $this->outlineparam = array();
1421          }
1422          if ( $tag == 'A' ) {
1423              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart && !$this->buffer_on ) {
1424                  // Deactivate $this->HREF for its info is already stored inside $this->textbuffer
1425                  $this->HREF = '';
1426                  // Save x,y coords ???
1427                  $x = $this->x;
1428                  $y = $this->y;
1429                  // Set some default values
1430                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1431                  // Print content
1432                  $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
1433                  $this->textbuffer = array();
1434                  // Reset values
1435                  $this->Reset();
1436              }
1437              $this->HREF = '';
1438          }
1439          if ( $tag == 'TH' ) $this->SetStyle( 'B', false );
1440          if ( $tag == 'TH' || $tag == 'TD' ) $this->tdbegin = false;
1441          if ( $tag == 'SPAN' ) {
1442              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1443                  if ( !empty( $this->CSSproperties ) ) {
1444                      // Check if we have borders to print
1445                      if ( ( $this->divborder || $this->dash_on || $this->dotted_on || $this->divbgcolor ) ) {
1446                          $texto = '';
1447                          foreach( $this->textbuffer as $vetor ) $texto .= $vetor[0];
1448                          $tempx = $this->x;
1449                          if ( $this->divbgcolor ) $this->Cell( $this->GetStringWidth( $texto ), $this->lineheight, '', $this->divborder, '', 'L', $this->divbgcolor );
1450                          if ( $this->dash_on ) $this->Rect( $this->oldx, $this->oldy, $this->GetStringWidth( $texto ), $this->lineheight );
1451                          if ( $this->dotted_on ) $this->DottedRect( $this->x - $this->GetStringWidth( $texto ), $this->y, $this->GetStringWidth( $texto ), $this->lineheight );
1452                          $this->x = $tempx;
1453                          $this->x -= 1; //adjust alignment
1454                      }
1455                  }
1456                  // Save x,y coords ???
1457                  $x = $this->x;
1458                  $y = $this->y;
1459                  // Set some default values
1460                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1461                  // Print content
1462                  $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
1463                  $this->textbuffer = array();
1464                  // Reset values
1465                  $this->Reset();
1466              }
1467              $this->buffer_on = false;
1468          }
1469          if ( $tag == 'P' || $tag == 'DIV' ) { // CSS in BLOCK mode
1470              $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1471              if ( !$this->tablestart ) {
1472                  if ( $this->divwidth == 0 ) $this->divwidth = $this->pgwidth;
1473                  if ( $tag == 'P' ) {
1474                      $this->pbegin = false;
1475                      $this->pjustfinished = true;
1476                  } else $this->divbegin = false;
1477                  $content = '';
1478                  foreach( $this->textbuffer as $aux ) $content .= $aux[0];
1479                  $numlines = $this->WordWrap( $content, $this->divwidth );
1480                  if ( $this->divheight == 0 ) $this->divheight = $numlines * 5;
1481                  // Print content
1482                  $this->printbuffer( $this->textbuffer );
1483                  $this->textbuffer = array();
1484                  if ( $tag == 'P' ) $this->Ln( $this->lineheight );
1485              } //end of 'if (!this->tablestart)'
1486              // Reset values
1487          }
1488          if ( $tag == 'TABLE' ) { // TABLE-END
1489              $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1490              $this->table['cells'] = $this->cell;
1491              $this->table['wc'] = array_pad( array(), $this->table['nc'], array( 'miw' => 0, 'maw' => 0 ) );
1492              $this->table['hr'] = array_pad( array(), $this->table['nr'], 0 );
1493              $this->_tableColumnWidth( $this->table );
1494              $this->_tableWidth( $this->table );
1495              $this->_tableHeight( $this->table );
1496              // Output table on PDF
1497              $this->_tableWrite( $this->table );
1498              // Reset values
1499              $this->tablestart = false; //bool
1500              $this->table = array(); //array
1501              $this->cell = array(); //array
1502              $this->col = -1; //int
1503              $this->row = -1; //int
1504              $this->Ln( 0.5 * $this->lineheight );
1505          }
1506          if ( ( $tag == 'UL' ) || ( $tag == 'OL' ) ) {
1507              if ( $this->buffer_on == false ) $this->listnum--; //Adjust minor BUG (this happens when there are two </OL> together)
1508              if ( $this->listlvl == 1 ) { // We are closing the last OL/UL tag
1509                  $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1510                  $this->buffer_on = false;
1511                  if ( !empty( $this->textbuffer ) ) $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
1512                  $this->textbuffer = array();
1513                  $this->listlvl--;
1514                  $this->printlistbuffer();
1515              } else { // returning one level
1516                  if ( !empty( $this->textbuffer ) ) $this->listitem[] = array( $this->listlvl, $this->listnum, $this->textbuffer, $this->listoccur[$this->listlvl] );
1517                  $this->textbuffer = array();
1518                  $occur = $this->listoccur[$this->listlvl];
1519                  $this->listlist[$this->listlvl][$occur]['MAXNUM'] = $this->listnum; //save previous lvl's maxnum
1520                  $this->listlvl--;
1521                  $occur = $this->listoccur[$this->listlvl];
1522                  $this->listnum = $this->listlist[$this->listlvl][$occur]['MAXNUM']; // recover previous level's number
1523                  $this->listtype = $this->listlist[$this->listlvl][$occur]['TYPE']; // recover previous level's type
1524                  $this->buffer_on = false;
1525              }
1526          }
1527          if ( $tag == 'H1' || $tag == 'H2' || $tag == 'H3' || $tag == 'H4' || $tag == 'H5' || $tag == 'H6' ) {
1528              $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1529              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1530                  // These 2 codelines are useless?
1531                  $texto = '';
1532                  foreach( $this->textbuffer as $vetor ) $texto .= $vetor[0];
1533                  // Save x,y coords ???
1534                  $x = $this->x;
1535                  $y = $this->y;
1536                  // Set some default values
1537                  $this->divwidth = $this->pgwidth;
1538                  // Print content
1539                  $this->printbuffer( $this->textbuffer );
1540                  $this->textbuffer = array();
1541                  if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
1542                  // Reset values
1543                  $this->Reset();
1544              }
1545              $this->buffer_on = false;
1546              $this->lineheight = 5;
1547              $this->Ln( $this->lineheight );
1548              $this->SetFontSize( 11 );
1549              $this->SetStyle( 'B', false );
1550          }
1551          if ( $tag == 'TITLE' ) {
1552              $this->titulo = false;
1553              $this->blockjustfinished = true;
1554          }
1555          if ( $tag == 'FORM' ) $this->Ln( $this->lineheight );
1556          if ( $tag == 'PRE' ) {
1557              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1558                  if ( $this->divwidth == 0 ) $this->divwidth = $this->pgwidth;
1559                  $content = '';
1560                  foreach( $this->textbuffer as $aux ) $content .= $aux[0];
1561                  $numlines = $this->WordWrap( $content, $this->divwidth );
1562                  if ( $this->divheight == 0 ) $this->divheight = $numlines * 5;
1563                  // Print content
1564                  $this->textbuffer[0][0] = ltrim( $this->textbuffer[0][0] ); //Remove exceeding left-side space
1565                  $this->printbuffer( $this->textbuffer );
1566                  $this->textbuffer = array();
1567                  if ( $this->x != $this->lMargin ) $this->Ln( $this->lineheight );
1568                  // Reset values
1569                  $this->Reset();
1570                  $this->Ln( 1.1 * $this->lineheight );
1571              }
1572              if ( $this->tablestart ) {
1573                  $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 );
1574                  $this->cell[$this->row][$this->col]['text'][] = "\n";
1575              }
1576              if ( $this->divbegin || $this->pbegin || $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 );
1577              $this->buffer_on = false;
1578              $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1579              $this->pjustfinished = true; //behaves the same way
1580          }
1581          if ( $tag == 'CODE' || $tag == 'PRE' || $tag == 'TT' || $tag == 'KBD' || $tag == 'SAMP' ) {
1582              $this->currentfont = '';
1583              $this->SetFont( 'helvetica' );
1584          }
1585          if ( $eq_tag == 'B' || $eq_tag == 'I' || $eq_tag == 'U' ) {
1586              $this->SetStyle( $eq_tag, false );
1587          }
1588          if ( $tag == 'TEXTAREA' ) {
1589              if ( !$this->tablestart ) { // not inside a table
1590                  // Draw arrows too?
1591                  $texto = '';
1592                  foreach( $this->textbuffer as $v ) $texto .= $v[0];
1593                  $this->SetFillColor( 235, 235, 235 );
1594                  $this->SetFont( 'courier' );
1595                  $this->x += 3;
1596                  $linesneeded = $this->WordWrap( $texto, ( $this->col * 2.2 ) + 3 );
1597                  if ( $linesneeded > $this->row ) { // Too many words inside textarea
1598                      $textoaux = explode( "\n", $texto );
1599                      $texto = '';
1600                      for( $i = 0;$i < $this->row;$i++ ) {
1601                          if ( $i == $this->row-1 ) $texto .= $textoaux[$i];
1602                          else $texto .= $textoaux[$i] . "\n";
1603                      }
1604                      // Inform the user that some text has been truncated
1605                      $texto{strlen($texto)-1} = ".";
1606                      $texto{strlen($texto)-2} = ".";
1607                      $texto{strlen($texto)-3} = ".";
1608                  }
1609                  $backup_y = $this->y;
1610                  $this->Rect( $this->x, $this->y, ( 2.2 * $this->col ) + 6, 5 * $this->row, 'DF' );
1611                  if ( $texto != '' ) $this->MultiCell( ( 2.2 * $this->col ) + 6, $this->lineheight, $texto );
1612                  $this->y = $backup_y + $this->row * $this->lineheight;
1613                  $this->SetFont( 'Helvetica' );
1614              } else { // inside a table
1615                  $this->cell[$this->row][$this->col]['textbuffer'][] = $this->textbuffer[0];
1616                  $this->cell[$this->row][$this->col]['text'][] = $this->textbuffer[0];
1617                  $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
1618                  $this->specialcontent = '';
1619              }
1620              $this->SetFillColor( 255 );
1621              $this->textbuffer = array();
1622              $this->buffer_on = false;
1623          }
1624          if ( $tag == 'SELECT' ) {
1625              $texto = '';
1626              $tamanho = 0;
1627              if ( isset( $this->selectoption['MAXWIDTH'] ) ) $tamanho = $this->selectoption['MAXWIDTH'];
1628              if ( $this->tablestart ) {
1629                  $texto = "ť¤Ź" . $this->specialcontent . "ť¤Ź" . $this->selectoption['SELECTED'];
1630                  $aux = explode( "ť¤Ź", $texto );
1631                  $texto = $aux[2];
1632                  $texto = "ť¤Ź" . $aux[1] . ",width=$tamanho,height=" . ( $this->lineheight + 2 ) . "ť¤Ź" . $texto;
1633                  $this->cell[$this->row][$this->col]['s'] += $tamanho + 7; // margin + arrow box
1634                  $this->cell[$this->row][$this->col]['form'] = true; // in order to make some width adjustments later
1635  
1636                  if ( !isset( $this->cell[$this->row][$this->col]['h'] ) ) $this->cell[$this->row][$this->col]['h'] = $this->lineheight + 2;
1637                  $this->cell[$this->row][$this->col]['textbuffer'][] = array( $texto );
1638                  $this->cell[$this->row][$this->col]['text'][] = '';
1639              } else { // not inside a table
1640                  $texto = $this->selectoption['SELECTED'];
1641                  $this->SetFillColor( 235, 235, 235 );
1642                  $this->x += 2;
1643                  $this->Rect( $this->x, $this->y, $tamanho + 2, 5, 'DF' ); //+2 margin
1644                  $this->x += 1;
1645                  if ( $texto != '' ) $this->Write( 5, $texto, $this->x );
1646                  $this->x += $tamanho - $this->GetStringWidth( $texto ) + 2;
1647                  $this->SetFillColor( 190, 190, 190 );
1648                  $this->Rect( $this->x-1, $this->y, 5, 5, 'DF' ); //Arrow Box
1649                  $this->SetFont( 'zapfdingbats' );
1650                  $this->Write( 5, chr( 116 ), $this->x ); //Down arrow
1651                  $this->SetFont( 'Helvetica' );
1652                  $this->SetFillColor( 255 );
1653                  $this->x += 1;
1654              }
1655              $this->selectoption = array();
1656              $this->specialcontent = '';
1657              $this->textbuffer = array();
1658          }
1659          if ( $tag == 'SUB' || $tag == 'SUP' ) { // subscript or superscript
1660              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart && !$this->buffer_on && !$this->strike ) {
1661                  // Deactivate $this->SUB/SUP for its info is already stored inside $this->textbuffer
1662                  $this->SUB = false;
1663                  $this->SUP = false;
1664                  // Save x,y coords ???
1665                  $x = $this->x;
1666                  $y = $this->y;
1667                  // Set some default values
1668                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1669                  // Print content
1670                  $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
1671                  $this->textbuffer = array();
1672                  // Reset values
1673                  $this->Reset();
1674              }
1675              $this->SUB = false;
1676              $this->SUP = false;
1677          }
1678          if ( $tag == 'S' || $tag == 'STRIKE' || $tag == 'DEL' ) {
1679              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1680                  // Deactivate $this->strike for its info is already stored inside $this->textbuffer
1681                  $this->strike = false;
1682                  // Save x,y coords ???
1683                  $x = $this->x;
1684                  $y = $this->y;
1685                  // Set some default values
1686                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1687                  // Print content
1688                  $this->printbuffer( $this->textbuffer, true/*is out of a block (e.g. DIV,P etc.)*/ );
1689                  $this->textbuffer = array();
1690                  // Reset values
1691                  $this->Reset();
1692              }
1693              $this->strike = false;
1694          }
1695          if ( $tag == 'ADDRESS' || $tag == 'CENTER' ) { // <ADDRESS> or <CENTER> tag
1696              $this->blockjustfinished = true; //Eliminate exceeding left-side spaces
1697              if ( !$this->pbegin && !$this->divbegin && !$this->tablestart ) {
1698                  // Save x,y coords ???
1699                  $x = $this->x;
1700                  $y = $this->y;
1701                  // Set some default values
1702                  $this->divwidth = $this->pgwidth - $x + $this->lMargin;
1703                  // Print content
1704                  $this->printbuffer( $this->textbuffer );
1705                  $this->textbuffer = array();
1706                  // Reset values
1707                  $this->Reset();
1708              }
1709              $this->buffer_on = false;
1710              if ( $tag == 'ADDRESS' ) $this->SetStyle( 'I', false );
1711          }
1712          if ( $tag == 'BIG' ) {
1713              $newsize = $this->FontSizePt - 1;
1714              $this->SetFontSize( $newsize );
1715              $this->SetStyle( 'B', false );
1716          }
1717          if ( $tag == 'SMALL' ) {
1718              $newsize = $this->FontSizePt + 1;
1719              $this->SetFontSize( $newsize );
1720          }
1721          if ( $tag == 'FONT' ) {
1722              if ( $this->issetcolor == true ) {
1723                  $this->colorarray = array();
1724                  $this->SetTextColor( 0 );
1725                  $this->issetcolor = false;
1726              }
1727              if ( $this->issetfont ) {
1728                  $this->SetFont( 'Helvetica' );
1729                  $this->issetfont = false;
1730              }
1731          }
1732          $this->RevertCSSproperties( $tag );
1733          // $this->debug("CloseTag($tag) END<br>");
1734      }
1735      /* CloseTag */
1736  
1737  	function printlistbuffer()
1738      {
1739          // ! @return void
1740          // ! @desc Prints all list-related buffered info
1741          // Save x coordinate
1742          $x = $this->oldx;
1743          foreach( $this->listitem as $item ) {
1744              // Set default width & height values
1745              $this->divwidth = $this->pgwidth;
1746              $this->divheight = $this->lineheight;
1747              // Get list's buffered data
1748              $lvl = $item[0];
1749              $num = $item[1];
1750              $this->textbuffer = $item[2];
1751              $occur = $item[3];
1752              $type = $this->listlist[$lvl][$occur]['TYPE'];
1753              $maxnum = $this->listlist[$lvl][$occur]['MAXNUM'];
1754              switch ( $type ) { // Format type
1755                  case 'A':
1756                      $num = dec2alpha( $num, true );
1757                      $maxnum = dec2alpha( $maxnum, true );
1758                      $type = str_pad( $num, strlen( $maxnum ), ' ', STR_PAD_LEFT ) . ".";
1759                      break;
1760                  case 'a':
1761                      $num = dec2alpha( $num, false );
1762                      $maxnum = dec2alpha( $maxnum, false );
1763                      $type = str_pad( $num, strlen( $maxnum ), ' ', STR_PAD_LEFT ) . ".";
1764                      break;
1765                  case 'I':
1766                      $num = dec2roman( $num, true );
1767                      $maxnum = dec2roman( $maxnum, true );
1768                      $type = str_pad( $num, strlen( $maxnum ), ' ', STR_PAD_LEFT ) . ".";
1769                      break;
1770                  case 'i':
1771                      $num = dec2roman( $num, false );
1772                      $maxnum = dec2roman( $maxnum, false );
1773                      $type = str_pad( $num, strlen( $maxnum ), ' ', STR_PAD_LEFT ) . ".";
1774                      break;
1775                  case '1':
1776                      $type = str_pad( $num, strlen( $maxnum ), ' ', STR_PAD_LEFT ) . ".";
1777                      break;
1778                  case 'disc':
1779                      $type = chr( 149 );
1780                      break;
1781                  case 'square':
1782                      $type = chr( 110 ); //black square on Zapfdingbats font
1783                      break;
1784                  case 'circle':
1785                      $type = chr( 186 );
1786                      break;
1787                  default: break;
1788              }
1789              $this->x = ( 5 * $lvl ) + $x; //Indent list
1790              // Get bullet width including margins
1791              $oldsize = $this->FontSize * $this->k;
1792              if ( $type == chr( 110 ) ) $this->SetFont( 'zapfdingbats', '', 5 );
1793              $type .= ' ';
1794              $blt_width = $this->GetStringWidth( $type ) + $this->cMargin * 2;
1795              // Output bullet
1796              $this->Cell( $blt_width, 5, $type, '', '', 'L' );
1797              $this->SetFont( 'Helvetica', '', $oldsize );
1798              $this->divwidth = $this->divwidth + $this->lMargin - $this->x;
1799              // Print content
1800              $this->printbuffer( $this->textbuffer );
1801              $this->textbuffer = array();
1802          }
1803          // Reset all used values
1804          $this->listoccur = array();
1805          $this->listitem = array();
1806          $this->listlist = array();
1807          $this->listlvl = 0;
1808          $this->listnum = 0;
1809          $this->listtype = '';
1810          $this->textbuffer = array();
1811          $this->divwidth = 0;
1812          $this->divheight = 0;
1813          $this->oldx = -1;
1814          // At last, but not least, skip a line
1815          $this->Ln( $this->lineheight );
1816      }
1817  
1818  	function printbuffer( $arrayaux, $outofblock = false, $is_table = false )
1819      {
1820          // ! @return headache
1821          // ! @desc Prepares buffered text to be printed with FlowingBlock()
1822          if ( !$this->isdisplay ) return; // HOW TO TAKE DISPLAY == NONE into account?
1823  
1824          // Save some previous parameters
1825          $save = array();
1826          $save['strike'] = $this->strike;
1827          $save['SUP'] = $this->SUP;
1828          $save['SUB'] = $this->SUB;
1829          $save['DOTTED'] = $this->dotted_on;
1830          $save['DASHED'] = $this->dash_on;
1831          $this->SetDash(); //restore to no dash
1832          $this->dash_on = false;
1833          $this->dotted_on = false;
1834  
1835          $bak_y = $this->y;
1836          $bak_x = $this->x;
1837          $align = $this->divalign;
1838          $oldpage = $this->page;
1839          // Overall object size == $old_height
1840          // Line height == $this->divheight
1841          $old_height = $this->divheight;
1842          if ( $is_table ) {
1843              $this->divheight = 1.1 * $this->lineheight;
1844              $fill = 0;
1845          } else {
1846              $this->divheight = $this->lineheight;
1847              if ( $this->FillColor == '1.000 g' ) $fill = 0; //avoid useless background painting (1.000 g == white background color)
1848              else $fill = 1;
1849          }
1850  
1851          $this->newFlowingBlock( $this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table );
1852  
1853          $array_size = count( $arrayaux );
1854          for( $i = 0;$i < $array_size; $i++ ) {
1855              $vetor = $arrayaux[$i];
1856              if ( $i == 0 && $vetor[0] != "\n" ) $vetor[0] = ltrim( $vetor[0] );
1857              if ( empty( $vetor[0] ) && empty( $vetor[7] ) ) continue; //Ignore empty text and not carrying an internal link
1858              // Activating buffer properties
1859              if ( isset( $vetor[10] ) && !empty( $vetor[10] ) ) { // Background color
1860                  $cor = $vetor[10];
1861                  $this->SetFillColor( $cor['R'], $cor['G'], $cor['B'] );
1862                  $this->divbgcolor = true;
1863              }
1864              if ( isset( $vetor[9] ) && !empty( $vetor[9] ) ) { // Outline parameters
1865                  $cor = $vetor[9]['COLOR'];
1866                  $outlinewidth = $vetor[9]['WIDTH'];
1867                  $this->SetTextOutline( $outlinewidth, $cor['R'], $cor['G'], $cor['B'] );
1868                  $this->outline_on = true;
1869              }
1870              if ( isset( $vetor[8] ) && $vetor[8] === true ) { // strike-through the text
1871                  $this->strike = true;
1872              }
1873              if ( isset( $vetor[7] ) && $vetor[7] != '' ) { // internal link: <a name="anyvalue">
1874                  $this->internallink[$vetor[7]] = array( "Y" => $this->y, "PAGE" => $this->page );
1875                  $this->Bookmark( $vetor[7] . " (pg. $this->page)", 0, $this->y );
1876                  if ( empty( $vetor[0] ) ) continue; //Ignore empty text
1877              }
1878              if ( isset( $vetor[6] ) && $vetor[6] === true ) { // Subscript
1879                  $this->SUB = true;
1880                  $this->SetFontSize( 6 );
1881              }
1882              if ( isset( $vetor[5] ) && $vetor[5] === true ) { // Superscript
1883                  $this->SUP = true;
1884                  $this->SetFontSize( 6 );
1885              }
1886              if ( isset( $vetor[4] ) && $vetor[4] != '' ) $this->SetFont( $vetor[4] ); // Font Family
1887              if ( !empty( $vetor[3] ) ) { // Font Color
1888                  $cor = $vetor[3];
1889                  $this->SetTextColor( $cor['R'], $cor['G'], $cor['B'] );
1890              }
1891              if ( isset( $vetor[2] ) && $vetor[2] != '' ) { // Bold,Italic,Underline styles
1892                  if ( strpos( $vetor[2], "B" ) !== false ) $this->SetStyle( 'B', true );
1893                  if ( strpos( $vetor[2], "I" ) !== false ) $this->SetStyle( 'I', true );
1894                  if ( strpos( $vetor[2], "U" ) !== false ) $this->SetStyle( 'U', true );
1895              }
1896              if ( isset( $vetor[1] ) && $vetor[1] != '' ) { // LINK
1897                  if ( strpos( $vetor[1], "." ) === false ) { // assuming every external link has a dot indicating extension (e.g: .html .txt .zip www.somewhere.com etc.)
1898                      // Repeated reference to same anchor?
1899                      while ( array_key_exists( $vetor[1], $this->internallink ) ) $vetor[1] = "#" . $vetor[1];
1900                      $this->internallink[$vetor[1]] = $this->AddLink();
1901                      $vetor[1] = $this->internallink[$vetor[1]];
1902                  }
1903                  $this->HREF = $vetor[1];
1904                  $this->SetTextColor( 0, 0, 255 );
1905                  $this->SetStyle( 'U', true );
1906              }
1907              // Print-out special content
1908              //if ( isset($vetor[0]) && $vetor[0]{0} == 'ť' && $vetor[0]{1} == '¤' && $vetor[0]{2} == 'Ź' ) { // identifier has been identified!
1909              // OG 2007-04-28 make strpos check -> should be 
1910              if ( isset($vetor[0]) && strpos($vetor[0], 'ť¤Ź') === 0 ) {
1911                  $content = explode( 'ť¤Ź', $vetor[0] );
1912                  $texto = $content[2];
1913                  $content = explode( ",", $content[1] );
1914                  foreach( $content as $value ) {
1915                      $value = explode( '=', $value );
1916                      $specialcontent[$value[0]] = $value[1];
1917                  }
1918                  if ( $this->flowingBlockAttr[ 'contentWidth' ] > 0 ) { // Print out previously accumulated content
1919                      $width_used = $this->flowingBlockAttr[ 'contentWidth' ] / $this->k;
1920                      // Restart Flowing Block
1921                      $this->finishFlowingBlock( $outofblock );
1922                      $this->x = $bak_x + ( $width_used % $this->divwidth ) + 0.5; // 0.5 == margin
1923                      $this->y -= ( $this->lineheight + 0.5 );
1924                      $extrawidth = 0; //only to be used in case $specialcontent['width'] does not contain all used width (e.g. Select Box)
1925                      if ( $specialcontent['type'] == 'select' ) $extrawidth = 7; //arrow box + margin
1926                      if ( ( $this->x - $bak_x ) + $specialcontent['width'] + $extrawidth > $this->divwidth ) {
1927                          $this->x = $bak_x;
1928                          $this->y += $this->lineheight - 1;
1929                      }
1930                      $this->newFlowingBlock( $this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table );
1931                  }
1932                  switch ( strtoupper( $specialcontent['type'] ) ) {
1933                      case 'IMAGE':
1934                          // xpos and ypos used in order to support: <div align='center'><img ...></div>
1935                          $xpos = 0;
1936                          $ypos = 0;
1937                          if ( isset( $specialcontent['ypos'] ) && $specialcontent['ypos'] != '' ) $ypos = ( float )$specialcontent['ypos'];
1938                          if ( isset( $specialcontent['xpos'] ) && $specialcontent['xpos'] != '' ) $xpos = ( float )$specialcontent['xpos'];
1939                          $width_used = ( ( $this->x - $bak_x ) + $specialcontent['width'] ) * $this->k; //in order to adjust x coordinate later
1940                          // Is this the best way of fixing x,y coordinates?
1941                          $fix_x = ( $this->x + 2 ) * $this->k + ( $xpos * $this->k ); //+2 margin
1942                          $fix_y = ( $this->h - ( ( $this->y + 2 ) + $specialcontent['height'] ) ) * $this->k; //+2 margin
1943                          $imgtemp = explode( " ", $texto );
1944                          $imgtemp[5] = $fix_x; // x
1945                          $imgtemp[6] = $fix_y; // y
1946                          $texto = implode( " ", $imgtemp );
1947                          $this->_out( $texto );
1948                          // Readjust x coordinate in order to allow text to be placed after this form element
1949                          $this->x = $bak_x;
1950                          $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1951                          $spacenum = ( integer )ceil( ( $width_used / $spacesize ) );
1952                          // Consider the space used so far in this line as a bunch of spaces
1953                          if ( $ypos != 0 ) $this->Ln( $ypos );
1954                          else $this->WriteFlowingBlock( str_repeat( ' ', $spacenum ) );
1955                          break;
1956                      case 'INPUT':
1957                          switch ( $specialcontent['subtype'] ) {
1958                              case 'PASSWORD':
1959                              case 'TEXT': // Draw TextField
1960                                  $width_used = ( ( $this->x - $bak_x ) + $specialcontent['width'] ) * $this->k; //in order to adjust x coordinate later
1961                                  $this->SetFillColor( 235, 235, 235 );
1962                                  $this->x += 1;
1963                                  $this->y += 1;
1964                                  $this->Rect( $this->x, $this->y, $specialcontent['width'], 4.5, 'DF' ); // 4.5 in order to avoid overlapping
1965                                  if ( $texto != '' ) {
1966                                      $this->x += 1;
1967                                      $this->Write( 5, $texto, $this->x );
1968                                      $this->x -= $this->GetStringWidth( $texto );
1969                                  }
1970                                  $this->SetFillColor( 255 );
1971                                  $this->y -= 1;
1972                                  // Readjust x coordinate in order to allow text to be placed after this form element
1973                                  $this->x = $bak_x;
1974                                  $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1975                                  $spacenum = ( integer )ceil( ( $width_used / $spacesize ) );
1976                                  // Consider the space used so far in this line as a bunch of spaces
1977                                  $this->WriteFlowingBlock( str_repeat( ' ', $spacenum ) );
1978                                  break;
1979                              case 'CHECKBOX': // Draw Checkbox
1980                                  $width_used = ( ( $this->x - $bak_x ) + $specialcontent['width'] ) * $this->k; //in order to adjust x coordinate later
1981                                  $checked = $texto;
1982                                  $this->SetFillColor( 235, 235, 235 );
1983                                  $this->y += 1;
1984                                  $this->x += 1;
1985                                  $this->Rect( $this->x, $this->y, 3, 3, 'DF' );
1986                                  if ( $checked ) {
1987                                      $this->Line( $this->x, $this->y, $this->x + 3, $this->y + 3 );
1988                                      $this->Line( $this->x, $this->y + 3, $this->x + 3, $this->y );
1989                                  }
1990                                  $this->SetFillColor( 255 );
1991                                  $this->y -= 1;
1992                                  // Readjust x coordinate in order to allow text to be placed after this form element
1993                                  $this->x = $bak_x;
1994                                  $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
1995                                  $spacenum = ( integer )ceil( ( $width_used / $spacesize ) );
1996                                  // Consider the space used so far in this line as a bunch of spaces
1997                                  $this->WriteFlowingBlock( str_repeat( ' ', $spacenum ) );
1998                                  break;
1999                              case 'RADIO': // Draw Radio button
2000                                  $width_used = ( ( $this->x - $bak_x ) + $specialcontent['width'] + 0.5 ) * $this->k; //in order to adjust x coordinate later
2001                                  $checked = $texto;
2002                                  $this->x += 2;
2003                                  $this->y += 1.5;
2004                                  $this->Circle( $this->x, $this->y + 1.2, 1, 'D' );
2005                                  $this->_out( '0.000 g' );
2006                                  if ( $checked ) $this->Circle( $this->x, $this->y + 1.2, 0.4, 'DF' );
2007                                  $this->y -= 1.5;
2008                                  // Readjust x coordinate in order to allow text to be placed after this form element
2009                                  $this->x = $bak_x;
2010                                  $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
2011                                  $spacenum = ( integer )ceil( ( $width_used / $spacesize ) );
2012                                  // Consider the space used so far in this line as a bunch of spaces
2013                                  $this->WriteFlowingBlock( str_repeat( ' ', $spacenum ) );
2014                                  break;
2015                              case 'BUTTON': // Draw a button
2016                              case 'SUBMIT':
2017                              case 'RESET':
2018                                  $nihil = ( $specialcontent['width'] - $this->GetStringWidth( $texto ) ) / 2;
2019                                  $this->x += 1.5;
2020                                  $this->y += 1;
2021                                  $this->SetFillColor( 190, 190, 190 );
2022                                  $this->Rect( $this->x, $this->y, $specialcontent['width'], 4.5, 'DF' ); // 4.5 in order to avoid overlapping
2023                                  $this->x += $nihil;
2024                                  $this->Write( 5, $texto, $this->x );
2025                                  $this->x += $nihil;
2026                                  $this->SetFillColor( 255 );
2027                                  $this->y -= 1;
2028                                  break;
2029                              default: break;
2030                          }
2031                          break;
2032                      case 'SELECT':
2033                          $width_used = ( ( $this->x - $bak_x ) + $specialcontent['width'] + 8 ) * $this->k; //in order to adjust x coordinate later
2034                          $this->SetFillColor( 235, 235, 235 ); //light gray
2035                          $this->x += 1.5;
2036                          $this->y += 1;
2037                          $this->Rect( $this->x, $this->y, $specialcontent['width'] + 2, $this->lineheight, 'DF' ); // +2 == margin
2038                          $this->x += 1;
2039                          if ( $texto != '' ) $this->Write( $this->lineheight, $texto, $this->x ); //the combobox content
2040                          $this->x += $specialcontent['width'] - $this->GetStringWidth( $texto ) + 2;
2041                          $this->SetFillColor( 190, 190, 190 ); //dark gray
2042                          $this->Rect( $this->x-1, $this->y, 5, 5, 'DF' ); //Arrow Box
2043                          $this->SetFont( 'zapfdingbats' );
2044                          $this->Write( $this->lineheight, chr( 116 ), $this->x ); //Down arrow
2045                          $this->SetFont( 'Helvetica' );
2046                          $this->SetFillColor( 255 );
2047                          // Readjust x coordinate in order to allow text to be placed after this form element
2048                          $this->x = $bak_x;
2049                          $spacesize = $this->CurrentFont[ 'cw' ][ ' ' ] * ( $this->FontSizePt / 1000 );
2050                          $spacenum = ( integer )ceil( ( $width_used / $spacesize ) );
2051                          // Consider the space used so far in this line as a bunch of spaces
2052                          $this->WriteFlowingBlock( str_repeat( ' ', $spacenum ) );
2053                          break;
2054                      case 'TEXTAREA':
2055                          // Setup TextArea properties
2056                          $this->SetFillColor( 235, 235, 235 );
2057                          $this->SetFont( 'courier' );
2058                          $this->currentfont = 'courier';
2059                          $ta_lines = $specialcontent['lines'];
2060                          $ta_height = 1.1 * $this->lineheight * $ta_lines;
2061                          $ta_width = $specialcontent['width'];
2062                          // Adjust x,y coordinates
2063                          $this->x += 1.5;
2064                          $this->y += 1.5;
2065                          $linesneeded = $this->WordWrap( $texto, $ta_width );
2066                          if ( $linesneeded > $ta_lines ) { // Too many words inside textarea
2067                              $textoaux = explode( "\n", $texto );
2068                              $texto = '';
2069                              for( $i = 0;$i < $ta_lines;$i++ ) {
2070                                  if ( $i == $ta_lines-1 ) $texto .= $textoaux[$i];
2071                                  else $texto .= $textoaux[$i] . "\n";
2072                              }
2073                              // Inform the user that some text has been truncated
2074                              $texto{strlen($texto)-1} = ".";
2075                              $texto{strlen($texto)-2} = ".";
2076                              $texto{strlen($texto)-3} = ".";
2077                          }
2078                          $backup_y = $this->y;
2079                          $backup_x = $this->x;
2080                          $this->Rect( $this->x, $this->y, $ta_width + 3, $ta_height, 'DF' );
2081                          if ( $texto != '' ) $this->MultiCell( $ta_width + 3, $this->lineheight, $texto );
2082                          $this->y = $backup_y - 1.5;
2083                          $this->x = $backup_x + $ta_width + 2.5;
2084                          $this->SetFillColor( 255 );
2085                          $this->SetFont( 'Helvetica' );
2086                          $this->currentfont = '';
2087                          break;
2088                      default: break;
2089                  }
2090              } else { // THE text
2091                  if ( $vetor[0] == "\n" ) { // We are reading a <BR> now turned into newline ("\n")
2092                      // Restart Flowing Block
2093                      $this->finishFlowingBlock( $outofblock );
2094                      if ( $outofblock ) $this->Ln( $this->lineheight );
2095                      $this->x = $bak_x;
2096                      $this->newFlowingBlock( $this->divwidth, $this->divheight, $this->divborder, $align, $fill, $is_table );
2097                  } else $this->WriteFlowingBlock( $vetor[0] , $outofblock );
2098              }
2099              // Check if it is the last element. If so then finish printing the block
2100              if ( $i == ( $array_size-1 ) ) $this->finishFlowingBlock( $outofblock );
2101              // Now we must deactivate what we have used
2102              if ( ( isset( $vetor[1] ) && $vetor[1] != '' ) || $this->HREF != '' ) {
2103                  $this->SetTextColor( 0 );
2104                  $this->SetStyle( 'U', false );
2105                  $this->HREF = '';
2106              }
2107              if ( isset( $vetor[2] ) && $vetor[2] != '' ) {
2108                  $this->SetStyle( 'B', false );
2109                  $this->SetStyle( 'I', false );
2110                  $this->SetStyle( 'U', false );
2111              }
2112              if ( isset( $vetor[3] ) && $vetor[3] != '' ) {
2113                  unset( $cor );
2114                  $this->SetTextColor( 0 );
2115              }
2116              if ( isset( $vetor[4] ) && $vetor[4] != '' ) $this->SetFont( 'Helvetica' );
2117              if ( isset( $vetor[5] ) && $vetor[5] === true ) {
2118                  $this->SUP = false;
2119                  $this->SetFontSize( 11 );
2120              }
2121              if ( isset( $vetor[6] ) && $vetor[6] === true ) {
2122                  $this->SUB = false;
2123                  $this->SetFontSize( 11 );
2124              }
2125              // vetor7-internal links
2126              if ( isset( $vetor[8] ) && $vetor[8] === true ) { // strike-through the text
2127                  $this->strike = false;
2128              }
2129              if ( isset( $vetor[9] ) && !empty( $vetor[9] ) ) { // Outline parameters
2130                  $this->SetTextOutline( false );
2131                  $this->outline_on = false;
2132              }
2133              if ( isset( $vetor[10] ) && !empty( $vetor[10] ) ) { // Background color
2134                  $this->SetFillColor( 255 );
2135                  $this->divbgcolor = false;
2136              }
2137          } //end of for(i=0;i<arraysize;i++)
2138          // Restore some previously set parameters
2139          $this->strike = $save['strike'];
2140          $this->SUP = $save['SUP'];
2141          $this->SUB = $save['SUB'];
2142          $this->dotted_on = $save['DOTTED'];
2143          $this->dash_on = $save['DASHED'];
2144          if ( $this->dash_on ) $this->SetDash( 2, 2 );
2145          // Check whether we have borders to paint or not
2146          // (only works 100% if whole content spans only 1 page)
2147          if ( !empty( $this->CSSproperties ) && ( $this->divborder || $this->dash_on || $this->dotted_on || $this->divbgcolor ) ) {
2148              if ( $oldpage != $this->page ) {
2149                  // Only border on last page is painted (known bug)
2150                  $x = $this->lMargin;
2151                  $y = $this->tMargin;
2152                  $old_height = $this->y - $y;
2153              } else {
2154                  if ( $this->oldx < 0 ) $x = $this->x;
2155                  else $x = $this->oldx;
2156                  if ( $this->oldy < 0 ) $y = $this->y - $old_height;
2157                  else $y = $this->oldy;
2158              }
2159              if ( $this->divborder ) $this->Rect( $x, $y, $this->divwidth, $old_height );
2160              if ( $this->dash_on ) $this->Rect( $x, $y, $this->divwidth, $old_height );
2161              if ( $this->dotted_on ) $this->DottedRect( $x, $y, $this->divwidth, $old_height );
2162              $this->x = $bak_x;
2163          }
2164      }
2165  
2166  	function Reset()
2167      {
2168          // ! @return void
2169          // ! @desc Resets several class attributes
2170          $this->debug( "Reset properties<br>" );
2171          // if ( $this->issetcolor !== true )
2172          // {
2173          $this->SetTextColor( 0 );
2174          $this->SetDrawColor( 0 );
2175          $this->SetFillColor( 255 );
2176          $this->colorarray = array();
2177          $this->bgcolorarray = array();
2178          $this->issetcolor = false;
2179          // }
2180          $this->HREF = '';
2181          $this->SetTextOutline( false );
2182          // $this->strike = false;
2183          $this->SetFontSize( 11 );
2184          $this->SetStyle( 'B', false );
2185          $this->SetStyle( 'I', false );
2186          $this->SetStyle( 'U', false );
2187          $this->SetFont( 'Helvetica' );
2188          $this->divwidth = 0;
2189          $this->divheight = 0;
2190          $this->divalign = "L";
2191          $this->divrevert = false;
2192          $this->divborder = 0;
2193          $this->divbgcolor = false;
2194          $this->toupper = false;
2195          $this->tolower = false;
2196          $this->SetDash(); //restore to no dash
2197          $this->dash_on = false;
2198          $this->dotted_on = false;
2199          $this->oldx = -1;
2200          $this->oldy = -1;
2201          $this->isdisplay = true;
2202          $this->SetCSS( $this->CSSproperties );
2203      }
2204  
2205  	function ReadMetaTags( $html )
2206      {
2207          // ! @return void
2208          // ! @desc Pass meta tag info to PDF file properties
2209          $regexp = '/<(meta .*?)>/si';
2210          preg_match_all( $regexp, $html, $aux );
2211          foreach ( $aux[1] as $meta ) {
2212              $this->GetTagAndAttrs( $meta, $tag, $attr );
2213  
2214              if ( isset( $attr['NAME'] ) && isset( $attr['CONTENT'] ) ) {
2215                  switch ( $attr['NAME'] ) {
2216                      case "KEYWORDS": $this->SetKeywords( $attr['CONTENT'] );
2217                          break;
2218                      case "AUTHOR": $this->SetAuthor( $attr['CONTENT'] );
2219                          break;
2220                      case "DESCRIPTION": $this->SetSubject( $attr['CONTENT'] );
2221                          break;
2222                  }
2223              }
2224          }
2225          // Comercial do Aplicativo usado (no caso um script):
2226          $this->SetCreator( "HTML2FPDF >> http://html2fpdf.sf.net" );
2227      }
2228      // ////////////////
2229      // / CSS parser ///
2230      // ////////////////
2231  	function add_properties( &$array, $properties )
2232      {
2233          // ! @desc CSS parser
2234          // ! @return string
2235          // TODO: Take weights, 'important' into account
2236          foreach( $properties as $p => $v ) {
2237              $array[$p] = $v;
2238          }
2239      }
2240  
2241  	function ParseStyle( $CSSblock )
2242      {
2243          // ! @desc Parse style code, either from style sheet or embedded style code
2244          // ! @return string
2245          // ////////////////////////////
2246          // PARSE THE STYLESHEET ITSELF
2247          // Get class/id name and its characteristics from $CSSblock[1]
2248          $id_class_exp = '(?:[^#\\.]*[\\.#])?\\S+?\\s*?';
2249          $properties_exp = '\{(.+?)\}';
2250          $regexp = '/(' . $id_class_exp . '(?:,\s*' . $id_class_exp . ')*)' . $properties_exp . '/s';
2251          // $this->debug("EXP2=".$regexp."<br>");
2252          preg_match_all( $regexp, $CSSblock, $extstyle );
2253          // Make CSSXXX[Name-of-the-class] = array(key => value)
2254          $property_regexp = '/\\s*?(\\S+?)\\s*:\\s*(\S+?|"[^"]*")(?:\\s*\\\!\\s*important)?\\s*;/si';
2255          $id_class_exp = '/([^\\#\\.,\s]*(?=[\\.\\#]))?([\\.\\#]?)([^,\\.\\#\\s]+)/m';
2256  
2257          for( $i = 0; $i < count( $extstyle[1] ) ; $i++ ) {
2258              $this->debug( "ID/CLASS=" . $extstyle[1][$i] . "<br>" );
2259              $this->debug( "PROPS=" . $extstyle[2][$i] . "<br>" );
2260  
2261              preg_match_all( $property_regexp, $extstyle[2][$i], $extstyleinfo );
2262              $extproperties = $extstyleinfo[1];
2263              $extvalues = $extstyleinfo[2];
2264              for( $j = 0; $j < count( $extproperties ) ; $j++ ) {
2265                  // Array-properties and Array-values must have the SAME SIZE!
2266                  $extclassproperties[strtoupper( $extproperties[$j] )] = trim( $extvalues[$j] );
2267              }
2268              $cnt = preg_match_all( $id_class_exp, $extstyle[1][$i], $id_class_info );
2269              // $this->debug("ID=".$id_class_exp."<br>");
2270              // $this->debug("STR='".$extstyle[1][$i]."'<br>");
2271              // $this->debug("CNT=".$cnt."<br>");
2272              for( $j = 0;$j < count( $id_class_info[0] );$j++ ) {
2273                  // TODO: Need to check conversion to upper case
2274                  // $this->debug("RES".$j."='".$id_class_info[1][$j]."''".$id_class_info[2][$j]."''".$id_class_info[3][$j]."'<br>");
2275                  if ( $id_class_info[2][$j] == '#' ) {
2276                      // Id with or without element
2277                      // $this->debug($id_class_info[0][$j]."=>".$extclassproperties."<br>");
2278                      $this->add_properties( $this->CSS_ids[strtoupper( $id_class_info[1][$j] )][$id_class_info[3][$j]], $extclassproperties );
2279                  } else if ( $id_class_info[2][$j] == '.' ) {
2280                      // class with or without element
2281                      // $this->debug($id_class_info[0][$j]."=>".$extclassproperties."<br>");
2282                      $this->add_properties( $this->CSS_classes[strtoupper( $id_class_info[1][$j] )][$id_class_info[3][$j]], $extclassproperties );
2283                  } else {
2284                      // class only
2285                      // $this->debug($id_class_info[0][$j]."=>".$extclassproperties."<br>");
2286                      $this->add_properties( $this->CSS_elements[$id_class_info[3][$j]], $extclassproperties );
2287                  }
2288              }
2289              $extproperties = array();
2290              $extvalues = array();
2291              $extclassproperties = array();
2292          }
2293      }
2294  
2295  	function ReadCSS( $html )
2296      {
2297          // ! @desc CSS parser
2298          // ! @return string
2299          /*
2300      * This version ONLY supports:  .class {...} / #id { .... }
2301      * It does NOT support: body{...} / a#hover { ... } / p.right { ... } / other mixed names
2302      * This function must read the CSS code (internal or external) and order its value inside $this->CSS.
2303      * Add support for: selector.class:pseudo-class { property: value }
2304      * Add support for respecting the cascading order (see http://www.htmlhelp.com/reference/css/structure.html)
2305      *  (-> add lists defining weigth and order)
2306      */
2307          // TODO:
2308          // Check '... ! ...' values in properties;
2309          // Remove quotes ("") from values in properties;
2310          // Cumulate properties (in stead of replacing them all?)
2311          // DONE:
2312          // a#hover, p.right are interpreted.  To be used elsewhere in the code.
2313          $match = 0; // no match yet
2314          $regexp = ''; // This helps debugging: showing what is the REAL string being processed
2315  
2316          // CSS inside external files
2317          // ///////////////////////////////////////////////////////////////////////////////
2318          // Find links to CSS in external files
2319          // ///////////////////////////////////////////////////////////////////////////////
2320          $regexp = '/<link rel=["\']stylesheet["\'].*?href=[\'"](.+?)[\'"]\\s*?\/?>/si';
2321          $regexp = '/<(link\\s.*?)>/si';
2322          $match = preg_match_all( $regexp, $html, $CSSext );
2323          $ind = 0;
2324          $attr = array();
2325  
2326          foreach ( $CSSext[1] as $CSSlink ) {
2327              $this->GetTagAndAttrs( $CSSlink, $tag, $attr );
2328              $this->debug( "LINK:$CSSlink " . $attr['HREF'] . "<br>" );
2329              if ( is_array( $attr ) )
2330                  foreach ( $attr as $k => $v ) {
2331                  $this->debug( "LINKATTR: $k $v<br>" );
2332              }
2333              if ( isset( $attr['REL'] ) && isset( $attr['HREF'] ) && ( strtoupper( $attr['REL'] ) == 'STYLESHEET' ) ) {
2334                  if ( !isset( $attr['MEDIA'] ) || ereg( 'print', $attr['MEDIA'] ) ) {
2335                      // //////////////
2336                      // Get the file
2337                      $CSSextblock = file_get_contents( $attr['HREF'] );
2338                      $this->debug( "------------ Accepting " . $attr['HREF'] . "-------<br>" );
2339                      // Remove comments
2340                      $CSSextblock = preg_replace( "{/\*.*?\*/}s", "", $CSSextblock );
2341                      $CSSextblock = preg_replace( "{//.*?$}sm", "", $CSSextblock );
2342  
2343                      $this->ParseStyle( $CSSextblock );
2344                  } else {
2345                      $this->debug( '------------ Ignoring ' . $attr['HREF'] . '-------<br>' );
2346                  }
2347              }
2348          } //end of match
2349          // CSS internal
2350          // Get content between tags and order it, using regexp
2351          $regexp = '/<(style.*?)>(.*?)<\/style>/si'; // it can be <style> or <style type="txt/css">
2352          $match = preg_match_all( $regexp, $html, $CSSblock );
2353  
2354          $ind = 0;
2355          while ( $match ) {
2356              $this->GetTagAndAttrs( $CSSblock[1][$ind], $tag, $attr );
2357              if ( !isset( $attr['MEDIA'] ) || ereg( 'print', $attr['MEDIA'] ) ) {
2358                  $this->debug( '------------ Accepting CSS -------<br>' . $CSSblock[2][$ind] . '<br>---------- end of CSS block -----------<br>' );
2359                  $this->ParseStyle( $CSSblock[2][$ind] );
2360              } else {
2361                  $this->debug( '------------ Ignoring -------<br>' . $CSSblock[2][$ind] . '<br>---------- end of ignored block -----------<br>' );
2362              }
2363              $match--;
2364              $ind++;
2365          } // end of match
2366          // Remove CSS (tags and content), if any
2367          $regexp = '/<style.*?>.*?<\/style>/si'; // it can be <style> or <style type="txt/css">
2368          $html = preg_replace( $regexp, '', $html );
2369  
2370          return $html;
2371      }
2372  
2373  	function readInlineCSS( $html )
2374      {
2375          // ! @return array
2376          // ! @desc Reads inline CSS and returns an array of properties
2377          // Fix incomplete CSS code
2378          $size = strlen( $html )-1;
2379          if ( $html{$size} != ';' ) $html .= ';';
2380          // Make CSS[Name-of-the-class] = array(key => value)
2381          $regexp = '|\\s*?(\\S+?):(.+?);|i'; // TODO
2382          preg_match_all( $regexp, $html, $styleinfo );
2383          $properties = $styleinfo[1];
2384          $values = $styleinfo[2];
2385          // Array-properties and Array-values must have the SAME SIZE!
2386          $classproperties = array();
2387          for( $i = 0; $i < count( $properties ) ; $i++ ) $classproperties[strtoupper( $properties[$i] )] = trim( $values[$i] );
2388  
2389          return $classproperties;
2390      }
2391  
2392  	function setCSS( $arrayaux )
2393      {
2394          // ! @return void
2395          // ! @desc Change some class attributes according to CSS properties
2396          if ( !is_array( $arrayaux ) ) return; //Removes PHP Warning
2397          foreach( $arrayaux as $k => $v ) {
2398              $this->CSSproperties[$k] = $v; // Update current properties
2399              $this->debug( "Set property $k = $v <br>" );
2400              // $k : CSS property
2401              // $v : CSS property value
2402              switch ( $k ) {
2403                  case 'WIDTH':
2404                      $this->divwidth = ConvertSize( $v, $this->pgwidth );
2405                      break;
2406                  case 'HEIGHT':
2407                      $this->divheight = ConvertSize( $v, $this->pgwidth );
2408                      break;
2409                  case 'BORDER': // width style color (width not supported correctly - it is always considered as normal)
2410                      $prop = explode( ' ', $v );
2411                      if ( count( $prop ) != 3 ) break; // Not supported: borders not fully declared
2412                      // style: dashed dotted none (anything else => solid )
2413                      if ( strnatcasecmp( $prop[1], "dashed" ) == 0 ) { // found "dashed"! (ignores case)
2414                          $this->dash_on = true;
2415                          $this->SetDash( 2, 2 ); //2mm on, 2mm off
2416                      } elseif ( strnatcasecmp( $prop[1], "dotted" ) == 0 ) { // found "dotted"! (ignores case)
2417                          $this->dotted_on = true;
2418                      } elseif ( strnatcasecmp( $prop[1], "none" ) == 0 ) $this->divborder = 0;
2419                      else $this->divborder = 1;
2420                      // color
2421                      $coul = ConvertColor( $prop[2] );
2422                      $this->SetDrawColor( $coul['R'], $coul['G'], $coul['B'] );
2423                      $this->issetcolor = true;
2424                      break;
2425                  case 'FONT-FAMILY': // one of the $this->fontlist fonts
2426                      // If it is a font list, get all font types
2427                      $aux_fontlist = explode( ",", $v );
2428                      $fontarraysize = count( $aux_fontlist );
2429                      for( $i = 0;$i < $fontarraysize;$i++ ) {
2430                          $fonttype = $aux_fontlist[$i];
2431                          $fonttype = trim( $fonttype );
2432                          // If font is found, set it, and exit loop
2433                          if ( in_array( strtolower( $fonttype ), $this->fontlist ) ) {
2434                              $this->SetFont( strtolower( $fonttype ) );
2435                              break;
2436                          }
2437                          // If font = "courier new" for example, try simply looking for "courier"
2438                          $fonttype = explode( " ", $fonttype );
2439                          $fonttype = $fonttype[0];
2440                          if ( in_array( strtolower( $fonttype ), $this->fontlist ) ) {
2441                              $this->SetFont( strtolower( $fonttype ) );
2442                              break;
2443                          }
2444                      }
2445                      break;
2446                  case 'FONT-SIZE': // Does not support: smaller, larger
2447                      if ( is_numeric( $v{0} ) ) {
2448                          $mmsize = ConvertSize( $v, $this->pgwidth );
2449                          $this->SetFontSize( $mmsize * ( 72 / 25.4 ) ); //Get size in points (pt)
2450                      } else {
2451                          $v = strtoupper( $v );
2452                          switch ( $v ) {
2453                              // Values obtained from http://www.w3schools.com/html/html_reference.asp
2454                              case 'XX-SMALL': $this->SetFontSize( ( 0.7 ) * 11 );
2455                                  break;
2456                              case 'X-SMALL': $this->SetFontSize( ( 0.77 ) * 11 );
2457                                  break;
2458                              case 'SMALL': $this->SetFontSize( ( 0.86 ) * 11 );
2459                                  break;
2460                              case 'MEDIUM': $this->SetFontSize( 11 );
2461                                  break;
2462                              case 'LARGE': $this->SetFontSize( ( 1.2 ) * 11 );
2463                                  break;
2464                              case 'X-LARGE': $this->SetFontSize( ( 1.5 ) * 11 );
2465                                  break;
2466                              case 'XX-LARGE': $this->SetFontSize( 2 * 11 );
2467                                  break;
2468                          }
2469                      }
2470                      break;
2471                  case 'FONT-STYLE': // italic normal oblique
2472                      switch ( strtoupper( $v ) ) {
2473                          case 'ITALIC':
2474                          case 'OBLIQUE':
2475                              $this->SetStyle( 'I', true );
2476                              break;
2477                          case 'NORMAL': break;
2478                      }
2479                      break;
2480                  case 'FONT-WEIGHT': // normal bold //Does not support: bolder, lighter, 100..900(step value=100)
2481                      switch ( strtoupper( $v ) ) {
2482                          case 'BOLD':
2483                              $this->SetStyle( 'B', true );
2484                              break;
2485                          case 'NORMAL': break;
2486                      }
2487                      break;
2488                  case 'TEXT-DECORATION': // none underline //Does not support: overline, blink
2489                      switch ( strtoupper( $v ) ) {
2490                          case 'LINE-THROUGH':
2491                              $this->strike = true;
2492                              break;
2493                          case 'UNDERLINE':
2494                              $this->SetStyle( 'U', true );
2495                              break;
2496                          case 'NONE': break;
2497                      }
2498                  case 'TEXT-TRANSFORM': // none uppercase lowercase //Does not support: capitalize
2499                      switch ( strtoupper( $v ) ) { // Not working 100%
2500                          case 'UPPERCASE':
2501                              $this->toupper = true;
2502                              break;
2503                          case 'LOWERCASE':
2504                              $this->tolower = true;
2505                              break;
2506                          case 'NONE': break;
2507                      }
2508                  case 'TEXT-ALIGN': // left right center justify
2509                      switch ( strtoupper( $v ) ) {
2510                          case 'LEFT':
2511                              $this->divalign = "L";
2512                              break;
2513                          case 'CENTER':
2514                              $this->divalign = "C";
2515                              break;
2516                          case 'RIGHT':
2517                              $this->divalign = "R";
2518                              break;
2519                          case 'JUSTIFY':
2520                              $this->divalign = "J";
2521                              break;
2522                      }
2523                      break;
2524                  case 'DIRECTION': // ltr(default) rtl
2525                      if ( strtolower( $v ) == 'rtl' ) $this->divrevert = true;
2526                      break;
2527                  case 'BACKGROUND': // bgcolor only
2528                      // correction for BUG in htmltoolkit??
2529                      if ( strtolower( $v ) == 'none' ) $v = '#FFFFFF';
2530                      // end of correction
2531                      $cor = ConvertColor( $v );
2532                      $this->bgcolorarray = $cor;
2533                      $this->SetFillColor( $cor['R'], $cor['G'], $cor['B'] );
2534                      $this->divbgcolor = true;
2535                      break;
2536                  case 'COLOR': // font color
2537                      $cor = ConvertColor( $v );
2538                      $this->colorarray = $cor;
2539                      $this->SetTextColor( $cor['R'], $cor['G'], $cor['B'] );
2540                      $this->issetcolor = true;
2541                      break;
2542                  case 'DISPLAY':
2543                      if ( strtolower( $v ) == 'none' ) {
2544                          $this->isdisplay = false;
2545                      }
2546                      break;
2547              } //end of switch($k)
2548          } //end of foreach
2549      }
2550  
2551  	function SetStyle( $tag, $enable )
2552      {
2553          // ! @return void
2554          // ! @desc Enables/Disables B,I,U styles
2555          // Modify style and select corresponding font
2556          $this->$tag += ( $enable ? 1 : -1 );
2557          $style = '';
2558          // Fix some SetStyle misuse
2559          if ( $this->$tag < 0 ) $this->$tag = 0;
2560          if ( $this->$tag > 1 ) $this->$tag = 1;
2561          foreach( array( 'B', 'I', 'U' ) as $s )
2562          if ( $this->$s > 0 )
2563              $style .= $s;
2564  
2565          $this->currentstyle = $style;
2566          $this->SetFont( '', $style );
2567      }
2568  
2569  	function DisableTags( $str = '' )
2570      {
2571          // ! @return void
2572          // ! @desc Disable some tags using ',' as separator. Enable all tags calling this function without parameters.
2573          if ( $str == '' ) { // enable all tags
2574              // Insert new supported tags in the long string below.
2575              $this->enabledtags = "<body><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>";
2576          } else {
2577              $str = explode( ",", $str );
2578              foreach( $str as $v ) $this->enabledtags = str_replace( trim( $v ), '', $this->enabledtags );
2579          }
2580      }
2581      // //////////////////////TABLE CODE (from PDFTable)/////////////////////////////////////
2582      // Thanks to vietcom (vncommando at yahoo dot com)
2583      /*     Modified by Renato Coelho
2584       in order to print tables that span more than 1 page and to allow
2585       bold,italic and the likes inside table cells (and alignment now works with styles!)
2586    */
2587      // table        Array of (w, h, bc, nr, wc, hr, cells)
2588      // w            Width of table
2589      // h            Height of table
2590      // nc        Number column
2591      // nr        Number row
2592      // hr        List of height of each row
2593      // wc        List of width of each column
2594      // cells        List of cells of each rows, cells[i][j] is a cell in the table
2595  	function _tableColumnWidth( &$table )
2596      {
2597          // ! @return void
2598          $cs = &$table['cells'];
2599          $mw = $this->getStringWidth( 'W' );
2600          $nc = $table['nc'];
2601          $nr = $table['nr'];
2602          $listspan = array();
2603          // Xac dinh do rong cua cac cell va cac cot tuong ung
2604          for( $j = 0 ; $j < $nc ; $j++ ) { // columns
2605              $wc = &$table['wc'][$j];
2606              for( $i = 0 ; $i < $nr ; $i++ ) { // rows
2607                  if ( isset( $cs[$i][$j] ) && $cs[$i][$j] ) {
2608                      $c = &$cs[$i][$j];
2609                      $miw = $mw;
2610                      if ( isset( $c['maxs'] ) && $c['maxs'] != '' ) $c['s'] = $c['maxs'];
2611                      $c['maw'] = $c['s'];
2612                      if ( isset( $c['nowrap'] ) ) $miw = $c['maw'];
2613                      if ( isset( $c['w'] ) ) {
2614                          if ( $miw < $c['w'] ) $c['miw'] = $c['w'];
2615                          if ( $miw > $c['w'] ) $c['miw'] = $c['w'] = $miw;
2616                          if ( !isset( $wc['w'] ) ) $wc['w'] = 1;
2617                      } else $c['miw'] = $miw;
2618                      if ( $c['maw'] < $c['miw'] ) $c['maw'] = $c['miw'];
2619                      if ( !isset( $c['colspan'] ) ) {
2620                          if ( $wc['miw'] < $c['miw'] ) $wc['miw'] = $c['miw'];
2621                          if ( $wc['maw'] < $c['maw'] ) $wc['maw'] = $c['maw'];
2622                      } else $listspan[] = array( $i, $j );
2623                      // Check if minimum width of the whole column is big enough for a huge word to fit
2624                      $auxtext = implode( "", $c['text'] );
2625                      $minwidth = $this->WordWrap( $auxtext, $wc['miw']-2 ); // -2 == margin
2626                      if ( $minwidth < 0 && ( - $minwidth ) > $wc['miw'] ) $wc['miw'] = ( - $minwidth ) + 2; //increase minimum width
2627                      if ( $wc['miw'] > $wc['maw'] ) $wc['maw'] = $wc['miw']; //update maximum width, if needed
2628                  }
2629              } //rows
2630          } //columns
2631          // Xac dinh su anh huong cua cac cell colspan len cac cot va nguoc lai
2632          $wc = &$table['wc'];
2633          foreach ( $listspan as $span ) {
2634              list( $i, $j ) = $span;
2635              $c = &$cs[$i][$j];
2636              $lc = $j + $c['colspan'];
2637              if ( $lc > $nc ) $lc = $nc;
2638  
2639              $wis = $wisa = 0;
2640              $was = $wasa = 0;
2641              $list = array();
2642              for( $k = $j;$k < $lc;$k++ ) {
2643                  $wis += $wc[$k]['miw'];
2644                  $was += $wc[$k]['maw'];
2645                  if ( !isset( $c['w'] ) ) {
2646                      $list[] = $k;
2647                      $wisa += $wc[$k]['miw'];
2648                      $wasa += $wc[$k]['maw'];
2649                  }
2650              }
2651              if ( $c['miw'] > $wis ) {
2652                  if ( !$wis ) { // Cac cot chua co kich thuoc => chia deu
2653                      for( $k = $j;$k < $lc;$k++ ) $wc[$k]['miw'] = $c['miw'] / $c['colspan'];
2654                  } elseif ( !count( $list ) ) { // Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
2655                      $wi = $c['miw'] - $wis;
2656                      for( $k = $j;$k < $lc;$k++ ) $wc[$k]['miw'] += ( $wc[$k]['miw'] / $wis ) * $wi;
2657                  } else { // Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2658                      $wi = $c['miw'] - $wis;
2659                      foreach ( $list as $k ) $wc[$k]['miw'] += ( $wc[$k]['miw'] / $wisa ) * $wi;
2660                  }
2661              }
2662              if ( $c['maw'] > $was ) {
2663                  if ( !$wis ) { // Cac cot chua co kich thuoc => chia deu
2664                      for( $k = $j;$k < $lc;$k++ ) $wc[$k]['maw'] = $c['maw'] / $c['colspan'];
2665                  } elseif ( !count( $list ) ) {
2666                      // Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
2667                      $wi = $c['maw'] - $was;
2668                      for( $k = $j;$k < $lc;$k++ ) $wc[$k]['maw'] += ( $wc[$k]['maw'] / $was ) * $wi;
2669                  } else { // Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2670                      $wi = $c['maw'] - $was;
2671                      foreach ( $list as $k ) $wc[$k]['maw'] += ( $wc[$k]['maw'] / $wasa ) * $wi;
2672                  }
2673              }
2674          }
2675      }
2676  
2677  	function _tableWidth( &$table )
2678      {
2679          // ! @return void
2680          // ! @desc Calculates the Table Width
2681          //  @desc Xac dinh chieu rong cua table
2682          $widthcols = &$table['wc'];
2683          $numcols = $table['nc'];
2684          $tablewidth = 0;
2685          for ( $i = 0 ; $i < $numcols ; $i++ ) {
2686              $tablewidth += isset( $widthcols[$i]['w'] ) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
2687          }
2688          if ( $tablewidth > $this->pgwidth ) $table['w'] = $this->pgwidth;
2689          if ( isset( $table['w'] ) ) {
2690              $wis = $wisa = 0;
2691              $list = array();
2692              for( $i = 0 ; $i < $numcols ; $i++ ) {
2693                  $wis += $widthcols[$i]['miw'];
2694                  if ( !isset( $widthcols[$i]['w'] ) ) {
2695                      $list[] = $i;
2696                      $wisa += $widthcols[$i]['miw'];
2697                  }
2698              }
2699              if ( $table['w'] > $wis ) {
2700                  if ( !count( $list ) ) { // Khong co cot nao co kich thuoc auto => chia deu phan du cho tat ca
2701                      // http://www.ksvn.com/anhviet_new.htm - translating comments...
2702                      // bent shrink essence move size measure automatic => divide against give as a whole
2703                      // $wi = $table['w'] - $wis;
2704                      $wi = ( $table['w'] - $wis ) / $numcols;
2705                      for( $k = 0;$k < $numcols;$k++ )
2706                      // $widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wis)*$wi;
2707                      $widthcols[$k]['miw'] += $wi;
2708                  } else { // Co mot so cot co kich thuoc auto => chia deu phan du cho cac cot auto
2709                      // $wi = $table['w'] - $wis;
2710                      $wi = ( $table['w'] - $wis ) / count( $list );
2711                      foreach ( $list as $k )
2712                      // $widthcols[$k]['miw'] += ($widthcols[$k]['miw']/$wisa)*$wi;
2713                      $widthcols[$k]['miw'] += $wi;
2714                  }
2715              }
2716              for ( $i = 0;$i < $numcols;$i++ ) {
2717                  $tablewidth = $widthcols[$i]['miw'];
2718                  unset( $widthcols[$i] );
2719                  $widthcols[$i] = $tablewidth;
2720              }
2721          } else { // table has no width defined
2722              $table['w'] = $tablewidth;
2723              for ( $i = 0 ; $i < $numcols ; $i++ ) {
2724                  $tablewidth = isset( $widthcols[$i]['w'] ) ? $widthcols[$i]['miw'] : $widthcols[$i]['maw'];
2725                  unset( $widthcols[$i] );
2726                  $widthcols[$i] = $tablewidth;
2727              }
2728          }
2729      }
2730  
2731  	function _tableHeight( &$table )
2732      {
2733          // ! @return void
2734          // ! @desc Calculates the Table Height
2735          $cells = &$table['cells'];
2736          $numcols = $table['nc'];
2737          $numrows = $table['nr'];
2738          $listspan = array();
2739          for( $i = 0 ; $i < $numrows ; $i++ ) { // rows
2740              $heightrow = &$table['hr'][$i];
2741              for( $j = 0 ; $j < $numcols ; $j++ ) { // columns
2742                  if ( isset( $cells[$i][$j] ) && $cells[$i][$j] ) {
2743                      $c = &$cells[$i][$j];
2744                      list( $x, $cw ) = $this->_tableGetWidth( $table, $i, $j );
2745                      // Check whether width is enough for this cells' text
2746                      $auxtext = implode( "", $c['text'] );
2747                      $auxtext2 = $auxtext; //in case we have text with styles
2748                      $nostyles_size = $this->GetStringWidth( $auxtext ) + 3; // +3 == margin
2749                      $linesneeded = $this->WordWrap( $auxtext, $cw-2 ); // -2 == margin
2750                      if ( $c['s'] > $nostyles_size && !isset( $c['form'] ) ) { // Text with styles
2751                          $auxtext = $auxtext2; //recover original characteristics (original /n placements)
2752                          $diffsize = $c['s'] - $nostyles_size; //with bold et al. char width gets a bit bigger than plain char
2753                          if ( $linesneeded == 0 ) $linesneeded = 1; //to avoid division by zero
2754                          $diffsize /= $linesneeded;
2755                          $linesneeded = $this->WordWrap( $auxtext, $cw-2 - $diffsize ); //diffsize used to wrap text correctly
2756                      }
2757                      if ( isset( $c['form'] ) ) {
2758                          $linesneeded = ceil( ( $c['s']-3 ) / ( $cw-2 ) ); //Text + form in a cell
2759                          // Presuming the use of styles
2760                          if ( ( $this->GetStringWidth( $auxtext ) + 3 ) > ( $cw-2 ) ) $linesneeded++;
2761                      }
2762                      $ch = $linesneeded * 1.1 * $this->lineheight;
2763                      // If height is bigger than page height...
2764                      if ( $ch > ( $this->fh - $this->bMargin - $this->tMargin ) ) $ch = ( $this->fh - $this->bMargin - $this->tMargin );
2765                      // If height is defined and it is bigger than calculated $ch then update values
2766                      if ( isset( $c['h'] ) && $c['h'] > $ch ) {
2767                          $c['mih'] = $ch; //in order to keep valign working
2768                          $ch = $c['h'];
2769                      } else $c['mih'] = $ch;
2770                      if ( isset( $c['rowspan'] ) ) $listspan[] = array( $i, $j );
2771                      elseif ( $heightrow < $ch ) $heightrow = $ch;
2772                      if ( isset( $c['form'] ) ) $c['mih'] = $ch;
2773                  }
2774              } //end of columns
2775          } //end of rows
2776          $heightrow = &$table['hr'];
2777          foreach ( $listspan as $span ) {
2778              list( $i, $j ) = $span;
2779              $c = &$cells[$i][$j];
2780              $lr = $i + $c['rowspan'];
2781              if ( $lr > $numrows ) $lr = $numrows;
2782              $hs = $hsa = 0;
2783              $list = array();
2784              for( $k = $i;$k < $lr;$k++ ) {
2785                  $hs += $heightrow[$k];
2786                  if ( !isset( $c['h'] ) ) {
2787                      $list[] = $k;
2788                      $hsa += $heightrow[$k];
2789                  }
2790              }
2791              if ( $c['mih'] > $hs ) {
2792                  if ( !$hs ) { // Cac dong chua co kich thuoc => chia deu
2793                      for( $k = $i;$k < $lr;$k++ ) $heightrow[$k] = $c['mih'] / $c['rowspan'];
2794                  } elseif ( !count( $list ) ) { // Khong co dong nao co kich thuoc auto => chia deu phan du cho tat ca
2795                      $hi = $c['mih'] - $hs;
2796                      for( $k = $i;$k < $lr;$k++ ) $heightrow[$k] += ( $heightrow[$k] / $hs ) * $hi;
2797                  } else { // Co mot so dong co kich thuoc auto => chia deu phan du cho cac dong auto
2798                      $hi = $c['mih'] - $hsa;
2799                      foreach ( $list as $k ) $heightrow[$k] += ( $heightrow[$k] / $hsa ) * $hi;
2800                  }
2801              }
2802          }
2803      }
2804  
2805  	function _tableGetWidth( &$table, $i, $j )
2806      {
2807          // ! @return array (x,w)
2808          //  @desc Xac dinh toa do va do rong cua mot cell
2809          $cell = &$table['cells'][$i][$j];
2810          if ( $cell ) {
2811              if ( isset( $cell['x0'] ) ) return array( $cell['x0'], $cell['w0'] );
2812              $x = 0;
2813              $widthcols = &$table['wc'];
2814              for( $k = 0 ; $k < $j ; $k++ ) $x += $widthcols[$k];
2815              $w = $widthcols[$j];
2816              if ( isset( $cell['colspan'] ) ) {
2817                  for ( $k = $j + $cell['colspan']-1 ; $k > $j ; $k-- ) $w += $widthcols[$k];
2818              }
2819              $cell['x0'] = $x;
2820              $cell['w0'] = $w;
2821              return array( $x, $w );
2822          }
2823          return array( 0, 0 );
2824      }
2825  
2826  	function _tableGetHeight( &$table, $i, $j )
2827      {
2828          // ! @return array (y,h)
2829          $cell = &$table['cells'][$i][$j];
2830          if ( $cell ) {
2831              if ( isset( $cell['y0'] ) ) return array( $cell['y0'], $cell['h0'] );
2832              $y = 0;
2833              $heightrow = &$table['hr'];
2834              for ( $k = 0;$k < $i;$k++ ) $y += $heightrow[$k];
2835              $h = $heightrow[$i];
2836              if ( isset( $cell['rowspan'] ) ) {
2837                  for ( $k = $i + $cell['rowspan']-1;$k > $i;$k-- )
2838                  $h += $heightrow[$k];
2839              }
2840              $cell['y0'] = $y;
2841              $cell['h0'] = $h;
2842              return array( $y, $h );
2843          }
2844          return array( 0, 0 );
2845      }
2846  
2847  	function _tableRect( $x, $y, $w, $h, $type = 1 )
2848      {
2849          // ! @return void
2850          if ( $type == 1 ) $this->Rect( $x, $y, $w, $h );
2851          elseif ( strlen( $type ) == 4 ) {
2852              $x2 = $x + $w;
2853              $y2 = $y + $h;
2854              if ( intval( $type{0} ) ) $this->Line( $x , $y , $x2, $y );
2855              if ( intval( $type{1} ) ) $this->Line( $x2, $y , $x2, $y2 );
2856              if ( intval( $type{2} ) ) $this->Line( $x , $y2, $x2, $y2 );
2857              if ( intval( $type{3} ) ) $this->Line( $x , $y , $x , $y2 );
2858          }
2859      }
2860  
2861  	function _tableWrite( &$table )
2862      {
2863          // ! @desc Main table function
2864          // ! @return void
2865          $cells = &$table['cells'];
2866          $numcols = $table['nc'];
2867          $numrows = $table['nr'];
2868          $x0 = $this->x;
2869          $y0 = $this->y;
2870          $right = $this->pgwidth - $this->rMargin;
2871          if ( isset( $table['a'] ) && ( $table['w'] != $this->pgwidth ) ) {
2872              if ( $table['a'] == 'C' ) $x0 += ( ( $right - $x0 ) - $table['w'] ) / 2;
2873              elseif ( $table['a'] == 'R' ) $x0 = $right - $table['w'];
2874          }
2875          $returny = 0;
2876          $tableheader = array();
2877          // Draw Table Contents and Borders
2878          for( $i = 0 ; $i < $numrows ; $i++ ) { // Rows
2879              $skippage = false;
2880              for( $j = 0 ; $j < $numcols ; $j++ ) { // Columns
2881                  if ( isset( $cells[$i][$j] ) && $cells[$i][$j] ) {
2882                      $cell = &$cells[$i][$j];
2883                      list( $x, $w ) = $this->_tableGetWidth( $table, $i, $j );
2884                      list( $y, $h ) = $this->_tableGetHeight( $table, $i, $j );
2885                      $x += $x0;
2886                      $y += $y0;
2887                      $y -= $returny;
2888                      if ( ( ( $y + $h ) > ( $this->fh - $this->bMargin ) ) && ( $y0 > 0 || $x0 > 0 ) ) {
2889                          if ( !$skippage ) {
2890                              $y -= $y0;
2891                              $returny += $y;
2892                              $this->AddPage();
2893                              if ( $this->usetableheader ) $this->Header( $tableheader );
2894                              if ( $this->usetableheader ) $y0 = $this->y;
2895                              else $y0 = $this->tMargin;
2896                              $y = $y0;
2897                          }
2898                          $skippage = true;
2899                      }
2900                      // Align
2901                      $this->x = $x;
2902                      $this->y = $y;
2903                      $align = isset( $cell['a'] )? $cell['a'] : 'L';
2904                      // Vertical align
2905                      if ( !isset( $cell['va'] ) || $cell['va'] == 'M' ) $this->y += ( $h - $cell['mih'] ) / 2;
2906                      elseif ( isset( $cell['va'] ) && $cell['va'] == 'B' ) $this->y += $h - $cell['mih'];
2907                      // Fill
2908                      $fill = isset( $cell['bgcolor'] ) ? $cell['bgcolor']
2909                      : ( isset( $table['bgcolor'][$i] ) ? $table['bgcolor'][$i]
2910                          : ( isset( $table['bgcolor'][-1] ) ? $table['bgcolor'][-1] : 0 ) );
2911                      if ( $fill ) {
2912                          $color = ConvertColor( $fill );
2913                          $this->SetFillColor( $color['R'], $color['G'], $color['B'] );
2914                          $this->Rect( $x, $y, $w, $h, 'F' );
2915                      }
2916                      // Border
2917                      if ( isset( $cell['border'] ) ) $this->_tableRect( $x, $y, $w, $h, $cell['border'] );
2918                      elseif ( isset( $table['border'] ) && $table['border'] ) $this->Rect( $x, $y, $w, $h );
2919                      $this->divalign = $align;
2920                      $this->divwidth = $w-2;
2921                      // Get info of first row == table header
2922                      if ( $this->usetableheader && $i == 0 ) {
2923                          $tableheader[$j]['x'] = $x;
2924                          $tableheader[$j]['y'] = $y;
2925                          $tableheader[$j]['h'] = $h;
2926                          $tableheader[$j]['w'] = $w;
2927                          $tableheader[$j]['text'] = $cell['text'];
2928                          $tableheader[$j]['textbuffer'] = $cell['textbuffer'];
2929                          $tableheader[$j]['a'] = isset( $cell['a'] )? $cell['a'] : 'L';
2930                          $tableheader[$j]['va'] = $cell['va'];
2931                          $tableheader[$j]['mih'] = $cell['mih'];
2932                          $tableheader[$j]['bgcolor'] = $fill;
2933                          if ( $table['border'] ) $tableheader[$j]['border'] = 'all';
2934                          elseif ( isset( $cell['border'] ) ) $tableheader[$j]['border'] = $cell['border'];
2935                      }
2936                      if ( !empty( $cell['textbuffer'] ) ) $this->printbuffer( $cell['textbuffer'], false, true/*inside a table*/ );
2937                      // Reset values
2938                      $this->Reset();
2939                  } //end of (if isset(cells)...)
2940              } // end of columns
2941              if ( $i == $numrows-1 ) $this->y = $y + $h; //last row jump (update this->y position)
2942          } // end of rows
2943      } //END OF FUNCTION _tableWrite()
2944      // ///////////////////////END OF TABLE CODE//////////////////////////////////
2945  } //end of Class
2946  
2947  ?>


Generated: Wed Dec 30 05:55:15 2009 Cross-referenced by PHPXref 0.7