phpgroupware-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Phpgroupware-cvs] property/pdf/class.ezpdf.php, 1.1.1.3


From: nomail
Subject: [Phpgroupware-cvs] property/pdf/class.ezpdf.php, 1.1.1.3
Date: Fri, 21 May 2004 19:12:23 -0000

Update of /property/pdf
Modified Files:
        Branch: 
          class.ezpdf.php

date: 2004/04/23 21:26:42;  author: sigurdne;  state: Exp;  lines: +1556 -1556

Log Message:
no message
=====================================================================
Index: property/pdf/class.ezpdf.php
diff -u property/pdf/class.ezpdf.php:1.1.1.2 
property/pdf/class.ezpdf.php:1.1.1.3
--- property/pdf/class.ezpdf.php:1.1.1.2        Fri Apr 23 20:27:26 2004
+++ property/pdf/class.ezpdf.php        Fri Apr 23 21:26:42 2004
@@ -1,1557 +1,1557 @@
-<?php
-
-//include_once('class.pdf.php');
-//include_once (PHPGW_APP_INC . '/pdf/class.pdf.php');
-
-class pdf extends pdf_ {
-//==============================================================================
-// this class will take the basic interaction facilities of the Cpdf class
-// and make more useful functions so that the user does not have to
-// know all the ins and outs of pdf presentation to produce something pretty.
-//
-// IMPORTANT NOTE
-// there is no warranty, implied or otherwise with this software.
-//
-// version 009 (versioning is linked to class.pdf.php)
-//
-// released under a public domain licence.
-//
-// Wayne Munro, R&OS Ltd, http://www.ros.co.nz/pdf
-//==============================================================================
-
-var $ez=array('fontSize'=>10); // used for storing most of the page 
configuration parameters
-var $y; // this is the current vertical positon on the page of the writing 
point, very important
-var $ezPages=array(); // keep an array of the ids of the pages, making it easy 
to go back and add page numbers etc.
-var $ezPageCount=0;
-
-// 
------------------------------------------------------------------------------
-
-function pdf($paper='a4',$orientation='portrait'){
-       // Assuming that people don't want to specify the paper size using the 
absolute coordinates
-       // allow a couple of options:
-       // orientation can be 'portrait' or 'landscape'
-       // or, to actually set the coordinates, then pass an array in as the 
first parameter.
-       // the defaults are as shown.
-       //
-       // -------------------------
-       // 2002-07-24 - Nicola Asuni (address@hidden):
-       // Added new page formats (45 standard ISO paper formats and 4 american 
common formats)
-       // paper cordinates are calculated in this way: (inches * 72) where 1 
inch = 2.54 cm
-       //
-       // Now you may also pass a 2 values array containing the page width and 
height in centimeters
-       // -------------------------
-
-       if (!is_array($paper)){
-               switch (strtoupper($paper)){
-                       case '4A0': {$size = array(0,0,4767.87,6740.79); break;}
-                       case '2A0': {$size = array(0,0,3370.39,4767.87); break;}
-                       case 'A0': {$size = array(0,0,2383.94,3370.39); break;}
-                       case 'A1': {$size = array(0,0,1683.78,2383.94); break;}
-                       case 'A2': {$size = array(0,0,1190.55,1683.78); break;}
-                       case 'A3': {$size = array(0,0,841.89,1190.55); break;}
-                       case 'A4': default: {$size = array(0,0,595.28,841.89); 
break;}
-                       case 'A5': {$size = array(0,0,419.53,595.28); break;}
-                       case 'A6': {$size = array(0,0,297.64,419.53); break;}
-                       case 'A7': {$size = array(0,0,209.76,297.64); break;}
-                       case 'A8': {$size = array(0,0,147.40,209.76); break;}
-                       case 'A9': {$size = array(0,0,104.88,147.40); break;}
-                       case 'A10': {$size = array(0,0,73.70,104.88); break;}
-                       case 'B0': {$size = array(0,0,2834.65,4008.19); break;}
-                       case 'B1': {$size = array(0,0,2004.09,2834.65); break;}
-                       case 'B2': {$size = array(0,0,1417.32,2004.09); break;}
-                       case 'B3': {$size = array(0,0,1000.63,1417.32); break;}
-                       case 'B4': {$size = array(0,0,708.66,1000.63); break;}
-                       case 'B5': {$size = array(0,0,498.90,708.66); break;}
-                       case 'B6': {$size = array(0,0,354.33,498.90); break;}
-                       case 'B7': {$size = array(0,0,249.45,354.33); break;}
-                       case 'B8': {$size = array(0,0,175.75,249.45); break;}
-                       case 'B9': {$size = array(0,0,124.72,175.75); break;}
-                       case 'B10': {$size = array(0,0,87.87,124.72); break;}
-                       case 'C0': {$size = array(0,0,2599.37,3676.54); break;}
-                       case 'C1': {$size = array(0,0,1836.85,2599.37); break;}
-                       case 'C2': {$size = array(0,0,1298.27,1836.85); break;}
-                       case 'C3': {$size = array(0,0,918.43,1298.27); break;}
-                       case 'C4': {$size = array(0,0,649.13,918.43); break;}
-                       case 'C5': {$size = array(0,0,459.21,649.13); break;}
-                       case 'C6': {$size = array(0,0,323.15,459.21); break;}
-                       case 'C7': {$size = array(0,0,229.61,323.15); break;}
-                       case 'C8': {$size = array(0,0,161.57,229.61); break;}
-                       case 'C9': {$size = array(0,0,113.39,161.57); break;}
-                       case 'C10': {$size = array(0,0,79.37,113.39); break;}
-                       case 'RA0': {$size = array(0,0,2437.80,3458.27); break;}
-                       case 'RA1': {$size = array(0,0,1729.13,2437.80); break;}
-                       case 'RA2': {$size = array(0,0,1218.90,1729.13); break;}
-                       case 'RA3': {$size = array(0,0,864.57,1218.90); break;}
-                       case 'RA4': {$size = array(0,0,609.45,864.57); break;}
-                       case 'SRA0': {$size = array(0,0,2551.18,3628.35); 
break;}
-                       case 'SRA1': {$size = array(0,0,1814.17,2551.18); 
break;}
-                       case 'SRA2': {$size = array(0,0,1275.59,1814.17); 
break;}
-                       case 'SRA3': {$size = array(0,0,907.09,1275.59); break;}
-                       case 'SRA4': {$size = array(0,0,637.80,907.09); break;}
-                       case 'LETTER': {$size = array(0,0,612.00,792.00); 
break;}
-                       case 'LEGAL': {$size = array(0,0,612.00,1008.00); 
break;}
-                       case 'EXECUTIVE': {$size = array(0,0,521.86,756.00); 
break;}
-                       case 'FOLIO': {$size = array(0,0,612.00,936.00); break;}
-               }
-               switch (strtolower($orientation)){
-                       case 'landscape':
-                               $a=$size[3];
-                               $size[3]=$size[2];
-                               $size[2]=$a;
-                               break;
-               }
-       } else {
-               if (count($paper)>2) {
-                       // then an array was sent it to set the size
-                       $size = $paper;
-               }
-               else { //size in centimeters has been passed
-                       $size[0] = 0;
-                       $size[1] = 0;
-                       $size[2] = ( $paper[0] / 2.54 ) * 72;
-                       $size[3] = ( $paper[1] / 2.54 ) * 72;
-               }
-       }
-//     $this->Cpdf($size);
-       $this->pdf_($size);
-       $this->ez['pageWidth']=$size[2];
-       $this->ez['pageHeight']=$size[3];
-
-       // also set the margins to some reasonable defaults
-       $this->ez['topMargin']=30;
-       $this->ez['bottomMargin']=30;
-       $this->ez['leftMargin']=30;
-       $this->ez['rightMargin']=30;
-
-       // set the current writing position to the top of the first page
-       $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
-       // and get the ID of the page that was created during the instancing 
process.
-       $this->ezPages[1]=$this->getFirstPageId();
-       $this->ezPageCount=1;
-}
-
-// 
------------------------------------------------------------------------------
-// 2002-07-24: Nicola Asuni (address@hidden)
-// Set Margins in centimeters
-function ezSetCmMargins($top,$bottom,$left,$right){
-       $top = ( $top / 2.54 ) * 72;
-       $bottom = ( $bottom / 2.54 ) * 72;
-       $left = ( $left / 2.54 ) * 72;
-       $right = ( $right / 2.54 ) * 72;
-       $this->ezSetMargins($top,$bottom,$left,$right);
-}
-// 
------------------------------------------------------------------------------
-
-
-function ezColumnsStart($options=array()){
-  // start from the current y-position, make the set number of columne
-  if (isset($this->ez['columns']) && $this->ez['columns']==1){
-    // if we are already in a column mode then just return.
-    return;
-  }
-  $def=array('gap'=>10,'num'=>2);
-  foreach($def as $k=>$v){
-    if (!isset($options[$k])){
-      $options[$k]=$v;
-    }
-  }
-  // setup the columns
-  $this->ez['columns']=array('on'=>1,'colNum'=>1);
-
-  // store the current margins
-  $this->ez['columns']['margins']=array(
-     $this->ez['leftMargin']
-    ,$this->ez['rightMargin']
-    ,$this->ez['topMargin']
-    ,$this->ez['bottomMargin']
-  );
-  // and store the settings for the columns
-  $this->ez['columns']['options']=$options;
-  // then reset the margins to suit the new columns
-  // safe enough to assume the first column here, but start from the current 
y-position
-  $this->ez['topMargin']=$this->ez['pageHeight']-$this->y;
-  
$width=($this->ez['pageWidth']-$this->ez['leftMargin']-$this->ez['rightMargin']-($options['num']-1)*$options['gap'])/$options['num'];
-  $this->ez['columns']['width']=$width;
-  
$this->ez['rightMargin']=$this->ez['pageWidth']-$this->ez['leftMargin']-$width;
-
-}
-// 
------------------------------------------------------------------------------
-function ezColumnsStop(){
-  if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
-    $this->ez['columns']['on']=0;
-    $this->ez['leftMargin']=$this->ez['columns']['margins'][0];
-    $this->ez['rightMargin']=$this->ez['columns']['margins'][1];
-    $this->ez['topMargin']=$this->ez['columns']['margins'][2];
-    $this->ez['bottomMargin']=$this->ez['columns']['margins'][3];
-  }
-}
-// 
------------------------------------------------------------------------------
-function ezInsertMode($status=1,$pageNum=1,$pos='before'){
-  // puts the document into insert mode. new pages are inserted until this is 
re-called with status=0
-  // by default pages wil be inserted at the start of the document
-  switch($status){
-    case '1':
-      if (isset($this->ezPages[$pageNum])){
-        $this->ez['insertMode']=1;
-        
$this->ez['insertOptions']=array('id'=>$this->ezPages[$pageNum],'pos'=>$pos);
-      }
-      break;
-    case '0':
-      $this->ez['insertMode']=0;
-      break;
-  }
-}
-// 
------------------------------------------------------------------------------
-
-function ezNewPage(){
-  $pageRequired=1;
-  if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
-    // check if this is just going to a new column
-    // increment the column number
-//echo 'HERE<br>';
-    $this->ez['columns']['colNum']++;
-//echo $this->ez['columns']['colNum'].'<br>';
-    if ($this->ez['columns']['colNum'] <= 
$this->ez['columns']['options']['num']){
-      // then just reset to the top of the next column
-      $pageRequired=0;
-    } else {
-      $this->ez['columns']['colNum']=1;
-      $this->ez['topMargin']=$this->ez['columns']['margins'][2];
-    }
-
-    $width = $this->ez['columns']['width'];
-    
$this->ez['leftMargin']=$this->ez['columns']['margins'][0]+($this->ez['columns']['colNum']-1)*($this->ez['columns']['options']['gap']+$width);
-    
$this->ez['rightMargin']=$this->ez['pageWidth']-$this->ez['leftMargin']-$width;
-  }
-//echo 'left='.$this->ez['leftMargin'].'   
right='.$this->ez['rightMargin'].'<br>';
-
-  if ($pageRequired){
-    // make a new page, setting the writing point back to the top
-    $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
-    // make the new page with a call to the basic class.
-    $this->ezPageCount++;
-    if (isset($this->ez['insertMode']) && $this->ez['insertMode']==1){
-      $id = $this->ezPages[$this->ezPageCount] = 
$this->newPage(1,$this->ez['insertOptions']['id'],$this->ez['insertOptions']['pos']);
-      // then manipulate the insert options so that inserted pages follow each 
other
-      $this->ez['insertOptions']['id']=$id;
-      $this->ez['insertOptions']['pos']='after';
-    } else {
-      $this->ezPages[$this->ezPageCount] = $this->newPage();
-    }
-  } else {
-    $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezSetMargins($top,$bottom,$left,$right){
-  // sets the margins to new values
-  $this->ez['topMargin']=$top;
-  $this->ez['bottomMargin']=$bottom;
-  $this->ez['leftMargin']=$left;
-  $this->ez['rightMargin']=$right;
-  // check to see if this means that the current writing position is outside 
the
-  // writable area
-  if ($this->y > $this->ez['pageHeight']-$top){
-    // then move y down
-    $this->y = $this->ez['pageHeight']-$top;
-  }
-  if ( $this->y < $bottom){
-    // then make a new page
-    $this->ezNewPage();
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezGetCurrentPageNumber(){
-  // return the strict numbering (1,2,3,4..) number of the current page
-  return $this->ezPageCount;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezStartPageNumbers($x,$y,$size,$pos='left',$pattern='{PAGENUM} of 
{TOTALPAGENUM}',$num=''){
-  // put page numbers on the pages from here.
-  // place then on the 'pos' side of the coordinates (x,y).
-  // pos can be 'left' or 'right'
-  // use the given 'pattern' for display, where (PAGENUM} and {TOTALPAGENUM} 
are replaced
-  // as required.
-  // if $num is set, then make the first page this number, the number of total 
pages will
-  // be adjusted to account for this.
-  // Adjust this function so that each time you 'start' page numbers then you 
effectively start a different batch
-  // return the number of the batch, so that they can be stopped in a 
different order if required.
-  if (!$pos || !strlen($pos)){
-    $pos='left';
-  }
-  if (!$pattern || !strlen($pattern)){
-    $pattern='{PAGENUM} of {TOTALPAGENUM}';
-  }
-  if (!isset($this->ez['pageNumbering'])){
-    $this->ez['pageNumbering']=array();
-  }
-  $i = count($this->ez['pageNumbering']);
-  
$this->ez['pageNumbering'][$i][$this->ezPageCount]=array('x'=>$x,'y'=>$y,'pos'=>$pos,'pattern'=>$pattern,'num'=>$num,'size'=>$size);
-  return $i;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezWhatPageNumber($pageNum,$i=0){
-  // given a particular generic page number (ie, document numbered 
sequentially from beginning),
-  // return the page number under a particular page numbering scheme ($i)
-  $num=0;
-  $start=1;
-  $startNum=1;
-  if (!isset($this->ez['pageNumbering']))
-  {
-    $this->addMessage('WARNING: page numbering called for and wasn\'t started 
with ezStartPageNumbers');
-    return 0;
-  }
-  foreach($this->ez['pageNumbering'][$i] as $k=>$v){
-    if ($k<=$pageNum){
-      if (is_array($v)){
-        // start block
-        if (strlen($v['num'])){
-          // a start was specified
-          $start=$v['num'];
-          $startNum=$k;
-          $num=$pageNum-$startNum+$start;
-        }
-      } else {
-        // stop block
-        $num=0;
-      }
-    }
-  }
-  return $num;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezStopPageNumbers($stopTotal=0,$next=0,$i=0){
-  // if stopTotal=1 then the totalling of pages for this number will stop too
-  // if $next=1, then do this page, but not the next, else do not do this page 
either
-  // if $i is set, then stop that particular pagenumbering sequence.
-  if (!isset($this->ez['pageNumbering'])){
-    $this->ez['pageNumbering']=array();
-  }
-  if ($next && isset($this->ez['pageNumbering'][$i][$this->ezPageCount]) && 
is_array($this->ez['pageNumbering'][$i][$this->ezPageCount])){
-    // then this has only just been started, this will over-write the start, 
and nothing will appear
-    // add a special command to the start block, telling it to stop as well
-    if ($stopTotal){
-      $this->ez['pageNumbering'][$i][$this->ezPageCount]['stoptn']=1;
-    } else {
-      $this->ez['pageNumbering'][$i][$this->ezPageCount]['stopn']=1;
-    }
-  } else {
-    if ($stopTotal){
-      $this->ez['pageNumbering'][$i][$this->ezPageCount]='stopt';
-    } else {
-      $this->ez['pageNumbering'][$i][$this->ezPageCount]='stop';
-    }
-    if ($next){
-      $this->ez['pageNumbering'][$i][$this->ezPageCount].='n';
-    }
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezPRVTpageNumberSearch($lbl,&$tmp){
-  foreach($tmp as $i=>$v){
-    if (is_array($v)){
-      if (isset($v[$lbl])){
-        return $i;
-      }
-    } else {
-      if ($v==$lbl){
-        return $i;
-      }
-    }
-  }
-  return 0;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezPRVTaddPageNumbers(){
-  // this will go through the pageNumbering array and add the page numbers are 
required
-  if (isset($this->ez['pageNumbering'])){
-    $totalPages1 = $this->ezPageCount;
-    $tmp1=$this->ez['pageNumbering'];
-    $status=0;
-    foreach($tmp1 as $i=>$tmp){
-      // do each of the page numbering systems
-      // firstly, find the total pages for this one
-      $k = $this->ezPRVTpageNumberSearch('stopt',$tmp);
-      if ($k && $k>0){
-        $totalPages = $k-1;
-      } else {
-        $l = $this->ezPRVTpageNumberSearch('stoptn',$tmp);
-        if ($l && $l>0){
-          $totalPages = $l;
-        } else {
-          $totalPages = $totalPages1;
-        }
-      }
-      foreach ($this->ezPages as $pageNum=>$id){
-        if (isset($tmp[$pageNum])){
-          if (is_array($tmp[$pageNum])){
-            // then this must be starting page numbers
-            $status=1;
-            $info = $tmp[$pageNum];
-            $info['dnum']=$info['num']-$pageNum;
-            // also check for the special case of the numbering stopping and 
starting on the same page
-            if (isset($info['stopn']) || isset($info['stoptn']) ){
-              $status=2;
-            }
-          } else if ($tmp[$pageNum]=='stop' || $tmp[$pageNum]=='stopt'){
-            // then we are stopping page numbers
-            $status=0;
-          } else if ($status==1 && ($tmp[$pageNum]=='stoptn' || 
$tmp[$pageNum]=='stopn')){
-            // then we are stopping page numbers
-            $status=2;
-          }
-        }
-        if ($status){
-          // then add the page numbering to this page
-          if (strlen($info['num'])){
-            $num=$pageNum+$info['dnum'];
-          } else {
-            $num=$pageNum;
-          }
-          $total = $totalPages+$num-$pageNum;
-          $pat = str_replace('{PAGENUM}',$num,$info['pattern']);
-          $pat = str_replace('{TOTALPAGENUM}',$total,$pat);
-          $this->reopenObject($id);
-          switch($info['pos']){
-            case 'right':
-              $this->addText($info['x'],$info['y'],$info['size'],$pat);
-              break;
-            default:
-              $w=$this->getTextWidth($info['size'],$pat);
-              $this->addText($info['x']-$w,$info['y'],$info['size'],$pat);
-              break;
-          }
-          $this->closeObject();
-        }
-        if ($status==2){
-          $status=0;
-        }
-      }
-    }
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezPRVTcleanUp(){
-  $this->ezPRVTaddPageNumbers();
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezStream($options=''){
-  $this->ezPRVTcleanUp();
-  $this->stream($options);
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezOutput($options=0){
-  $this->ezPRVTcleanUp();
-  return $this->output($options);
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezSetY($y){
-  // used to change the vertical position of the writing point.
-  $this->y = $y;
-  if ( $this->y < $this->ez['bottomMargin']){
-    // then make a new page
-    $this->ezNewPage();
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezSetDy($dy,$mod=''){
-  // used to change the vertical position of the writing point.
-  // changes up by a positive increment, so enter a negative number to go
-  // down the page
-  // if $mod is set to 'makeSpace' and a new page is forced, then the pointed 
will be moved
-  // down on the new page, this will allow space to be reserved for graphics 
etc.
-  $this->y += $dy;
-  if ( $this->y < $this->ez['bottomMargin']){
-    // then make a new page
-    $this->ezNewPage();
-    if ($mod=='makeSpace'){
-      $this->y += $dy;
-    }
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function 
ezPrvtTableDrawLines($pos,$gap,$x0,$x1,$y0,$y1,$y2,$col,$inner,$outer,$opt=1){
-  $x0=1000;
-  $x1=0;
-  $this->setStrokeColor($col[0],$col[1],$col[2]);
-  $cnt=0;
-  $n = count($pos);
-  foreach($pos as $x){
-    $cnt++;
-    if ($cnt==1 || $cnt==$n){
-      $this->setLineStyle($outer);
-    } else {
-      $this->setLineStyle($inner);
-    }
-    $this->line($x-$gap/2,$y0,$x-$gap/2,$y2);
-    if ($x>$x1){ $x1=$x; };
-    if ($x<$x0){ $x0=$x; };
-  }
-  $this->setLineStyle($outer);
-  $this->line($x0-$gap/2-$outer/2,$y0,$x1-$gap/2+$outer/2,$y0);
-  // only do the second line if it is different to the first, AND each row 
does not have
-  // a line on it.
-  if ($y0!=$y1 && $opt<2){
-    $this->line($x0-$gap/2,$y1,$x1-$gap/2,$y1);
-  }
-  $this->line($x0-$gap/2-$outer/2,$y2,$x1-$gap/2+$outer/2,$y2);
-}
-
-// 
------------------------------------------------------------------------------
-
-function 
ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$gap,$size,&$y,$optionsAll=array()){
-  // uses ezText to add the text, and returns the height taken by the largest 
heading
-  // this page will move the headings to a new page if they will not fit 
completely on this one
-  // transaction support will be used to implement this
-
-  if (isset($optionsAll['cols'])){
-    $options = $optionsAll['cols'];
-  } else {
-    $options = array();
-  }
-
-  $mx=0;
-  $startPage = $this->ezPageCount;
-  $secondGo=0;
-
-  // $y is the position at which the top of the table should start, so the base
-  // of the first text, is $y-$height-$gap-$decender, but ezText starts by 
dropping $height
-
-  // the return from this function is the total cell height, including gaps, 
and $y is adjusted
-  // to be the postion of the bottom line
-
-  // begin the transaction
-  $this->transaction('start');
-  $ok=0;
-//  $y-=$gap-$decender;
-  $y-=$gap;
-  while ($ok==0){
-    foreach($cols as $colName=>$colHeading){
-      $this->ezSetY($y);
-      if (isset($options[$colName]) && 
isset($options[$colName]['justification'])){
-        $justification = $options[$colName]['justification'];
-      } else {
-        $justification = 'left';
-      }
-      $this->ezText($colHeading,$size,array('aleft'=> 
$pos[$colName],'aright'=>($maxWidth[$colName]+$pos[$colName]),'justification'=>$justification));
-      $dy = $y-$this->y;
-      if ($dy>$mx){
-        $mx=$dy;
-      }
-    }
-    $y = $y - $mx - $gap + $decender;
-//    $y -= $mx-$gap+$decender;
-
-    // now, if this has moved to a new page, then abort the transaction, move 
to a new page, and put it there
-    // do not check on the second time around, to avoid an infinite loop
-    if ($this->ezPageCount != $startPage && $secondGo==0){
-      $this->transaction('rewind');
-      $this->ezNewPage();
-      $y = $this->y - $gap-$decender;
-      $ok=0;
-      $secondGo=1;
-//      $y = $store_y;
-      $mx=0;
-
-    } else {
-      $this->transaction('commit');
-      $ok=1;
-    }
-  }
-
-  return $mx+$gap*2-$decender;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezPrvtGetTextWidth($size,$text){
-  // will calculate the maximum width, taking into account that the text may 
be broken
-  // by line breaks.
-  $mx=0;
-  $lines = explode("\n",$text);
-  foreach ($lines as $line){
-    $w = $this->getTextWidth($size,$line);
-    if ($w>$mx){
-      $mx=$w;
-    }
-  }
-  return $mx;
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezTable(&$data,$cols='',$title='',$options=''){
-  // add a table of information to the pdf document
-  // $data is a two dimensional array
-  // $cols (optional) is an associative array, the keys are the names of the 
columns from $data
-  // to be presented (and in that order), the values are the titles to be 
given to the columns
-  // $title (optional) is the title to be put on the top of the table
-  //
-  // $options is an associative array which can contain:
-  // 'showLines'=> 0,1,2, default is 1 (show outside and top lines only), 2=> 
lines on each row
-  // 'showHeadings' => 0 or 1
-  // 'shaded'=> 0,1,2,3 default is 1 (1->alternate lines are shaded, 0->no 
shading, 2-> both shaded, second uses shadeCol2)
-  // 'shadeCol' => (r,g,b) array, defining the colour of the shading, default 
is (0.8,0.8,0.8)
-  // 'shadeCol2' => (r,g,b) array, defining the colour of the shading of the 
other blocks, default is (0.7,0.7,0.7)
-  // 'fontSize' => 10
-  // 'textCol' => (r,g,b) array, text colour
-  // 'titleFontSize' => 12
-  // 'rowGap' => 2 , the space added at the top and bottom of each row, 
between the text and the lines
-  // 'colGap' => 5 , the space on the left and right sides of each cell
-  // 'lineCol' => (r,g,b) array, defining the colour of the lines, default, 
black.
-  // 'xPos' => 'left','right','center','centre',or coordinate, reference 
coordinate in the x-direction
-  // 'xOrientation' => 'left','right','center','centre', position of the table 
w.r.t 'xPos'
-  // 'width'=> <number> which will specify the width of the table, if it turns 
out to not be this
-  //    wide, then it will stretch the table to fit, if it is wider then each 
cell will be made
-  //    proportionalty smaller, and the content may have to wrap.
-  // 'maxWidth'=> <number> similar to 'width', but will only make table 
smaller than it wants to be
-  // 'options' => 
array(<colname>=>array('justification'=>'left','width'=>100,'link'=>linkDataName),<colname>=>....)
-  //             allow the setting of other paramaters for the individual 
columns
-  // 'minRowSpace'=> the minimum space between the bottom of each row and the 
bottom margin, in which a new row will be started
-  //                  if it is less, then a new page would be started, 
default=-100
-  // 'innerLineThickness'=>1
-  // 'outerLineThickness'=>1
-  // 'splitRows'=>0, 0 or 1, whether or not to allow the rows to be split 
across page boundaries
-  // 'protectRows'=>number, the number of rows to hold with the heading on 
page, ie, if there less than this number of
-  //                rows on the page, then move the whole lot onto the next 
page, default=1
-  //
-  // note that the user will have had to make a font selection already or this 
will not
-  // produce a valid pdf file.
-
-  if (!is_array($data)){
-    return;
-  }
-
-  if (!is_array($cols)){
-    // take the columns from the first row of the data set
-    reset($data);
-    list($k,$v)=each($data);
-    if (!is_array($v)){
-      return;
-    }
-    $cols=array();
-    foreach($v as $k1=>$v1){
-      $cols[$k1]=$k1;
-    }
-  }
-
-  if (!is_array($options)){
-    $options=array();
-  }
-
-  $defaults = array(
-    
'shaded'=>1,'showLines'=>1,'shadeCol'=>array(0.8,0.8,0.8),'shadeCol2'=>array(0.7,0.7,0.7),'fontSize'=>10,'titleFontSize'=>12
-    
,'titleGap'=>5,'lineCol'=>array(0,0,0),'gap'=>5,'xPos'=>'centre','xOrientation'=>'centre'
-    
,'showHeadings'=>1,'textCol'=>array(0,0,0),'width'=>0,'maxWidth'=>0,'cols'=>array(),'minRowSpace'=>-100,'rowGap'=>2,'colGap'=>5
-    
,'innerLineThickness'=>1,'outerLineThickness'=>1,'splitRows'=>0,'protectRows'=>1
-    );
-
-  foreach($defaults as $key=>$value){
-    if (is_array($value)){
-      if (!isset($options[$key]) || !is_array($options[$key])){
-        $options[$key]=$value;
-      }
-    } else {
-      if (!isset($options[$key])){
-        $options[$key]=$value;
-      }
-    }
-  }
-  $options['gap']=2*$options['colGap'];
-
-  $middle = 
($this->ez['pageWidth']-$this->ez['rightMargin'])/2+($this->ez['leftMargin'])/2;
-  // figure out the maximum widths of the text within each column
-  $maxWidth=array();
-  foreach($cols as $colName=>$colHeading){
-    $maxWidth[$colName]=0;
-  }
-  // find the maximum cell widths based on the data
-  foreach($data as $row){
-    foreach($cols as $colName=>$colHeading){
-      $w = 
$this->ezPrvtGetTextWidth($options['fontSize'],(string)$row[$colName])*1.01;
-      if ($w > $maxWidth[$colName]){
-        $maxWidth[$colName]=$w;
-      }
-    }
-  }
-  // and the maximum widths to fit in the headings
-  foreach($cols as $colName=>$colTitle){
-    $w = 
$this->ezPrvtGetTextWidth($options['fontSize'],(string)$colTitle)*1.01;
-    if ($w > $maxWidth[$colName]){
-      $maxWidth[$colName]=$w;
-    }
-  }
-
-  // calculate the start positions of each of the columns
-  $pos=array();
-  $x=0;
-  $t=$x;
-  $adjustmentWidth=0;
-  $setWidth=0;
-  foreach($maxWidth as $colName => $w){
-    $pos[$colName]=$t;
-    // if the column width has been specified then set that here, also total 
the
-    // width avaliable for adjustment
-    if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['width']) && 
$options['cols'][$colName]['width']>0){
-      $t=$t+$options['cols'][$colName]['width'];
-      $maxWidth[$colName] = 
$options['cols'][$colName]['width']-$options['gap'];
-      $setWidth += $options['cols'][$colName]['width'];
-    } else {
-      $t=$t+$w+$options['gap'];
-      $adjustmentWidth += $w;
-      $setWidth += $options['gap'];
-    }
-  }
-  $pos['_end_']=$t;
-
-  // if maxWidth is specified, and the table is too wide, and the width has 
not been set,
-  // then set the width.
-  if ($options['width']==0 && $options['maxWidth'] && 
($t-$x)>$options['maxWidth']){
-    // then need to make this one smaller
-    $options['width']=$options['maxWidth'];
-  }
-
-  if ($options['width'] && $adjustmentWidth>0 && $setWidth<$options['width']){
-    // first find the current widths of the columns involved in this mystery
-    $cols0 = array();
-    $cols1 = array();
-    $xq=0;
-    $presentWidth=0;
-    $last='';
-    foreach($pos as $colName=>$p){
-      if (!isset($options['cols'][$last]) || 
!isset($options['cols'][$last]['width']) || 
$options['cols'][$last]['width']<=0){
-        if (strlen($last)){
-          $cols0[$last]=$p-$xq -$options['gap'];
-          $presentWidth += ($p-$xq - $options['gap']);
-        }
-      } else {
-        $cols1[$last]=$p-$xq;
-      }
-      $last=$colName;
-      $xq=$p;
-    }
-    // $cols0 contains the widths of all the columns which are not set
-    $neededWidth = $options['width']-$setWidth;
-    // if needed width is negative then add it equally to each column, else 
get more tricky
-    if ($presentWidth<$neededWidth){
-      foreach($cols0 as $colName=>$w){
-        $cols0[$colName]+= ($neededWidth-$presentWidth)/count($cols0);
-      }
-    } else {
-
-      $cnt=0;
-      while ($presentWidth>$neededWidth && $cnt<100){
-        $cnt++; // insurance policy
-        // find the widest columns, and the next to widest width
-        $aWidest = array();
-        $nWidest=0;
-        $widest=0;
-        foreach($cols0 as $colName=>$w){
-          if ($w>$widest){
-            $aWidest=array($colName);
-            $nWidest = $widest;
-            $widest=$w;
-          } else if ($w==$widest){
-            $aWidest[]=$colName;
-          }
-        }
-        // then figure out what the width of the widest columns would have to 
be to take up all the slack
-        $newWidestWidth = $widest - 
($presentWidth-$neededWidth)/count($aWidest);
-        if ($newWidestWidth > $nWidest){
-          // then there is space to set them to this
-          foreach($aWidest as $colName){
-            $cols0[$colName] = $newWidestWidth;
-          }
-          $presentWidth=$neededWidth;
-        } else {
-          // there is not space, reduce the size of the widest ones down to 
the next size down, and we
-          // will go round again
-          foreach($aWidest as $colName){
-            $cols0[$colName] = $nWidest;
-          }
-          $presentWidth=$presentWidth-($widest-$nWidest)*count($aWidest);
-        }
-      }
-    }
-    // $cols0 now contains the new widths of the constrained columns.
-    // now need to update the $pos and $maxWidth arrays
-    $xq=0;
-    foreach($pos as $colName=>$p){
-      $pos[$colName]=$xq;
-      if (!isset($options['cols'][$colName]) || 
!isset($options['cols'][$colName]['width']) || 
$options['cols'][$colName]['width']<=0){
-        if (isset($cols0[$colName])){
-          $xq += $cols0[$colName] + $options['gap'];
-          $maxWidth[$colName]=$cols0[$colName];
-        }
-      } else {
-        if (isset($cols1[$colName])){
-          $xq += $cols1[$colName];
-        }
-      }
-    }
-
-    $t=$x+$options['width'];
-    $pos['_end_']=$t;
-  }
-
-  // now adjust the table to the correct location across the page
-  switch ($options['xPos']){
-    case 'left':
-      $xref = $this->ez['leftMargin'];
-      break;
-    case 'right':
-      $xref = $this->ez['pageWidth'] - $this->ez['rightMargin'];
-      break;
-    case 'centre':
-    case 'center':
-      $xref = $middle;
-      break;
-    default:
-      $xref = $options['xPos'];
-      break;
-  }
-  switch ($options['xOrientation']){
-    case 'left':
-      $dx = $xref-$t;
-      break;
-    case 'right':
-      $dx = $xref;
-      break;
-    case 'centre':
-    case 'center':
-      $dx = $xref-$t/2;
-      break;
-  }
-
-
-  foreach($pos as $k=>$v){
-    $pos[$k]=$v+$dx;
-  }
-  $x0=$x+$dx;
-  $x1=$t+$dx;
-
-  $baseLeftMargin = $this->ez['leftMargin'];
-  $basePos = $pos;
-  $baseX0 = $x0;
-  $baseX1 = $x1;
-
-  // ok, just about ready to make me a table
-  
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2]);
-  
$this->setStrokeColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2]);
-
-  $middle = ($x1+$x0)/2;
-
-  // start a transaction which will be used to regress the table, if there are 
not enough rows protected
-  if ($options['protectRows']>0){
-    $this->transaction('start');
-    $movedOnce=0;
-  }
-  $abortTable = 1;
-  while ($abortTable){
-  $abortTable=0;
-
-  $dm = $this->ez['leftMargin']-$baseLeftMargin;
-  foreach($basePos as $k=>$v){
-    $pos[$k]=$v+$dm;
-  }
-  $x0=$baseX0+$dm;
-  $x1=$baseX1+$dm;
-  $middle = ($x1+$x0)/2;
-
-
-  // if the title is set, then do that
-  if (strlen($title)){
-    $w = $this->getTextWidth($options['titleFontSize'],$title);
-    $this->y -= $this->getFontHeight($options['titleFontSize']);
-    if ($this->y < $this->ez['bottomMargin']){
-      $this->ezNewPage();
-        // margins may have changed on the newpage
-        $dm = $this->ez['leftMargin']-$baseLeftMargin;
-        foreach($basePos as $k=>$v){
-          $pos[$k]=$v+$dm;
-        }
-        $x0=$baseX0+$dm;
-        $x1=$baseX1+$dm;
-        $middle = ($x1+$x0)/2;
-      $this->y -= $this->getFontHeight($options['titleFontSize']);
-    }
-    $this->addText($middle-$w/2,$this->y,$options['titleFontSize'],$title);
-    $this->y -= $options['titleGap'];
-  }
-
-        // margins may have changed on the newpage
-        $dm = $this->ez['leftMargin']-$baseLeftMargin;
-        foreach($basePos as $k=>$v){
-          $pos[$k]=$v+$dm;
-        }
-        $x0=$baseX0+$dm;
-        $x1=$baseX1+$dm;
-
-  $y=$this->y; // to simplify the code a bit
-
-  // make the table
-  $height = $this->getFontHeight($options['fontSize']);
-  $decender = $this->getFontDecender($options['fontSize']);
-
-
-
-  $y0=$y+$decender;
-  $dy=0;
-  if ($options['showHeadings']){
-    // this function will move the start of the table to a new page if it does 
not fit on this one
-    $headingHeight = 
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
-    $y0 = $y+$headingHeight;
-    $y1 = $y;
-
-
-    $dm = $this->ez['leftMargin']-$baseLeftMargin;
-    foreach($basePos as $k=>$v){
-      $pos[$k]=$v+$dm;
-    }
-    $x0=$baseX0+$dm;
-    $x1=$baseX1+$dm;
-
-  } else {
-    $y1 = $y0;
-  }
-  $firstLine=1;
-
-
-  // open an object here so that the text can be put in over the shading
-  if ($options['shaded']){
-    $this->saveState();
-    $textObjectId = $this->openObject();
-    $this->closeObject();
-    $this->addObject($textObjectId);
-    $this->reopenObject($textObjectId);
-  }
-
-  $cnt=0;
-  $newPage=0;
-  foreach($data as $row){
-    $cnt++;
-    // the transaction support will be used to prevent rows being split
-    if ($options['splitRows']==0){
-      $pageStart = $this->ezPageCount;
-      if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
-        $columnStart = $this->ez['columns']['colNum'];
-      }
-      $this->transaction('start');
-      $row_orig = $row;
-      $y_orig = $y;
-      $y0_orig = $y0;
-      $y1_orig = $y1;
-    }
-    $ok=0;
-    $secondTurn=0;
-    while(!$abortTable && $ok == 0){
-
-    $mx=0;
-    $newRow=1;
-    while(!$abortTable && ($newPage || $newRow)){
-
-      $y-=$height;
-      if ($newPage || $y<$this->ez['bottomMargin'] || 
(isset($options['minRowSpace']) && 
$y<($this->ez['bottomMargin']+$options['minRowSpace'])) ){
-        // check that enough rows are with the heading
-        if ($options['protectRows']>0 && $movedOnce==0 && 
$cnt<=$options['protectRows']){
-          // then we need to move the whole table onto the next page
-          $movedOnce = 1;
-          $abortTable = 1;
-        }
-
-        $y2=$y-$mx+2*$height+$decender-$newRow*$height;
-        if ($options['showLines']){
-          if (!$options['showHeadings']){
-            $y0=$y1;
-          }
-          
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
-        }
-        if ($options['shaded']){
-          $this->closeObject();
-          $this->restoreState();
-        }
-        $this->ezNewPage();
-        // and the margins may have changed, this is due to the possibility of 
the columns being turned on
-        // as the columns are managed by manipulating the margins
-
-        $dm = $this->ez['leftMargin']-$baseLeftMargin;
-        foreach($basePos as $k=>$v){
-          $pos[$k]=$v+$dm;
-        }
-//        $x0=$x0+$dm;
-//        $x1=$x1+$dm;
-        $x0=$baseX0+$dm;
-        $x1=$baseX1+$dm;
-
-        if ($options['shaded']){
-          $this->saveState();
-          $textObjectId = $this->openObject();
-          $this->closeObject();
-          $this->addObject($textObjectId);
-          $this->reopenObject($textObjectId);
-        }
-        
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2],1);
-        $y = $this->ez['pageHeight']-$this->ez['topMargin'];
-        $y0=$y+$decender;
-        $mx=0;
-        if ($options['showHeadings']){
-          
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
-          $y1=$y;
-        } else {
-          $y1=$y0;
-        }
-        $firstLine=1;
-        $y -= $height;
-      }
-      $newRow=0;
-      // write the actual data
-      // if these cells need to be split over a page, then $newPage will be 
set, and the remaining
-      // text will be placed in $leftOvers
-      $newPage=0;
-      $leftOvers=array();
-
-      foreach($cols as $colName=>$colTitle){
-        $this->ezSetY($y+$height);
-        $colNewPage=0;
-        if (isset($row[$colName])){
-          if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['link']) && 
strlen($options['cols'][$colName]['link'])){
-
-            $lines = explode("\n",$row[$colName]);
-            if (isset($row[$options['cols'][$colName]['link']]) && 
strlen($row[$options['cols'][$colName]['link']])){
-              foreach($lines as $k=>$v){
-                
$lines[$k]='<c:alink:'.$row[$options['cols'][$colName]['link']].'>'.$v.'</c:alink>';
-              }
-            }
-          } else {
-            $lines = explode("\n",$row[$colName]);
-          }
-        } else {
-          $lines = array();
-        }
-        $this->y -= $options['rowGap'];
-        foreach ($lines as $line){
-          $line = $this->ezProcessText($line);
-          $start=1;
-
-          while (strlen($line) || $start){
-            $start=0;
-            if (!$colNewPage){
-              $this->y=$this->y-$height;
-            }
-            if ($this->y < $this->ez['bottomMargin']){
-  //            $this->ezNewPage();
-              $newPage=1;  // whether a new page is required for any of the 
columns
-              $colNewPage=1; // whether a new page is required for this column
-            }
-            if ($colNewPage){
-              if (isset($leftOvers[$colName])){
-                $leftOvers[$colName].="\n".$line;
-              } else {
-                $leftOvers[$colName] = $line;
-              }
-              $line='';
-            } else {
-              if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['justification']) ){
-                $just = $options['cols'][$colName]['justification'];
-              } else {
-                $just='left';
-              }
-
-              
$line=$this->addTextWrap($pos[$colName],$this->y,$maxWidth[$colName],$options['fontSize'],$line,$just);
-            }
-          }
-        }
-
-        $dy=$y+$height-$this->y+$options['rowGap'];
-        if ($dy-$height*$newPage>$mx){
-          $mx=$dy-$height*$newPage;
-        }
-      }
-      // set $row to $leftOvers so that they will be processed onto the new 
page
-      $row = $leftOvers;
-      // now add the shading underneath
-      if ($options['shaded'] && $cnt%2==0){
-        $this->closeObject();
-        
$this->setColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2],1);
-        
$this->filledRectangle($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
-        $this->reopenObject($textObjectId);
-      }
-
-      if ($options['shaded']==2 && $cnt%2==1){
-        $this->closeObject();
-        
$this->setColor($options['shadeCol2'][0],$options['shadeCol2'][1],$options['shadeCol2'][2],1);
-        
$this->filledRectangle($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
-        $this->reopenObject($textObjectId);
-      }
-
-      if ($options['showLines']>1){
-        // then draw a line on the top of each block
-//        $this->closeObject();
-        $this->saveState();
-        
$this->setStrokeColor($options['lineCol'][0],$options['lineCol'][1],$options['lineCol'][2],1);
-//        
$this->line($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
-        if ($firstLine){
-          $this->setLineStyle($options['outerLineThickness']);
-          $firstLine=0;
-        } else {
-          $this->setLineStyle($options['innerLineThickness']);
-        }
-        
$this->line($x0-$options['gap']/2,$y+$decender+$height,$x1-$options['gap']/2,$y+$decender+$height);
-        $this->restoreState();
-//        $this->reopenObject($textObjectId);
-      }
-    } // end of while
-    $y=$y-$mx+$height;
-
-    // checking row split over pages
-    if ($options['splitRows']==0){
-      if ( ( ($this->ezPageCount != $pageStart) || 
(isset($this->ez['columns']) && $this->ez['columns']['on']==1 && $columnStart 
!= $this->ez['columns']['colNum'] ))  && $secondTurn==0){
-        // then we need to go back and try that again !
-        $newPage=1;
-        $secondTurn=1;
-        $this->transaction('rewind');
-        $row = $row_orig;
-        $y = $y_orig;
-        $y0 = $y0_orig;
-        $y1 = $y1_orig;
-        $ok=0;
-
-        $dm = $this->ez['leftMargin']-$baseLeftMargin;
-        foreach($basePos as $k=>$v){
-          $pos[$k]=$v+$dm;
-        }
-        $x0=$baseX0+$dm;
-        $x1=$baseX1+$dm;
-
-      } else {
-        $this->transaction('commit');
-        $ok=1;
-      }
-    } else {
-      $ok=1;  // don't go round the loop if splitting rows is allowed
-    }
-
-    }  // end of while to check for row splitting
-    if ($abortTable){
-      if ($ok==0){
-        $this->transaction('abort');
-      }
-      // only the outer transaction should be operational
-      $this->transaction('rewind');
-      $this->ezNewPage();
-      break;
-    }
-
-  } // end of foreach ($data as $row)
-
-  } // end of while ($abortTable)
-
-  // table has been put on the page, the rows guarded as required, commit.
-  $this->transaction('commit');
-
-  $y2=$y+$decender;
-  if ($options['showLines']){
-    if (!$options['showHeadings']){
-      $y0=$y1;
-    }
-    
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
-  }
-
-  // close the object for drawing the text on top
-  if ($options['shaded']){
-    $this->closeObject();
-    $this->restoreState();
-  }
-
-  $this->y=$y;
-  return $y;
-}
-
-// 
------------------------------------------------------------------------------
-function ezProcessText($text){
-  // this function will intially be used to implement underlining support, but 
could be used for a range of other
-  // purposes
-  $search = array('<u>','<U>','</u>','</U>');
-  $replace = array('<c:uline>','<c:uline>','</c:uline>','</c:uline>');
-  return str_replace($search,$replace,$text);
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezText($text,$size=0,$options=array(),$test=0){
-  // this will add a string of text to the document, starting at the current 
drawing
-  // position.
-  // it will wrap to keep within the margins, including optional offsets from 
the left
-  // and the right, if $size is not specified, then it will be the last one 
used, or
-  // the default value (12 I think).
-  // the text will go to the start of the next line when a return code "\n" is 
found.
-  // possible options are:
-  // 'left'=> number, gap to leave from the left margin
-  // 'right'=> number, gap to leave from the right margin
-  // 'aleft'=> number, absolute left position (overrides 'left')
-  // 'aright'=> number, absolute right position (overrides 'right')
-  // 'justification' => 'left','right','center','centre','full'
-
-  // only set one of the next two items (leading overrides spacing)
-  // 'leading' => number, defines the total height taken by the line, 
independent of the font height.
-  // 'spacing' => a real number, though usually set to one of 1, 1.5, 2 (line 
spacing as used in word processing)
-
-  // if $test is set then this should just check if the text is going to flow 
onto a new page or not, returning true or false
-
-  // apply the filtering which will make the underlining function.
-  $text = $this->ezProcessText($text);
-
-  $newPage=false;
-  $store_y = $this->y;
-
-  if (is_array($options) && isset($options['aleft'])){
-    $left=$options['aleft'];
-  } else {
-    $left = $this->ez['leftMargin'] + ((is_array($options) && 
isset($options['left']))?$options['left']:0);
-  }
-  if (is_array($options) && isset($options['aright'])){
-    $right=$options['aright'];
-  } else {
-    $right = $this->ez['pageWidth'] - $this->ez['rightMargin'] - 
((is_array($options) && isset($options['right']))?$options['right']:0);
-  }
-  if ($size<=0){
-    $size = $this->ez['fontSize'];
-  } else {
-    $this->ez['fontSize']=$size;
-  }
-
-  if (is_array($options) && isset($options['justification'])){
-    $just = $options['justification'];
-  } else {
-    $just = 'left';
-  }
-
-  // modifications to give leading and spacing based on those given by Craig 
Heydenburg 1/1/02
-  if (is_array($options) && isset($options['leading'])) { ## use leading 
instead of spacing
-    $height = $options['leading'];
-       } else if (is_array($options) && isset($options['spacing'])) {
-    $height = $this->getFontHeight($size) * $options['spacing'];
-       } else {
-               $height = $this->getFontHeight($size);
-       }
-
-
-  $lines = explode("\n",$text);
-  foreach ($lines as $line){
-    $start=1;
-    while (strlen($line) || $start){
-      $start=0;
-      $this->y=$this->y-$height;
-      if ($this->y < $this->ez['bottomMargin']){
-        if ($test){
-          $newPage=true;
-        } else {
-          $this->ezNewPage();
-          // and then re-calc the left and right, in case they have changed 
due to columns
-        }
-      }
-      if (is_array($options) && isset($options['aleft'])){
-        $left=$options['aleft'];
-      } else {
-        $left = $this->ez['leftMargin'] + ((is_array($options) && 
isset($options['left']))?$options['left']:0);
-      }
-      if (is_array($options) && isset($options['aright'])){
-        $right=$options['aright'];
-      } else {
-        $right = $this->ez['pageWidth'] - $this->ez['rightMargin'] - 
((is_array($options) && isset($options['right']))?$options['right']:0);
-      }
-      
$line=$this->addTextWrap($left,$this->y,$right-$left,$size,$line,$just,0,$test);
-    }
-  }
-
-  if ($test){
-    $this->y=$store_y;
-    return $newPage;
-  } else {
-    return $this->y;
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function ezImage($image,$pad = 5,$width = 0,$resize = 'full',$just = 
'center',$border = ''){
-       //beta ezimage function
-       if (stristr($image,'://'))//copy to temp file
-       {
-               $fp = @fopen($image,"rb");
-               while(!feof($fp))
-               {
-                       $cont.= fread($fp,1024);
-               }
-               fclose($fp);
-               $image = tempnam ("/tmp", "php-pdf");
-               $fp2 = @fopen($image,"w");
-               fwrite($fp2,$cont);
-               fclose($fp2);
-               $temp = true;
-       }
-
-       if (!(file_exists($image))) return false; //return immediately if image 
file does not exist
-       $imageInfo = getimagesize($image);
-       switch ($imageInfo[2]){
-               case 2:
-                       $type = "jpeg";
-                       break;
-               case 3:
-                       $type = "png";
-                       break;
-               default:
-                       return false; //return if file is not jpg or png
-       }
-       if ($width == 0) $width = $imageInfo[0]; //set width
-       $ratio = $imageInfo[0]/$imageInfo[1];
-
-       //get maximum width of image
-       if (isset($this->ez['columns']) && $this->ez['columns']['on'] == 1)
-       {
-               $bigwidth = $this->ez['columns']['width'] - ($pad * 2);
-       }
-       else
-       {
-               $bigwidth = $this->ez['pageWidth'] - ($pad * 2);
-       }
-       //fix width if larger than maximum or if $resize=full
-       if ($resize == 'full' || $resize == 'width' || $width > $bigwidth)
-       {
-               $width = $bigwidth;
-
-       }
-
-       $height = ($width/$ratio); //set height
-
-       //fix size if runs off page
-       if ($height > ($this->y - $this->ez['bottomMargin'] - ($pad * 2)))
-       {
-               if ($resize != 'full')
-               {
-                       $this->ezNewPage();
-               }
-               else
-               {
-                       $height = ($this->y - $this->ez['bottomMargin'] - ($pad 
* 2)); //shrink height
-                       $width = ($height*$ratio); //fix width
-               }
-       }
-
-       //fix x-offset if image smaller than bigwidth
-       if ($width < $bigwidth)
-       {
-               //center if justification=center
-               if ($just == 'center')
-               {
-                       $offset = ($bigwidth - $width) / 2;
-               }
-               //move to right if justification=right
-               if ($just == 'right')
-               {
-                       $offset = ($bigwidth - $width);
-               }
-               //leave at left if justification=left
-               if ($just == 'left')
-               {
-                       $offset = 0;
-               }
-       }
-
-
-       //call appropriate function
-       if ($type == "jpeg"){
-               $this->addJpegFromFile($image,$this->ez['leftMargin'] + $pad + 
$offset, $this->y + $this->getFontHeight($this->ez['fontSize']) - $pad - 
$height,$width);
-       }
-
-       if ($type == "png"){
-               $this->addPngFromFile($image,$this->ez['leftMargin'] + $pad + 
$offset, $this->y + $this->getFontHeight($this->ez['fontSize']) - $pad - 
$height,$width);
-       }
-       //draw border
-       if ($border != '')
-       {
-       if (!(isset($border['color'])))
-       {
-               $border['color']['red'] = .5;
-               $border['color']['blue'] = .5;
-               $border['color']['green'] = .5;
-       }
-       if (!(isset($border['width']))) $border['width'] = 1;
-       if (!(isset($border['cap']))) $border['cap'] = 'round';
-       if (!(isset($border['join']))) $border['join'] = 'round';
-
-
-       
$this->setStrokeColor($border['color']['red'],$border['color']['green'],$border['color']['blue']);
-       $this->setLineStyle($border['width'],$border['cap'],$border['join']);
-       $this->rectangle($this->ez['leftMargin'] + $pad + $offset, $this->y + 
$this->getFontHeight($this->ez['fontSize']) - $pad - $height,$width,$height);
-
-       }
-       // move y below image
-       $this->y = $this->y - $pad - $height;
-       //remove tempfile for remote images
-       if ($temp == true) unlink($image);
-
-}
-// 
------------------------------------------------------------------------------
-
-// note that templating code is still considered developmental - have not 
really figured
-// out a good way of doing this yet.
-function loadTemplate($templateFile){
-  // this function will load the requested template ($file includes full or 
relative pathname)
-  // the code for the template will be modified to make it name safe, and then 
stored in
-  // an array for later use
-  // The id of the template will be returned for the user to operate on it 
later
-  if (!file_exists($templateFile)){
-    return -1;
-  }
-
-  $code = implode('',file($templateFile));
-  if (!strlen($code)){
-    return;
-  }
-
-  $code = trim($code);
-  if (substr($code,0,5)=='<?php'){
-    $code = substr($code,5);
-  }
-  if (substr($code,-2)=='?>'){
-    $code = substr($code,0,strlen($code)-2);
-  }
-  if (isset($this->ez['numTemplates'])){
-    $newNum = $this->ez['numTemplates'];
-    $this->ez['numTemplates']++;
-  } else {
-    $newNum=0;
-    $this->ez['numTemplates']=1;
-    $this->ez['templates']=array();
-  }
-
-  $this->ez['templates'][$newNum]['code']=$code;
-
-  return $newNum;
-}
-
-// 
------------------------------------------------------------------------------
-
-function execTemplate($id,$data=array(),$options=array()){
-  // execute the given template on the current document.
-  if (!isset($this->ez['templates'][$id])){
-    return;
-  }
-  eval($this->ez['templates'][$id]['code']);
-}
-
-// 
------------------------------------------------------------------------------
-function ilink($info){
-  $this->alink($info,1);
-}
-
-function alink($info,$internal=0){
-  // a callback function to support the formation of clickable links within 
the document
-  $lineFactor=0.05; // the thickness of the line as a proportion of the 
height. also the drop of the line.
-  switch($info['status']){
-    case 'start':
-    case 'sol':
-      // the beginning of the link
-      // this should contain the URl for the link as the 'p' entry, and will 
also contain the value of 'nCallback'
-      if (!isset($this->ez['links'])){
-        $this->ez['links']=array();
-      }
-      $i = $info['nCallback'];
-      $this->ez['links'][$i] = 
array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>$info['decender'],'height'=>$info['height'],'url'=>$info['p']);
-      if ($internal==0){
-        $this->saveState();
-        $this->setColor(0,0,1);
-        $this->setStrokeColor(0,0,1);
-        $thick = $info['height']*$lineFactor;
-        $this->setLineStyle($thick);
-      }
-      break;
-    case 'end':
-    case 'eol':
-      // the end of the link
-      // assume that it is the most recent opening which has closed
-      $i = $info['nCallback'];
-      $start = $this->ez['links'][$i];
-      // add underlining
-      if ($internal){
-        
$this->addInternalLink($start['url'],$start['x'],$start['y']+$start['decender'],$info['x'],$start['y']+$start['decender']+$start['height']);
-      } else {
-        $a = deg2rad((float)$start['angle']-90.0);
-        $drop = $start['height']*$lineFactor*1.5;
-        $dropx = cos($a)*$drop;
-        $dropy = -sin($a)*$drop;
-        
$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-$dropx,$info['y']-$dropy);
-        
$this->addLink($start['url'],$start['x'],$start['y']+$start['decender'],$info['x'],$start['y']+$start['decender']+$start['height']);
-        $this->restoreState();
-      }
-      break;
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-function uline($info){
-  // a callback function to support underlining
-  $lineFactor=0.05; // the thickness of the line as a proportion of the 
height. also the drop of the line.
-  switch($info['status']){
-    case 'start':
-    case 'sol':
-
-      // the beginning of the underline zone
-      if (!isset($this->ez['links'])){
-        $this->ez['links']=array();
-      }
-      $i = $info['nCallback'];
-      $this->ez['links'][$i] = 
array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>$info['decender'],'height'=>$info['height']);
-      $this->saveState();
-      $thick = $info['height']*$lineFactor;
-      $this->setLineStyle($thick);
-      break;
-    case 'end':
-    case 'eol':
-      // the end of the link
-      // assume that it is the most recent opening which has closed
-      $i = $info['nCallback'];
-      $start = $this->ez['links'][$i];
-      // add underlining
-      $a = deg2rad((float)$start['angle']-90.0);
-      $drop = $start['height']*$lineFactor*1.5;
-      $dropx = cos($a)*$drop;
-      $dropy = -sin($a)*$drop;
-      
$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-$dropx,$info['y']-$dropy);
-      $this->restoreState();
-      break;
-  }
-}
-
-// 
------------------------------------------------------------------------------
-
-}
+<?php
+
+//include_once('class.pdf.php');
+//include_once (PHPGW_APP_INC . '/pdf/class.pdf.php');
+
+class pdf extends pdf_ {
+//==============================================================================
+// this class will take the basic interaction facilities of the Cpdf class
+// and make more useful functions so that the user does not have to
+// know all the ins and outs of pdf presentation to produce something pretty.
+//
+// IMPORTANT NOTE
+// there is no warranty, implied or otherwise with this software.
+//
+// version 009 (versioning is linked to class.pdf.php)
+//
+// released under a public domain licence.
+//
+// Wayne Munro, R&OS Ltd, http://www.ros.co.nz/pdf
+//==============================================================================
+
+var $ez=array('fontSize'=>10); // used for storing most of the page 
configuration parameters
+var $y; // this is the current vertical positon on the page of the writing 
point, very important
+var $ezPages=array(); // keep an array of the ids of the pages, making it easy 
to go back and add page numbers etc.
+var $ezPageCount=0;
+
+// 
------------------------------------------------------------------------------
+
+function pdf($paper='a4',$orientation='portrait'){
+       // Assuming that people don't want to specify the paper size using the 
absolute coordinates
+       // allow a couple of options:
+       // orientation can be 'portrait' or 'landscape'
+       // or, to actually set the coordinates, then pass an array in as the 
first parameter.
+       // the defaults are as shown.
+       //
+       // -------------------------
+       // 2002-07-24 - Nicola Asuni (address@hidden):
+       // Added new page formats (45 standard ISO paper formats and 4 american 
common formats)
+       // paper cordinates are calculated in this way: (inches * 72) where 1 
inch = 2.54 cm
+       //
+       // Now you may also pass a 2 values array containing the page width and 
height in centimeters
+       // -------------------------
+
+       if (!is_array($paper)){
+               switch (strtoupper($paper)){
+                       case '4A0': {$size = array(0,0,4767.87,6740.79); break;}
+                       case '2A0': {$size = array(0,0,3370.39,4767.87); break;}
+                       case 'A0': {$size = array(0,0,2383.94,3370.39); break;}
+                       case 'A1': {$size = array(0,0,1683.78,2383.94); break;}
+                       case 'A2': {$size = array(0,0,1190.55,1683.78); break;}
+                       case 'A3': {$size = array(0,0,841.89,1190.55); break;}
+                       case 'A4': default: {$size = array(0,0,595.28,841.89); 
break;}
+                       case 'A5': {$size = array(0,0,419.53,595.28); break;}
+                       case 'A6': {$size = array(0,0,297.64,419.53); break;}
+                       case 'A7': {$size = array(0,0,209.76,297.64); break;}
+                       case 'A8': {$size = array(0,0,147.40,209.76); break;}
+                       case 'A9': {$size = array(0,0,104.88,147.40); break;}
+                       case 'A10': {$size = array(0,0,73.70,104.88); break;}
+                       case 'B0': {$size = array(0,0,2834.65,4008.19); break;}
+                       case 'B1': {$size = array(0,0,2004.09,2834.65); break;}
+                       case 'B2': {$size = array(0,0,1417.32,2004.09); break;}
+                       case 'B3': {$size = array(0,0,1000.63,1417.32); break;}
+                       case 'B4': {$size = array(0,0,708.66,1000.63); break;}
+                       case 'B5': {$size = array(0,0,498.90,708.66); break;}
+                       case 'B6': {$size = array(0,0,354.33,498.90); break;}
+                       case 'B7': {$size = array(0,0,249.45,354.33); break;}
+                       case 'B8': {$size = array(0,0,175.75,249.45); break;}
+                       case 'B9': {$size = array(0,0,124.72,175.75); break;}
+                       case 'B10': {$size = array(0,0,87.87,124.72); break;}
+                       case 'C0': {$size = array(0,0,2599.37,3676.54); break;}
+                       case 'C1': {$size = array(0,0,1836.85,2599.37); break;}
+                       case 'C2': {$size = array(0,0,1298.27,1836.85); break;}
+                       case 'C3': {$size = array(0,0,918.43,1298.27); break;}
+                       case 'C4': {$size = array(0,0,649.13,918.43); break;}
+                       case 'C5': {$size = array(0,0,459.21,649.13); break;}
+                       case 'C6': {$size = array(0,0,323.15,459.21); break;}
+                       case 'C7': {$size = array(0,0,229.61,323.15); break;}
+                       case 'C8': {$size = array(0,0,161.57,229.61); break;}
+                       case 'C9': {$size = array(0,0,113.39,161.57); break;}
+                       case 'C10': {$size = array(0,0,79.37,113.39); break;}
+                       case 'RA0': {$size = array(0,0,2437.80,3458.27); break;}
+                       case 'RA1': {$size = array(0,0,1729.13,2437.80); break;}
+                       case 'RA2': {$size = array(0,0,1218.90,1729.13); break;}
+                       case 'RA3': {$size = array(0,0,864.57,1218.90); break;}
+                       case 'RA4': {$size = array(0,0,609.45,864.57); break;}
+                       case 'SRA0': {$size = array(0,0,2551.18,3628.35); 
break;}
+                       case 'SRA1': {$size = array(0,0,1814.17,2551.18); 
break;}
+                       case 'SRA2': {$size = array(0,0,1275.59,1814.17); 
break;}
+                       case 'SRA3': {$size = array(0,0,907.09,1275.59); break;}
+                       case 'SRA4': {$size = array(0,0,637.80,907.09); break;}
+                       case 'LETTER': {$size = array(0,0,612.00,792.00); 
break;}
+                       case 'LEGAL': {$size = array(0,0,612.00,1008.00); 
break;}
+                       case 'EXECUTIVE': {$size = array(0,0,521.86,756.00); 
break;}
+                       case 'FOLIO': {$size = array(0,0,612.00,936.00); break;}
+               }
+               switch (strtolower($orientation)){
+                       case 'landscape':
+                               $a=$size[3];
+                               $size[3]=$size[2];
+                               $size[2]=$a;
+                               break;
+               }
+       } else {
+               if (count($paper)>2) {
+                       // then an array was sent it to set the size
+                       $size = $paper;
+               }
+               else { //size in centimeters has been passed
+                       $size[0] = 0;
+                       $size[1] = 0;
+                       $size[2] = ( $paper[0] / 2.54 ) * 72;
+                       $size[3] = ( $paper[1] / 2.54 ) * 72;
+               }
+       }
+//     $this->Cpdf($size);
+       $this->pdf_($size);
+       $this->ez['pageWidth']=$size[2];
+       $this->ez['pageHeight']=$size[3];
+
+       // also set the margins to some reasonable defaults
+       $this->ez['topMargin']=30;
+       $this->ez['bottomMargin']=30;
+       $this->ez['leftMargin']=30;
+       $this->ez['rightMargin']=30;
+
+       // set the current writing position to the top of the first page
+       $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
+       // and get the ID of the page that was created during the instancing 
process.
+       $this->ezPages[1]=$this->getFirstPageId();
+       $this->ezPageCount=1;
+}
+
+// 
------------------------------------------------------------------------------
+// 2002-07-24: Nicola Asuni (address@hidden)
+// Set Margins in centimeters
+function ezSetCmMargins($top,$bottom,$left,$right){
+       $top = ( $top / 2.54 ) * 72;
+       $bottom = ( $bottom / 2.54 ) * 72;
+       $left = ( $left / 2.54 ) * 72;
+       $right = ( $right / 2.54 ) * 72;
+       $this->ezSetMargins($top,$bottom,$left,$right);
+}
+// 
------------------------------------------------------------------------------
+
+
+function ezColumnsStart($options=array()){
+  // start from the current y-position, make the set number of columne
+  if (isset($this->ez['columns']) && $this->ez['columns']==1){
+    // if we are already in a column mode then just return.
+    return;
+  }
+  $def=array('gap'=>10,'num'=>2);
+  foreach($def as $k=>$v){
+    if (!isset($options[$k])){
+      $options[$k]=$v;
+    }
+  }
+  // setup the columns
+  $this->ez['columns']=array('on'=>1,'colNum'=>1);
+
+  // store the current margins
+  $this->ez['columns']['margins']=array(
+     $this->ez['leftMargin']
+    ,$this->ez['rightMargin']
+    ,$this->ez['topMargin']
+    ,$this->ez['bottomMargin']
+  );
+  // and store the settings for the columns
+  $this->ez['columns']['options']=$options;
+  // then reset the margins to suit the new columns
+  // safe enough to assume the first column here, but start from the current 
y-position
+  $this->ez['topMargin']=$this->ez['pageHeight']-$this->y;
+  
$width=($this->ez['pageWidth']-$this->ez['leftMargin']-$this->ez['rightMargin']-($options['num']-1)*$options['gap'])/$options['num'];
+  $this->ez['columns']['width']=$width;
+  
$this->ez['rightMargin']=$this->ez['pageWidth']-$this->ez['leftMargin']-$width;
+
+}
+// 
------------------------------------------------------------------------------
+function ezColumnsStop(){
+  if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
+    $this->ez['columns']['on']=0;
+    $this->ez['leftMargin']=$this->ez['columns']['margins'][0];
+    $this->ez['rightMargin']=$this->ez['columns']['margins'][1];
+    $this->ez['topMargin']=$this->ez['columns']['margins'][2];
+    $this->ez['bottomMargin']=$this->ez['columns']['margins'][3];
+  }
+}
+// 
------------------------------------------------------------------------------
+function ezInsertMode($status=1,$pageNum=1,$pos='before'){
+  // puts the document into insert mode. new pages are inserted until this is 
re-called with status=0
+  // by default pages wil be inserted at the start of the document
+  switch($status){
+    case '1':
+      if (isset($this->ezPages[$pageNum])){
+        $this->ez['insertMode']=1;
+        
$this->ez['insertOptions']=array('id'=>$this->ezPages[$pageNum],'pos'=>$pos);
+      }
+      break;
+    case '0':
+      $this->ez['insertMode']=0;
+      break;
+  }
+}
+// 
------------------------------------------------------------------------------
+
+function ezNewPage(){
+  $pageRequired=1;
+  if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
+    // check if this is just going to a new column
+    // increment the column number
+//echo 'HERE<br>';
+    $this->ez['columns']['colNum']++;
+//echo $this->ez['columns']['colNum'].'<br>';
+    if ($this->ez['columns']['colNum'] <= 
$this->ez['columns']['options']['num']){
+      // then just reset to the top of the next column
+      $pageRequired=0;
+    } else {
+      $this->ez['columns']['colNum']=1;
+      $this->ez['topMargin']=$this->ez['columns']['margins'][2];
+    }
+
+    $width = $this->ez['columns']['width'];
+    
$this->ez['leftMargin']=$this->ez['columns']['margins'][0]+($this->ez['columns']['colNum']-1)*($this->ez['columns']['options']['gap']+$width);
+    
$this->ez['rightMargin']=$this->ez['pageWidth']-$this->ez['leftMargin']-$width;
+  }
+//echo 'left='.$this->ez['leftMargin'].'   
right='.$this->ez['rightMargin'].'<br>';
+
+  if ($pageRequired){
+    // make a new page, setting the writing point back to the top
+    $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
+    // make the new page with a call to the basic class.
+    $this->ezPageCount++;
+    if (isset($this->ez['insertMode']) && $this->ez['insertMode']==1){
+      $id = $this->ezPages[$this->ezPageCount] = 
$this->newPage(1,$this->ez['insertOptions']['id'],$this->ez['insertOptions']['pos']);
+      // then manipulate the insert options so that inserted pages follow each 
other
+      $this->ez['insertOptions']['id']=$id;
+      $this->ez['insertOptions']['pos']='after';
+    } else {
+      $this->ezPages[$this->ezPageCount] = $this->newPage();
+    }
+  } else {
+    $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezSetMargins($top,$bottom,$left,$right){
+  // sets the margins to new values
+  $this->ez['topMargin']=$top;
+  $this->ez['bottomMargin']=$bottom;
+  $this->ez['leftMargin']=$left;
+  $this->ez['rightMargin']=$right;
+  // check to see if this means that the current writing position is outside 
the
+  // writable area
+  if ($this->y > $this->ez['pageHeight']-$top){
+    // then move y down
+    $this->y = $this->ez['pageHeight']-$top;
+  }
+  if ( $this->y < $bottom){
+    // then make a new page
+    $this->ezNewPage();
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezGetCurrentPageNumber(){
+  // return the strict numbering (1,2,3,4..) number of the current page
+  return $this->ezPageCount;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezStartPageNumbers($x,$y,$size,$pos='left',$pattern='{PAGENUM} of 
{TOTALPAGENUM}',$num=''){
+  // put page numbers on the pages from here.
+  // place then on the 'pos' side of the coordinates (x,y).
+  // pos can be 'left' or 'right'
+  // use the given 'pattern' for display, where (PAGENUM} and {TOTALPAGENUM} 
are replaced
+  // as required.
+  // if $num is set, then make the first page this number, the number of total 
pages will
+  // be adjusted to account for this.
+  // Adjust this function so that each time you 'start' page numbers then you 
effectively start a different batch
+  // return the number of the batch, so that they can be stopped in a 
different order if required.
+  if (!$pos || !strlen($pos)){
+    $pos='left';
+  }
+  if (!$pattern || !strlen($pattern)){
+    $pattern='{PAGENUM} of {TOTALPAGENUM}';
+  }
+  if (!isset($this->ez['pageNumbering'])){
+    $this->ez['pageNumbering']=array();
+  }
+  $i = count($this->ez['pageNumbering']);
+  
$this->ez['pageNumbering'][$i][$this->ezPageCount]=array('x'=>$x,'y'=>$y,'pos'=>$pos,'pattern'=>$pattern,'num'=>$num,'size'=>$size);
+  return $i;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezWhatPageNumber($pageNum,$i=0){
+  // given a particular generic page number (ie, document numbered 
sequentially from beginning),
+  // return the page number under a particular page numbering scheme ($i)
+  $num=0;
+  $start=1;
+  $startNum=1;
+  if (!isset($this->ez['pageNumbering']))
+  {
+    $this->addMessage('WARNING: page numbering called for and wasn\'t started 
with ezStartPageNumbers');
+    return 0;
+  }
+  foreach($this->ez['pageNumbering'][$i] as $k=>$v){
+    if ($k<=$pageNum){
+      if (is_array($v)){
+        // start block
+        if (strlen($v['num'])){
+          // a start was specified
+          $start=$v['num'];
+          $startNum=$k;
+          $num=$pageNum-$startNum+$start;
+        }
+      } else {
+        // stop block
+        $num=0;
+      }
+    }
+  }
+  return $num;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezStopPageNumbers($stopTotal=0,$next=0,$i=0){
+  // if stopTotal=1 then the totalling of pages for this number will stop too
+  // if $next=1, then do this page, but not the next, else do not do this page 
either
+  // if $i is set, then stop that particular pagenumbering sequence.
+  if (!isset($this->ez['pageNumbering'])){
+    $this->ez['pageNumbering']=array();
+  }
+  if ($next && isset($this->ez['pageNumbering'][$i][$this->ezPageCount]) && 
is_array($this->ez['pageNumbering'][$i][$this->ezPageCount])){
+    // then this has only just been started, this will over-write the start, 
and nothing will appear
+    // add a special command to the start block, telling it to stop as well
+    if ($stopTotal){
+      $this->ez['pageNumbering'][$i][$this->ezPageCount]['stoptn']=1;
+    } else {
+      $this->ez['pageNumbering'][$i][$this->ezPageCount]['stopn']=1;
+    }
+  } else {
+    if ($stopTotal){
+      $this->ez['pageNumbering'][$i][$this->ezPageCount]='stopt';
+    } else {
+      $this->ez['pageNumbering'][$i][$this->ezPageCount]='stop';
+    }
+    if ($next){
+      $this->ez['pageNumbering'][$i][$this->ezPageCount].='n';
+    }
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezPRVTpageNumberSearch($lbl,&$tmp){
+  foreach($tmp as $i=>$v){
+    if (is_array($v)){
+      if (isset($v[$lbl])){
+        return $i;
+      }
+    } else {
+      if ($v==$lbl){
+        return $i;
+      }
+    }
+  }
+  return 0;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezPRVTaddPageNumbers(){
+  // this will go through the pageNumbering array and add the page numbers are 
required
+  if (isset($this->ez['pageNumbering'])){
+    $totalPages1 = $this->ezPageCount;
+    $tmp1=$this->ez['pageNumbering'];
+    $status=0;
+    foreach($tmp1 as $i=>$tmp){
+      // do each of the page numbering systems
+      // firstly, find the total pages for this one
+      $k = $this->ezPRVTpageNumberSearch('stopt',$tmp);
+      if ($k && $k>0){
+        $totalPages = $k-1;
+      } else {
+        $l = $this->ezPRVTpageNumberSearch('stoptn',$tmp);
+        if ($l && $l>0){
+          $totalPages = $l;
+        } else {
+          $totalPages = $totalPages1;
+        }
+      }
+      foreach ($this->ezPages as $pageNum=>$id){
+        if (isset($tmp[$pageNum])){
+          if (is_array($tmp[$pageNum])){
+            // then this must be starting page numbers
+            $status=1;
+            $info = $tmp[$pageNum];
+            $info['dnum']=$info['num']-$pageNum;
+            // also check for the special case of the numbering stopping and 
starting on the same page
+            if (isset($info['stopn']) || isset($info['stoptn']) ){
+              $status=2;
+            }
+          } else if ($tmp[$pageNum]=='stop' || $tmp[$pageNum]=='stopt'){
+            // then we are stopping page numbers
+            $status=0;
+          } else if ($status==1 && ($tmp[$pageNum]=='stoptn' || 
$tmp[$pageNum]=='stopn')){
+            // then we are stopping page numbers
+            $status=2;
+          }
+        }
+        if ($status){
+          // then add the page numbering to this page
+          if (strlen($info['num'])){
+            $num=$pageNum+$info['dnum'];
+          } else {
+            $num=$pageNum;
+          }
+          $total = $totalPages+$num-$pageNum;
+          $pat = str_replace('{PAGENUM}',$num,$info['pattern']);
+          $pat = str_replace('{TOTALPAGENUM}',$total,$pat);
+          $this->reopenObject($id);
+          switch($info['pos']){
+            case 'right':
+              $this->addText($info['x'],$info['y'],$info['size'],$pat);
+              break;
+            default:
+              $w=$this->getTextWidth($info['size'],$pat);
+              $this->addText($info['x']-$w,$info['y'],$info['size'],$pat);
+              break;
+          }
+          $this->closeObject();
+        }
+        if ($status==2){
+          $status=0;
+        }
+      }
+    }
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezPRVTcleanUp(){
+  $this->ezPRVTaddPageNumbers();
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezStream($options=''){
+  $this->ezPRVTcleanUp();
+  $this->stream($options);
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezOutput($options=0){
+  $this->ezPRVTcleanUp();
+  return $this->output($options);
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezSetY($y){
+  // used to change the vertical position of the writing point.
+  $this->y = $y;
+  if ( $this->y < $this->ez['bottomMargin']){
+    // then make a new page
+    $this->ezNewPage();
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezSetDy($dy,$mod=''){
+  // used to change the vertical position of the writing point.
+  // changes up by a positive increment, so enter a negative number to go
+  // down the page
+  // if $mod is set to 'makeSpace' and a new page is forced, then the pointed 
will be moved
+  // down on the new page, this will allow space to be reserved for graphics 
etc.
+  $this->y += $dy;
+  if ( $this->y < $this->ez['bottomMargin']){
+    // then make a new page
+    $this->ezNewPage();
+    if ($mod=='makeSpace'){
+      $this->y += $dy;
+    }
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function 
ezPrvtTableDrawLines($pos,$gap,$x0,$x1,$y0,$y1,$y2,$col,$inner,$outer,$opt=1){
+  $x0=1000;
+  $x1=0;
+  $this->setStrokeColor($col[0],$col[1],$col[2]);
+  $cnt=0;
+  $n = count($pos);
+  foreach($pos as $x){
+    $cnt++;
+    if ($cnt==1 || $cnt==$n){
+      $this->setLineStyle($outer);
+    } else {
+      $this->setLineStyle($inner);
+    }
+    $this->line($x-$gap/2,$y0,$x-$gap/2,$y2);
+    if ($x>$x1){ $x1=$x; };
+    if ($x<$x0){ $x0=$x; };
+  }
+  $this->setLineStyle($outer);
+  $this->line($x0-$gap/2-$outer/2,$y0,$x1-$gap/2+$outer/2,$y0);
+  // only do the second line if it is different to the first, AND each row 
does not have
+  // a line on it.
+  if ($y0!=$y1 && $opt<2){
+    $this->line($x0-$gap/2,$y1,$x1-$gap/2,$y1);
+  }
+  $this->line($x0-$gap/2-$outer/2,$y2,$x1-$gap/2+$outer/2,$y2);
+}
+
+// 
------------------------------------------------------------------------------
+
+function 
ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$gap,$size,&$y,$optionsAll=array()){
+  // uses ezText to add the text, and returns the height taken by the largest 
heading
+  // this page will move the headings to a new page if they will not fit 
completely on this one
+  // transaction support will be used to implement this
+
+  if (isset($optionsAll['cols'])){
+    $options = $optionsAll['cols'];
+  } else {
+    $options = array();
+  }
+
+  $mx=0;
+  $startPage = $this->ezPageCount;
+  $secondGo=0;
+
+  // $y is the position at which the top of the table should start, so the base
+  // of the first text, is $y-$height-$gap-$decender, but ezText starts by 
dropping $height
+
+  // the return from this function is the total cell height, including gaps, 
and $y is adjusted
+  // to be the postion of the bottom line
+
+  // begin the transaction
+  $this->transaction('start');
+  $ok=0;
+//  $y-=$gap-$decender;
+  $y-=$gap;
+  while ($ok==0){
+    foreach($cols as $colName=>$colHeading){
+      $this->ezSetY($y);
+      if (isset($options[$colName]) && 
isset($options[$colName]['justification'])){
+        $justification = $options[$colName]['justification'];
+      } else {
+        $justification = 'left';
+      }
+      $this->ezText($colHeading,$size,array('aleft'=> 
$pos[$colName],'aright'=>($maxWidth[$colName]+$pos[$colName]),'justification'=>$justification));
+      $dy = $y-$this->y;
+      if ($dy>$mx){
+        $mx=$dy;
+      }
+    }
+    $y = $y - $mx - $gap + $decender;
+//    $y -= $mx-$gap+$decender;
+
+    // now, if this has moved to a new page, then abort the transaction, move 
to a new page, and put it there
+    // do not check on the second time around, to avoid an infinite loop
+    if ($this->ezPageCount != $startPage && $secondGo==0){
+      $this->transaction('rewind');
+      $this->ezNewPage();
+      $y = $this->y - $gap-$decender;
+      $ok=0;
+      $secondGo=1;
+//      $y = $store_y;
+      $mx=0;
+
+    } else {
+      $this->transaction('commit');
+      $ok=1;
+    }
+  }
+
+  return $mx+$gap*2-$decender;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezPrvtGetTextWidth($size,$text){
+  // will calculate the maximum width, taking into account that the text may 
be broken
+  // by line breaks.
+  $mx=0;
+  $lines = explode("\n",$text);
+  foreach ($lines as $line){
+    $w = $this->getTextWidth($size,$line);
+    if ($w>$mx){
+      $mx=$w;
+    }
+  }
+  return $mx;
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezTable(&$data,$cols='',$title='',$options=''){
+  // add a table of information to the pdf document
+  // $data is a two dimensional array
+  // $cols (optional) is an associative array, the keys are the names of the 
columns from $data
+  // to be presented (and in that order), the values are the titles to be 
given to the columns
+  // $title (optional) is the title to be put on the top of the table
+  //
+  // $options is an associative array which can contain:
+  // 'showLines'=> 0,1,2, default is 1 (show outside and top lines only), 2=> 
lines on each row
+  // 'showHeadings' => 0 or 1
+  // 'shaded'=> 0,1,2,3 default is 1 (1->alternate lines are shaded, 0->no 
shading, 2-> both shaded, second uses shadeCol2)
+  // 'shadeCol' => (r,g,b) array, defining the colour of the shading, default 
is (0.8,0.8,0.8)
+  // 'shadeCol2' => (r,g,b) array, defining the colour of the shading of the 
other blocks, default is (0.7,0.7,0.7)
+  // 'fontSize' => 10
+  // 'textCol' => (r,g,b) array, text colour
+  // 'titleFontSize' => 12
+  // 'rowGap' => 2 , the space added at the top and bottom of each row, 
between the text and the lines
+  // 'colGap' => 5 , the space on the left and right sides of each cell
+  // 'lineCol' => (r,g,b) array, defining the colour of the lines, default, 
black.
+  // 'xPos' => 'left','right','center','centre',or coordinate, reference 
coordinate in the x-direction
+  // 'xOrientation' => 'left','right','center','centre', position of the table 
w.r.t 'xPos'
+  // 'width'=> <number> which will specify the width of the table, if it turns 
out to not be this
+  //    wide, then it will stretch the table to fit, if it is wider then each 
cell will be made
+  //    proportionalty smaller, and the content may have to wrap.
+  // 'maxWidth'=> <number> similar to 'width', but will only make table 
smaller than it wants to be
+  // 'options' => 
array(<colname>=>array('justification'=>'left','width'=>100,'link'=>linkDataName),<colname>=>....)
+  //             allow the setting of other paramaters for the individual 
columns
+  // 'minRowSpace'=> the minimum space between the bottom of each row and the 
bottom margin, in which a new row will be started
+  //                  if it is less, then a new page would be started, 
default=-100
+  // 'innerLineThickness'=>1
+  // 'outerLineThickness'=>1
+  // 'splitRows'=>0, 0 or 1, whether or not to allow the rows to be split 
across page boundaries
+  // 'protectRows'=>number, the number of rows to hold with the heading on 
page, ie, if there less than this number of
+  //                rows on the page, then move the whole lot onto the next 
page, default=1
+  //
+  // note that the user will have had to make a font selection already or this 
will not
+  // produce a valid pdf file.
+
+  if (!is_array($data)){
+    return;
+  }
+
+  if (!is_array($cols)){
+    // take the columns from the first row of the data set
+    reset($data);
+    list($k,$v)=each($data);
+    if (!is_array($v)){
+      return;
+    }
+    $cols=array();
+    foreach($v as $k1=>$v1){
+      $cols[$k1]=$k1;
+    }
+  }
+
+  if (!is_array($options)){
+    $options=array();
+  }
+
+  $defaults = array(
+    
'shaded'=>1,'showLines'=>1,'shadeCol'=>array(0.8,0.8,0.8),'shadeCol2'=>array(0.7,0.7,0.7),'fontSize'=>10,'titleFontSize'=>12
+    
,'titleGap'=>5,'lineCol'=>array(0,0,0),'gap'=>5,'xPos'=>'centre','xOrientation'=>'centre'
+    
,'showHeadings'=>1,'textCol'=>array(0,0,0),'width'=>0,'maxWidth'=>0,'cols'=>array(),'minRowSpace'=>-100,'rowGap'=>2,'colGap'=>5
+    
,'innerLineThickness'=>1,'outerLineThickness'=>1,'splitRows'=>0,'protectRows'=>1
+    );
+
+  foreach($defaults as $key=>$value){
+    if (is_array($value)){
+      if (!isset($options[$key]) || !is_array($options[$key])){
+        $options[$key]=$value;
+      }
+    } else {
+      if (!isset($options[$key])){
+        $options[$key]=$value;
+      }
+    }
+  }
+  $options['gap']=2*$options['colGap'];
+
+  $middle = 
($this->ez['pageWidth']-$this->ez['rightMargin'])/2+($this->ez['leftMargin'])/2;
+  // figure out the maximum widths of the text within each column
+  $maxWidth=array();
+  foreach($cols as $colName=>$colHeading){
+    $maxWidth[$colName]=0;
+  }
+  // find the maximum cell widths based on the data
+  foreach($data as $row){
+    foreach($cols as $colName=>$colHeading){
+      $w = 
$this->ezPrvtGetTextWidth($options['fontSize'],(string)$row[$colName])*1.01;
+      if ($w > $maxWidth[$colName]){
+        $maxWidth[$colName]=$w;
+      }
+    }
+  }
+  // and the maximum widths to fit in the headings
+  foreach($cols as $colName=>$colTitle){
+    $w = 
$this->ezPrvtGetTextWidth($options['fontSize'],(string)$colTitle)*1.01;
+    if ($w > $maxWidth[$colName]){
+      $maxWidth[$colName]=$w;
+    }
+  }
+
+  // calculate the start positions of each of the columns
+  $pos=array();
+  $x=0;
+  $t=$x;
+  $adjustmentWidth=0;
+  $setWidth=0;
+  foreach($maxWidth as $colName => $w){
+    $pos[$colName]=$t;
+    // if the column width has been specified then set that here, also total 
the
+    // width avaliable for adjustment
+    if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['width']) && 
$options['cols'][$colName]['width']>0){
+      $t=$t+$options['cols'][$colName]['width'];
+      $maxWidth[$colName] = 
$options['cols'][$colName]['width']-$options['gap'];
+      $setWidth += $options['cols'][$colName]['width'];
+    } else {
+      $t=$t+$w+$options['gap'];
+      $adjustmentWidth += $w;
+      $setWidth += $options['gap'];
+    }
+  }
+  $pos['_end_']=$t;
+
+  // if maxWidth is specified, and the table is too wide, and the width has 
not been set,
+  // then set the width.
+  if ($options['width']==0 && $options['maxWidth'] && 
($t-$x)>$options['maxWidth']){
+    // then need to make this one smaller
+    $options['width']=$options['maxWidth'];
+  }
+
+  if ($options['width'] && $adjustmentWidth>0 && $setWidth<$options['width']){
+    // first find the current widths of the columns involved in this mystery
+    $cols0 = array();
+    $cols1 = array();
+    $xq=0;
+    $presentWidth=0;
+    $last='';
+    foreach($pos as $colName=>$p){
+      if (!isset($options['cols'][$last]) || 
!isset($options['cols'][$last]['width']) || 
$options['cols'][$last]['width']<=0){
+        if (strlen($last)){
+          $cols0[$last]=$p-$xq -$options['gap'];
+          $presentWidth += ($p-$xq - $options['gap']);
+        }
+      } else {
+        $cols1[$last]=$p-$xq;
+      }
+      $last=$colName;
+      $xq=$p;
+    }
+    // $cols0 contains the widths of all the columns which are not set
+    $neededWidth = $options['width']-$setWidth;
+    // if needed width is negative then add it equally to each column, else 
get more tricky
+    if ($presentWidth<$neededWidth){
+      foreach($cols0 as $colName=>$w){
+        $cols0[$colName]+= ($neededWidth-$presentWidth)/count($cols0);
+      }
+    } else {
+
+      $cnt=0;
+      while ($presentWidth>$neededWidth && $cnt<100){
+        $cnt++; // insurance policy
+        // find the widest columns, and the next to widest width
+        $aWidest = array();
+        $nWidest=0;
+        $widest=0;
+        foreach($cols0 as $colName=>$w){
+          if ($w>$widest){
+            $aWidest=array($colName);
+            $nWidest = $widest;
+            $widest=$w;
+          } else if ($w==$widest){
+            $aWidest[]=$colName;
+          }
+        }
+        // then figure out what the width of the widest columns would have to 
be to take up all the slack
+        $newWidestWidth = $widest - 
($presentWidth-$neededWidth)/count($aWidest);
+        if ($newWidestWidth > $nWidest){
+          // then there is space to set them to this
+          foreach($aWidest as $colName){
+            $cols0[$colName] = $newWidestWidth;
+          }
+          $presentWidth=$neededWidth;
+        } else {
+          // there is not space, reduce the size of the widest ones down to 
the next size down, and we
+          // will go round again
+          foreach($aWidest as $colName){
+            $cols0[$colName] = $nWidest;
+          }
+          $presentWidth=$presentWidth-($widest-$nWidest)*count($aWidest);
+        }
+      }
+    }
+    // $cols0 now contains the new widths of the constrained columns.
+    // now need to update the $pos and $maxWidth arrays
+    $xq=0;
+    foreach($pos as $colName=>$p){
+      $pos[$colName]=$xq;
+      if (!isset($options['cols'][$colName]) || 
!isset($options['cols'][$colName]['width']) || 
$options['cols'][$colName]['width']<=0){
+        if (isset($cols0[$colName])){
+          $xq += $cols0[$colName] + $options['gap'];
+          $maxWidth[$colName]=$cols0[$colName];
+        }
+      } else {
+        if (isset($cols1[$colName])){
+          $xq += $cols1[$colName];
+        }
+      }
+    }
+
+    $t=$x+$options['width'];
+    $pos['_end_']=$t;
+  }
+
+  // now adjust the table to the correct location across the page
+  switch ($options['xPos']){
+    case 'left':
+      $xref = $this->ez['leftMargin'];
+      break;
+    case 'right':
+      $xref = $this->ez['pageWidth'] - $this->ez['rightMargin'];
+      break;
+    case 'centre':
+    case 'center':
+      $xref = $middle;
+      break;
+    default:
+      $xref = $options['xPos'];
+      break;
+  }
+  switch ($options['xOrientation']){
+    case 'left':
+      $dx = $xref-$t;
+      break;
+    case 'right':
+      $dx = $xref;
+      break;
+    case 'centre':
+    case 'center':
+      $dx = $xref-$t/2;
+      break;
+  }
+
+
+  foreach($pos as $k=>$v){
+    $pos[$k]=$v+$dx;
+  }
+  $x0=$x+$dx;
+  $x1=$t+$dx;
+
+  $baseLeftMargin = $this->ez['leftMargin'];
+  $basePos = $pos;
+  $baseX0 = $x0;
+  $baseX1 = $x1;
+
+  // ok, just about ready to make me a table
+  
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2]);
+  
$this->setStrokeColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2]);
+
+  $middle = ($x1+$x0)/2;
+
+  // start a transaction which will be used to regress the table, if there are 
not enough rows protected
+  if ($options['protectRows']>0){
+    $this->transaction('start');
+    $movedOnce=0;
+  }
+  $abortTable = 1;
+  while ($abortTable){
+  $abortTable=0;
+
+  $dm = $this->ez['leftMargin']-$baseLeftMargin;
+  foreach($basePos as $k=>$v){
+    $pos[$k]=$v+$dm;
+  }
+  $x0=$baseX0+$dm;
+  $x1=$baseX1+$dm;
+  $middle = ($x1+$x0)/2;
+
+
+  // if the title is set, then do that
+  if (strlen($title)){
+    $w = $this->getTextWidth($options['titleFontSize'],$title);
+    $this->y -= $this->getFontHeight($options['titleFontSize']);
+    if ($this->y < $this->ez['bottomMargin']){
+      $this->ezNewPage();
+        // margins may have changed on the newpage
+        $dm = $this->ez['leftMargin']-$baseLeftMargin;
+        foreach($basePos as $k=>$v){
+          $pos[$k]=$v+$dm;
+        }
+        $x0=$baseX0+$dm;
+        $x1=$baseX1+$dm;
+        $middle = ($x1+$x0)/2;
+      $this->y -= $this->getFontHeight($options['titleFontSize']);
+    }
+    $this->addText($middle-$w/2,$this->y,$options['titleFontSize'],$title);
+    $this->y -= $options['titleGap'];
+  }
+
+        // margins may have changed on the newpage
+        $dm = $this->ez['leftMargin']-$baseLeftMargin;
+        foreach($basePos as $k=>$v){
+          $pos[$k]=$v+$dm;
+        }
+        $x0=$baseX0+$dm;
+        $x1=$baseX1+$dm;
+
+  $y=$this->y; // to simplify the code a bit
+
+  // make the table
+  $height = $this->getFontHeight($options['fontSize']);
+  $decender = $this->getFontDecender($options['fontSize']);
+
+
+
+  $y0=$y+$decender;
+  $dy=0;
+  if ($options['showHeadings']){
+    // this function will move the start of the table to a new page if it does 
not fit on this one
+    $headingHeight = 
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
+    $y0 = $y+$headingHeight;
+    $y1 = $y;
+
+
+    $dm = $this->ez['leftMargin']-$baseLeftMargin;
+    foreach($basePos as $k=>$v){
+      $pos[$k]=$v+$dm;
+    }
+    $x0=$baseX0+$dm;
+    $x1=$baseX1+$dm;
+
+  } else {
+    $y1 = $y0;
+  }
+  $firstLine=1;
+
+
+  // open an object here so that the text can be put in over the shading
+  if ($options['shaded']){
+    $this->saveState();
+    $textObjectId = $this->openObject();
+    $this->closeObject();
+    $this->addObject($textObjectId);
+    $this->reopenObject($textObjectId);
+  }
+
+  $cnt=0;
+  $newPage=0;
+  foreach($data as $row){
+    $cnt++;
+    // the transaction support will be used to prevent rows being split
+    if ($options['splitRows']==0){
+      $pageStart = $this->ezPageCount;
+      if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){
+        $columnStart = $this->ez['columns']['colNum'];
+      }
+      $this->transaction('start');
+      $row_orig = $row;
+      $y_orig = $y;
+      $y0_orig = $y0;
+      $y1_orig = $y1;
+    }
+    $ok=0;
+    $secondTurn=0;
+    while(!$abortTable && $ok == 0){
+
+    $mx=0;
+    $newRow=1;
+    while(!$abortTable && ($newPage || $newRow)){
+
+      $y-=$height;
+      if ($newPage || $y<$this->ez['bottomMargin'] || 
(isset($options['minRowSpace']) && 
$y<($this->ez['bottomMargin']+$options['minRowSpace'])) ){
+        // check that enough rows are with the heading
+        if ($options['protectRows']>0 && $movedOnce==0 && 
$cnt<=$options['protectRows']){
+          // then we need to move the whole table onto the next page
+          $movedOnce = 1;
+          $abortTable = 1;
+        }
+
+        $y2=$y-$mx+2*$height+$decender-$newRow*$height;
+        if ($options['showLines']){
+          if (!$options['showHeadings']){
+            $y0=$y1;
+          }
+          
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
+        }
+        if ($options['shaded']){
+          $this->closeObject();
+          $this->restoreState();
+        }
+        $this->ezNewPage();
+        // and the margins may have changed, this is due to the possibility of 
the columns being turned on
+        // as the columns are managed by manipulating the margins
+
+        $dm = $this->ez['leftMargin']-$baseLeftMargin;
+        foreach($basePos as $k=>$v){
+          $pos[$k]=$v+$dm;
+        }
+//        $x0=$x0+$dm;
+//        $x1=$x1+$dm;
+        $x0=$baseX0+$dm;
+        $x1=$baseX1+$dm;
+
+        if ($options['shaded']){
+          $this->saveState();
+          $textObjectId = $this->openObject();
+          $this->closeObject();
+          $this->addObject($textObjectId);
+          $this->reopenObject($textObjectId);
+        }
+        
$this->setColor($options['textCol'][0],$options['textCol'][1],$options['textCol'][2],1);
+        $y = $this->ez['pageHeight']-$this->ez['topMargin'];
+        $y0=$y+$decender;
+        $mx=0;
+        if ($options['showHeadings']){
+          
$this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options);
+          $y1=$y;
+        } else {
+          $y1=$y0;
+        }
+        $firstLine=1;
+        $y -= $height;
+      }
+      $newRow=0;
+      // write the actual data
+      // if these cells need to be split over a page, then $newPage will be 
set, and the remaining
+      // text will be placed in $leftOvers
+      $newPage=0;
+      $leftOvers=array();
+
+      foreach($cols as $colName=>$colTitle){
+        $this->ezSetY($y+$height);
+        $colNewPage=0;
+        if (isset($row[$colName])){
+          if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['link']) && 
strlen($options['cols'][$colName]['link'])){
+
+            $lines = explode("\n",$row[$colName]);
+            if (isset($row[$options['cols'][$colName]['link']]) && 
strlen($row[$options['cols'][$colName]['link']])){
+              foreach($lines as $k=>$v){
+                
$lines[$k]='<c:alink:'.$row[$options['cols'][$colName]['link']].'>'.$v.'</c:alink>';
+              }
+            }
+          } else {
+            $lines = explode("\n",$row[$colName]);
+          }
+        } else {
+          $lines = array();
+        }
+        $this->y -= $options['rowGap'];
+        foreach ($lines as $line){
+          $line = $this->ezProcessText($line);
+          $start=1;
+
+          while (strlen($line) || $start){
+            $start=0;
+            if (!$colNewPage){
+              $this->y=$this->y-$height;
+            }
+            if ($this->y < $this->ez['bottomMargin']){
+  //            $this->ezNewPage();
+              $newPage=1;  // whether a new page is required for any of the 
columns
+              $colNewPage=1; // whether a new page is required for this column
+            }
+            if ($colNewPage){
+              if (isset($leftOvers[$colName])){
+                $leftOvers[$colName].="\n".$line;
+              } else {
+                $leftOvers[$colName] = $line;
+              }
+              $line='';
+            } else {
+              if (isset($options['cols'][$colName]) && 
isset($options['cols'][$colName]['justification']) ){
+                $just = $options['cols'][$colName]['justification'];
+              } else {
+                $just='left';
+              }
+
+              
$line=$this->addTextWrap($pos[$colName],$this->y,$maxWidth[$colName],$options['fontSize'],$line,$just);
+            }
+          }
+        }
+
+        $dy=$y+$height-$this->y+$options['rowGap'];
+        if ($dy-$height*$newPage>$mx){
+          $mx=$dy-$height*$newPage;
+        }
+      }
+      // set $row to $leftOvers so that they will be processed onto the new 
page
+      $row = $leftOvers;
+      // now add the shading underneath
+      if ($options['shaded'] && $cnt%2==0){
+        $this->closeObject();
+        
$this->setColor($options['shadeCol'][0],$options['shadeCol'][1],$options['shadeCol'][2],1);
+        
$this->filledRectangle($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
+        $this->reopenObject($textObjectId);
+      }
+
+      if ($options['shaded']==2 && $cnt%2==1){
+        $this->closeObject();
+        
$this->setColor($options['shadeCol2'][0],$options['shadeCol2'][1],$options['shadeCol2'][2],1);
+        
$this->filledRectangle($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
+        $this->reopenObject($textObjectId);
+      }
+
+      if ($options['showLines']>1){
+        // then draw a line on the top of each block
+//        $this->closeObject();
+        $this->saveState();
+        
$this->setStrokeColor($options['lineCol'][0],$options['lineCol'][1],$options['lineCol'][2],1);
+//        
$this->line($x0-$options['gap']/2,$y+$decender+$height-$mx,$x1-$x0,$mx);
+        if ($firstLine){
+          $this->setLineStyle($options['outerLineThickness']);
+          $firstLine=0;
+        } else {
+          $this->setLineStyle($options['innerLineThickness']);
+        }
+        
$this->line($x0-$options['gap']/2,$y+$decender+$height,$x1-$options['gap']/2,$y+$decender+$height);
+        $this->restoreState();
+//        $this->reopenObject($textObjectId);
+      }
+    } // end of while
+    $y=$y-$mx+$height;
+
+    // checking row split over pages
+    if ($options['splitRows']==0){
+      if ( ( ($this->ezPageCount != $pageStart) || 
(isset($this->ez['columns']) && $this->ez['columns']['on']==1 && $columnStart 
!= $this->ez['columns']['colNum'] ))  && $secondTurn==0){
+        // then we need to go back and try that again !
+        $newPage=1;
+        $secondTurn=1;
+        $this->transaction('rewind');
+        $row = $row_orig;
+        $y = $y_orig;
+        $y0 = $y0_orig;
+        $y1 = $y1_orig;
+        $ok=0;
+
+        $dm = $this->ez['leftMargin']-$baseLeftMargin;
+        foreach($basePos as $k=>$v){
+          $pos[$k]=$v+$dm;
+        }
+        $x0=$baseX0+$dm;
+        $x1=$baseX1+$dm;
+
+      } else {
+        $this->transaction('commit');
+        $ok=1;
+      }
+    } else {
+      $ok=1;  // don't go round the loop if splitting rows is allowed
+    }
+
+    }  // end of while to check for row splitting
+    if ($abortTable){
+      if ($ok==0){
+        $this->transaction('abort');
+      }
+      // only the outer transaction should be operational
+      $this->transaction('rewind');
+      $this->ezNewPage();
+      break;
+    }
+
+  } // end of foreach ($data as $row)
+
+  } // end of while ($abortTable)
+
+  // table has been put on the page, the rows guarded as required, commit.
+  $this->transaction('commit');
+
+  $y2=$y+$decender;
+  if ($options['showLines']){
+    if (!$options['showHeadings']){
+      $y0=$y1;
+    }
+    
$this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']);
+  }
+
+  // close the object for drawing the text on top
+  if ($options['shaded']){
+    $this->closeObject();
+    $this->restoreState();
+  }
+
+  $this->y=$y;
+  return $y;
+}
+
+// 
------------------------------------------------------------------------------
+function ezProcessText($text){
+  // this function will intially be used to implement underlining support, but 
could be used for a range of other
+  // purposes
+  $search = array('<u>','<U>','</u>','</U>');
+  $replace = array('<c:uline>','<c:uline>','</c:uline>','</c:uline>');
+  return str_replace($search,$replace,$text);
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezText($text,$size=0,$options=array(),$test=0){
+  // this will add a string of text to the document, starting at the current 
drawing
+  // position.
+  // it will wrap to keep within the margins, including optional offsets from 
the left
+  // and the right, if $size is not specified, then it will be the last one 
used, or
+  // the default value (12 I think).
+  // the text will go to the start of the next line when a return code "\n" is 
found.
+  // possible options are:
+  // 'left'=> number, gap to leave from the left margin
+  // 'right'=> number, gap to leave from the right margin
+  // 'aleft'=> number, absolute left position (overrides 'left')
+  // 'aright'=> number, absolute right position (overrides 'right')
+  // 'justification' => 'left','right','center','centre','full'
+
+  // only set one of the next two items (leading overrides spacing)
+  // 'leading' => number, defines the total height taken by the line, 
independent of the font height.
+  // 'spacing' => a real number, though usually set to one of 1, 1.5, 2 (line 
spacing as used in word processing)
+
+  // if $test is set then this should just check if the text is going to flow 
onto a new page or not, returning true or false
+
+  // apply the filtering which will make the underlining function.
+  $text = $this->ezProcessText($text);
+
+  $newPage=false;
+  $store_y = $this->y;
+
+  if (is_array($options) && isset($options['aleft'])){
+    $left=$options['aleft'];
+  } else {
+    $left = $this->ez['leftMargin'] + ((is_array($options) && 
isset($options['left']))?$options['left']:0);
+  }
+  if (is_array($options) && isset($options['aright'])){
+    $right=$options['aright'];
+  } else {
+    $right = $this->ez['pageWidth'] - $this->ez['rightMargin'] - 
((is_array($options) && isset($options['right']))?$options['right']:0);
+  }
+  if ($size<=0){
+    $size = $this->ez['fontSize'];
+  } else {
+    $this->ez['fontSize']=$size;
+  }
+
+  if (is_array($options) && isset($options['justification'])){
+    $just = $options['justification'];
+  } else {
+    $just = 'left';
+  }
+
+  // modifications to give leading and spacing based on those given by Craig 
Heydenburg 1/1/02
+  if (is_array($options) && isset($options['leading'])) { ## use leading 
instead of spacing
+    $height = $options['leading'];
+       } else if (is_array($options) && isset($options['spacing'])) {
+    $height = $this->getFontHeight($size) * $options['spacing'];
+       } else {
+               $height = $this->getFontHeight($size);
+       }
+
+
+  $lines = explode("\n",$text);
+  foreach ($lines as $line){
+    $start=1;
+    while (strlen($line) || $start){
+      $start=0;
+      $this->y=$this->y-$height;
+      if ($this->y < $this->ez['bottomMargin']){
+        if ($test){
+          $newPage=true;
+        } else {
+          $this->ezNewPage();
+          // and then re-calc the left and right, in case they have changed 
due to columns
+        }
+      }
+      if (is_array($options) && isset($options['aleft'])){
+        $left=$options['aleft'];
+      } else {
+        $left = $this->ez['leftMargin'] + ((is_array($options) && 
isset($options['left']))?$options['left']:0);
+      }
+      if (is_array($options) && isset($options['aright'])){
+        $right=$options['aright'];
+      } else {
+        $right = $this->ez['pageWidth'] - $this->ez['rightMargin'] - 
((is_array($options) && isset($options['right']))?$options['right']:0);
+      }
+      
$line=$this->addTextWrap($left,$this->y,$right-$left,$size,$line,$just,0,$test);
+    }
+  }
+
+  if ($test){
+    $this->y=$store_y;
+    return $newPage;
+  } else {
+    return $this->y;
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function ezImage($image,$pad = 5,$width = 0,$resize = 'full',$just = 
'center',$border = ''){
+       //beta ezimage function
+       if (stristr($image,'://'))//copy to temp file
+       {
+               $fp = @fopen($image,"rb");
+               while(!feof($fp))
+               {
+                       $cont.= fread($fp,1024);
+               }
+               fclose($fp);
+               $image = tempnam ("/tmp", "php-pdf");
+               $fp2 = @fopen($image,"w");
+               fwrite($fp2,$cont);
+               fclose($fp2);
+               $temp = true;
+       }
+
+       if (!(file_exists($image))) return false; //return immediately if image 
file does not exist
+       $imageInfo = getimagesize($image);
+       switch ($imageInfo[2]){
+               case 2:
+                       $type = "jpeg";
+                       break;
+               case 3:
+                       $type = "png";
+                       break;
+               default:
+                       return false; //return if file is not jpg or png
+       }
+       if ($width == 0) $width = $imageInfo[0]; //set width
+       $ratio = $imageInfo[0]/$imageInfo[1];
+
+       //get maximum width of image
+       if (isset($this->ez['columns']) && $this->ez['columns']['on'] == 1)
+       {
+               $bigwidth = $this->ez['columns']['width'] - ($pad * 2);
+       }
+       else
+       {
+               $bigwidth = $this->ez['pageWidth'] - ($pad * 2);
+       }
+       //fix width if larger than maximum or if $resize=full
+       if ($resize == 'full' || $resize == 'width' || $width > $bigwidth)
+       {
+               $width = $bigwidth;
+
+       }
+
+       $height = ($width/$ratio); //set height
+
+       //fix size if runs off page
+       if ($height > ($this->y - $this->ez['bottomMargin'] - ($pad * 2)))
+       {
+               if ($resize != 'full')
+               {
+                       $this->ezNewPage();
+               }
+               else
+               {
+                       $height = ($this->y - $this->ez['bottomMargin'] - ($pad 
* 2)); //shrink height
+                       $width = ($height*$ratio); //fix width
+               }
+       }
+
+       //fix x-offset if image smaller than bigwidth
+       if ($width < $bigwidth)
+       {
+               //center if justification=center
+               if ($just == 'center')
+               {
+                       $offset = ($bigwidth - $width) / 2;
+               }
+               //move to right if justification=right
+               if ($just == 'right')
+               {
+                       $offset = ($bigwidth - $width);
+               }
+               //leave at left if justification=left
+               if ($just == 'left')
+               {
+                       $offset = 0;
+               }
+       }
+
+
+       //call appropriate function
+       if ($type == "jpeg"){
+               $this->addJpegFromFile($image,$this->ez['leftMargin'] + $pad + 
$offset, $this->y + $this->getFontHeight($this->ez['fontSize']) - $pad - 
$height,$width);
+       }
+
+       if ($type == "png"){
+               $this->addPngFromFile($image,$this->ez['leftMargin'] + $pad + 
$offset, $this->y + $this->getFontHeight($this->ez['fontSize']) - $pad - 
$height,$width);
+       }
+       //draw border
+       if ($border != '')
+       {
+       if (!(isset($border['color'])))
+       {
+               $border['color']['red'] = .5;
+               $border['color']['blue'] = .5;
+               $border['color']['green'] = .5;
+       }
+       if (!(isset($border['width']))) $border['width'] = 1;
+       if (!(isset($border['cap']))) $border['cap'] = 'round';
+       if (!(isset($border['join']))) $border['join'] = 'round';
+
+
+       
$this->setStrokeColor($border['color']['red'],$border['color']['green'],$border['color']['blue']);
+       $this->setLineStyle($border['width'],$border['cap'],$border['join']);
+       $this->rectangle($this->ez['leftMargin'] + $pad + $offset, $this->y + 
$this->getFontHeight($this->ez['fontSize']) - $pad - $height,$width,$height);
+
+       }
+       // move y below image
+       $this->y = $this->y - $pad - $height;
+       //remove tempfile for remote images
+       if ($temp == true) unlink($image);
+
+}
+// 
------------------------------------------------------------------------------
+
+// note that templating code is still considered developmental - have not 
really figured
+// out a good way of doing this yet.
+function loadTemplate($templateFile){
+  // this function will load the requested template ($file includes full or 
relative pathname)
+  // the code for the template will be modified to make it name safe, and then 
stored in
+  // an array for later use
+  // The id of the template will be returned for the user to operate on it 
later
+  if (!file_exists($templateFile)){
+    return -1;
+  }
+
+  $code = implode('',file($templateFile));
+  if (!strlen($code)){
+    return;
+  }
+
+  $code = trim($code);
+  if (substr($code,0,5)=='<?php'){
+    $code = substr($code,5);
+  }
+  if (substr($code,-2)=='?>'){
+    $code = substr($code,0,strlen($code)-2);
+  }
+  if (isset($this->ez['numTemplates'])){
+    $newNum = $this->ez['numTemplates'];
+    $this->ez['numTemplates']++;
+  } else {
+    $newNum=0;
+    $this->ez['numTemplates']=1;
+    $this->ez['templates']=array();
+  }
+
+  $this->ez['templates'][$newNum]['code']=$code;
+
+  return $newNum;
+}
+
+// 
------------------------------------------------------------------------------
+
+function execTemplate($id,$data=array(),$options=array()){
+  // execute the given template on the current document.
+  if (!isset($this->ez['templates'][$id])){
+    return;
+  }
+  eval($this->ez['templates'][$id]['code']);
+}
+
+// 
------------------------------------------------------------------------------
+function ilink($info){
+  $this->alink($info,1);
+}
+
+function alink($info,$internal=0){
+  // a callback function to support the formation of clickable links within 
the document
+  $lineFactor=0.05; // the thickness of the line as a proportion of the 
height. also the drop of the line.
+  switch($info['status']){
+    case 'start':
+    case 'sol':
+      // the beginning of the link
+      // this should contain the URl for the link as the 'p' entry, and will 
also contain the value of 'nCallback'
+      if (!isset($this->ez['links'])){
+        $this->ez['links']=array();
+      }
+      $i = $info['nCallback'];
+      $this->ez['links'][$i] = 
array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>$info['decender'],'height'=>$info['height'],'url'=>$info['p']);
+      if ($internal==0){
+        $this->saveState();
+        $this->setColor(0,0,1);
+        $this->setStrokeColor(0,0,1);
+        $thick = $info['height']*$lineFactor;
+        $this->setLineStyle($thick);
+      }
+      break;
+    case 'end':
+    case 'eol':
+      // the end of the link
+      // assume that it is the most recent opening which has closed
+      $i = $info['nCallback'];
+      $start = $this->ez['links'][$i];
+      // add underlining
+      if ($internal){
+        
$this->addInternalLink($start['url'],$start['x'],$start['y']+$start['decender'],$info['x'],$start['y']+$start['decender']+$start['height']);
+      } else {
+        $a = deg2rad((float)$start['angle']-90.0);
+        $drop = $start['height']*$lineFactor*1.5;
+        $dropx = cos($a)*$drop;
+        $dropy = -sin($a)*$drop;
+        
$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-$dropx,$info['y']-$dropy);
+        
$this->addLink($start['url'],$start['x'],$start['y']+$start['decender'],$info['x'],$start['y']+$start['decender']+$start['height']);
+        $this->restoreState();
+      }
+      break;
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+function uline($info){
+  // a callback function to support underlining
+  $lineFactor=0.05; // the thickness of the line as a proportion of the 
height. also the drop of the line.
+  switch($info['status']){
+    case 'start':
+    case 'sol':
+
+      // the beginning of the underline zone
+      if (!isset($this->ez['links'])){
+        $this->ez['links']=array();
+      }
+      $i = $info['nCallback'];
+      $this->ez['links'][$i] = 
array('x'=>$info['x'],'y'=>$info['y'],'angle'=>$info['angle'],'decender'=>$info['decender'],'height'=>$info['height']);
+      $this->saveState();
+      $thick = $info['height']*$lineFactor;
+      $this->setLineStyle($thick);
+      break;
+    case 'end':
+    case 'eol':
+      // the end of the link
+      // assume that it is the most recent opening which has closed
+      $i = $info['nCallback'];
+      $start = $this->ez['links'][$i];
+      // add underlining
+      $a = deg2rad((float)$start['angle']-90.0);
+      $drop = $start['height']*$lineFactor*1.5;
+      $dropx = cos($a)*$drop;
+      $dropy = -sin($a)*$drop;
+      
$this->line($start['x']-$dropx,$start['y']-$dropy,$info['x']-$dropx,$info['y']-$dropy);
+      $this->restoreState();
+      break;
+  }
+}
+
+// 
------------------------------------------------------------------------------
+
+}
 ?>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]