eZ Publish  [4.0]
class.ezpdf.php
Go to the documentation of this file.
00001 <?php
00002 
00003 //
00004 // Created on: <26-Aug-2003 15:15:32 kk>
00005 //
00006 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00007 // SOFTWARE NAME: eZ Publish
00008 // SOFTWARE RELEASE: 4.0.x
00009 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00010 // SOFTWARE LICENSE: GNU General Public License v2.0
00011 // NOTICE: >
00012 //   This program is free software; you can redistribute it and/or
00013 //   modify it under the terms of version 2.0  of the GNU General
00014 //   Public License as published by the Free Software Foundation.
00015 //
00016 //   This program is distributed in the hope that it will be useful,
00017 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //   GNU General Public License for more details.
00020 //
00021 //   You should have received a copy of version 2.0 of the GNU General
00022 //   Public License along with this program; if not, write to the Free
00023 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00024 //   MA 02110-1301, USA.
00025 //
00026 //
00027 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00028 //
00029 
00030 /*! \file class.ezpdf.php
00031 */
00032 
00033 //include_once( 'lib/ezpdf/classes/class.pdf.php' );
00034 
00035 /*!
00036   \class Cezpdf class.ezpdf.php
00037   \ingroup eZPDF
00038   \brief Cezpdf provides
00039 */
00040 
00041 class Cezpdf extends Cpdf
00042 {
00043 
00044     public $ez=array('fontSize'=>10); // used for storing most of the page configuration parameters
00045     public $y; // this is the current vertical positon on the page of the writing point, very important
00046     public $ezPages=array(); // keep an array of the ids of the pages, making it easy to go back and add page numbers etc.
00047     public $ezPageCount=0;
00048 
00049 // ------------------------------------------------------------------------------
00050 
00051     function Cezpdf( $paper = 'a4', $orientation = 'portrait' )
00052     {
00053         // Assuming that people don't want to specify the paper size using the absolute coordinates
00054         // allow a couple of options:
00055         // orientation can be 'portrait' or 'landscape'
00056         // or, to actually set the coordinates, then pass an array in as the first parameter.
00057         // the defaults are as shown.
00058         //
00059         // -------------------------
00060         // 2002-07-24 - Nicola Asuni (info@tecnick.com):
00061         // Added new page formats (45 standard ISO paper formats and 4 american common formats)
00062         // paper cordinates are calculated in this way: (inches * 72) where 1 inch = 2.54 cm
00063         //
00064         // Now you may also pass a 2 values array containing the page width and height in centimeters
00065         // -------------------------
00066 
00067         if ( !is_array( $paper ) )
00068         {
00069             switch ( strtoupper( $paper ) )
00070             {
00071                 case '4A0': {$size = array(0,0,4767.87,6740.79); break;}
00072                 case '2A0': {$size = array(0,0,3370.39,4767.87); break;}
00073                 case 'A0': {$size = array(0,0,2383.94,3370.39); break;}
00074                 case 'A1': {$size = array(0,0,1683.78,2383.94); break;}
00075                 case 'A2': {$size = array(0,0,1190.55,1683.78); break;}
00076                 case 'A3': {$size = array(0,0,841.89,1190.55); break;}
00077                 case 'A4': default: {$size = array(0,0,595.28,841.89); break;}
00078                 case 'A5': {$size = array(0,0,419.53,595.28); break;}
00079                 case 'A6': {$size = array(0,0,297.64,419.53); break;}
00080                 case 'A7': {$size = array(0,0,209.76,297.64); break;}
00081                 case 'A8': {$size = array(0,0,147.40,209.76); break;}
00082                 case 'A9': {$size = array(0,0,104.88,147.40); break;}
00083                 case 'A10': {$size = array(0,0,73.70,104.88); break;}
00084                 case 'B0': {$size = array(0,0,2834.65,4008.19); break;}
00085                 case 'B1': {$size = array(0,0,2004.09,2834.65); break;}
00086                 case 'B2': {$size = array(0,0,1417.32,2004.09); break;}
00087                 case 'B3': {$size = array(0,0,1000.63,1417.32); break;}
00088                 case 'B4': {$size = array(0,0,708.66,1000.63); break;}
00089                 case 'B5': {$size = array(0,0,498.90,708.66); break;}
00090                 case 'B6': {$size = array(0,0,354.33,498.90); break;}
00091                 case 'B7': {$size = array(0,0,249.45,354.33); break;}
00092                 case 'B8': {$size = array(0,0,175.75,249.45); break;}
00093                 case 'B9': {$size = array(0,0,124.72,175.75); break;}
00094                 case 'B10': {$size = array(0,0,87.87,124.72); break;}
00095                 case 'C0': {$size = array(0,0,2599.37,3676.54); break;}
00096                 case 'C1': {$size = array(0,0,1836.85,2599.37); break;}
00097                 case 'C2': {$size = array(0,0,1298.27,1836.85); break;}
00098                 case 'C3': {$size = array(0,0,918.43,1298.27); break;}
00099                 case 'C4': {$size = array(0,0,649.13,918.43); break;}
00100                 case 'C5': {$size = array(0,0,459.21,649.13); break;}
00101                 case 'C6': {$size = array(0,0,323.15,459.21); break;}
00102                 case 'C7': {$size = array(0,0,229.61,323.15); break;}
00103                 case 'C8': {$size = array(0,0,161.57,229.61); break;}
00104                 case 'C9': {$size = array(0,0,113.39,161.57); break;}
00105                 case 'C10': {$size = array(0,0,79.37,113.39); break;}
00106                 case 'RA0': {$size = array(0,0,2437.80,3458.27); break;}
00107                 case 'RA1': {$size = array(0,0,1729.13,2437.80); break;}
00108                 case 'RA2': {$size = array(0,0,1218.90,1729.13); break;}
00109                 case 'RA3': {$size = array(0,0,864.57,1218.90); break;}
00110                 case 'RA4': {$size = array(0,0,609.45,864.57); break;}
00111                 case 'SRA0': {$size = array(0,0,2551.18,3628.35); break;}
00112                 case 'SRA1': {$size = array(0,0,1814.17,2551.18); break;}
00113                 case 'SRA2': {$size = array(0,0,1275.59,1814.17); break;}
00114                 case 'SRA3': {$size = array(0,0,907.09,1275.59); break;}
00115                 case 'SRA4': {$size = array(0,0,637.80,907.09); break;}
00116                 case 'LETTER': {$size = array(0,0,612.00,792.00); break;}
00117                 case 'LEGAL': {$size = array(0,0,612.00,1008.00); break;}
00118                 case 'EXECUTIVE': {$size = array(0,0,521.86,756.00); break;}
00119                 case 'FOLIO': {$size = array(0,0,612.00,936.00); break;}
00120             }
00121             switch ( strtolower( $orientation ) )
00122             {
00123                 case 'landscape':
00124                     $a=$size[3];
00125                     $size[3]=$size[2];
00126                     $size[2]=$a;
00127                 break;
00128             }
00129         }
00130         else
00131         {
00132             if ( count( $paper ) > 2 )
00133             {   // then an array was sent it to set the size
00134                 $size = $paper;
00135             }
00136             else
00137             {   //size in centimeters has been passed
00138                 $size[0] = 0;
00139                 $size[1] = 0;
00140                 $size[2] = ( $paper[0] / 2.54 ) * 72;
00141                 $size[3] = ( $paper[1] / 2.54 ) * 72;
00142             }
00143         }
00144         $this->Cpdf( $size );
00145         $this->ez['pageWidth']=$size[2];
00146         $this->ez['pageHeight']=$size[3];
00147 
00148         // also set the margins to some reasonable defaults
00149         $config = eZINI::instance( 'pdf.ini' );
00150 
00151         $this->ez['topMargin']=$config->variable( 'PDFGeneral', 'TopMargin' );
00152         $this->ez['bottomMargin']=$config->variable( 'PDFGeneral', 'BottomMargin' );
00153         $this->ez['leftMargin']=$config->variable( 'PDFGeneral', 'LeftMargin' );
00154         $this->ez['rightMargin']=$config->variable( 'PDFGeneral', 'RightMargin' );
00155 
00156         // set the current writing position to the top of the first page
00157         $this->y = $this->ez['pageHeight']-$this->ez['topMargin'];
00158         $this->ez['xOffset'] = 0;
00159 
00160         // set current text justification
00161         $this->ez['justification'] = 'left';
00162         $this->ez['lineSpace'] = 1;
00163         // and get the ID of the page that was created during the instancing process.
00164         $this->ezPages[1]=$this->getFirstPageId();
00165         $this->ezPageCount=1;
00166     }
00167 
00168 // ------------------------------------------------------------------------------
00169 // 2002-07-24: Nicola Asuni (info@tecnick.com)
00170 // Set Margins in centimeters
00171     function ezSetCmMargins( $top, $bottom, $left, $right )
00172     {
00173         $top = ( $top / 2.54 ) * 72;
00174         $bottom = ( $bottom / 2.54 ) * 72;
00175         $left = ( $left / 2.54 ) * 72;
00176         $right = ( $right / 2.54 ) * 72;
00177         $this->ezSetMargins( $top, $bottom, $left, $right );
00178     }
00179 
00180 // ------------------------------------------------------------------------------
00181 // 2003-11-04 Kåre Køhler Høvik ( eZ Systems, http://ez.no )
00182 // Set fontsize
00183 
00184     function setFontSize( $size )
00185     {
00186         $this->ez['fontSize'] = $size;
00187     }
00188 
00189 // ------------------------------------------------------------------------------
00190 // 2003-11-06 Kåre Køhler Høvik ( eZ Systems, http://ez.no )
00191 // Set justification
00192 
00193     function setJustification( $align )
00194     {
00195         $this->ez['justification'] = $align;
00196     }
00197 
00198 // ------------------------------------------------------------------------------
00199 // 2003-11-06 Kåre Køhler Høvik ( eZ Systems, http://ez.no )
00200 // Get justification
00201 
00202     function justification()
00203     {
00204         return $this->ez['justification'];
00205     }
00206 
00207 // ------------------------------------------------------------------------------
00208 // 2003-11-04 Kåre Køhler Høvik ( eZ Systems, http://ez.no )
00209 // Get fontsize
00210 
00211     function fontSize()
00212     {
00213         return $this->ez['fontSize'];
00214     }
00215 
00216 // ------------------------------------------------------------------------------
00217 
00218     function ezColumnsStart( $options = array() )
00219     {
00220         // start from the current y-position, make the set number of columne
00221         if ( isset( $this->ez['columns'] ) && $this->ez['columns'] == 1 )
00222         {   // if we are already in a column mode then just return.
00223             return;
00224         }
00225         $def = array( 'gap'=>10, 'num'=>2 );
00226         foreach( $def as $k => $v )
00227         {
00228             if ( !isset( $options[$k] ) )
00229             {
00230                 $options[$k] = $v;
00231             }
00232         }
00233         // setup the columns
00234         $this->ez['columns'] = array( 'on' => 1, 'colNum' => 1 );
00235 
00236         // store the current margins
00237         $this->ez['columns']['margins'] = array( $this->ez['leftMargin'],
00238                                                  $this->ez['rightMargin'],
00239                                                  $this->ez['topMargin'],
00240                                                  $this->ez['bottomMargin'] );
00241         // and store the settings for the columns
00242         $this->ez['columns']['options'] = $options;
00243         // then reset the margins to suit the new columns
00244         // safe enough to assume the first column here, but start from the current y-position
00245         $this->ez['topMargin'] = $this->ez['pageHeight']-$this->y;
00246         $width = ( $this->ez['pageWidth'] - $this->ez['leftMargin'] - $this->ez['rightMargin'] - ( $options['num'] - 1 ) * $options['gap'] ) / $options['num'];
00247         $this->ez['columns']['width'] = $width;
00248         $this->ez['rightMargin'] = $this->ez['pageWidth'] - $this->ez['leftMargin'] - $width;
00249 
00250     }
00251 // ------------------------------------------------------------------------------
00252     function ezColumnsStop()
00253     {
00254         if ( isset( $this->ez['columns'] ) && $this->ez['columns']['on']==1 )
00255         {
00256             $this->ez['columns']['on'] = 0;
00257             $this->ez['leftMargin'] = $this->ez['columns']['margins'][0];
00258             $this->ez['rightMargin'] = $this->ez['columns']['margins'][1];
00259             $this->ez['topMargin'] = $this->ez['columns']['margins'][2];
00260             $this->ez['bottomMargin'] = $this->ez['columns']['margins'][3];
00261         }
00262     }
00263 // ------------------------------------------------------------------------------
00264     function ezInsertMode( $status = 1, $pageNum = 1, $pos = 'before' )
00265     {
00266         // puts the document into insert mode. new pages are inserted until this is re-called with status=0
00267         // by default pages wil be inserted at the start of the document
00268         switch ( $status )
00269         {
00270             case '1':
00271                 if ( isset( $this->ezPages[$pageNum] ) )
00272                 {
00273                     $this->ez['insertMode'] = 1;
00274                     $this->ez['insertOptions'] = array( 'id' => $this->ezPages[$pageNum],
00275                                                         'pos' => $pos );
00276                 } break;
00277             case '0':
00278                 $this->ez['insertMode'] = 0;
00279                 break;
00280         }
00281     }
00282 // ------------------------------------------------------------------------------
00283 
00284     function ezNewPage()
00285     {
00286         $pageRequired = 1;
00287         if ( isset( $this->ez['columns'] ) && $this->ez['columns']['on'] == 1 )
00288         {
00289             // check if this is just going to a new column
00290             // increment the column number
00291 
00292             $this->ez['columns']['colNum']++;
00293             if ( $this->ez['columns']['colNum'] <= $this->ez['columns']['options']['num'] )
00294             {
00295                 // then just reset to the top of the next column
00296                 $pageRequired=0;
00297             }
00298             else
00299             {
00300                 $this->ez['columns']['colNum'] = 1;
00301                 $this->ez['topMargin'] = $this->ez['columns']['margins'][2];
00302             }
00303 
00304             $width = $this->ez['columns']['width'];
00305             $this->ez['leftMargin'] = $this->ez['columns']['margins'][0] + ( $this->ez['columns']['colNum'] - 1 ) * ( $this->ez['columns']['options']['gap'] + $width );
00306             $this->ez['rightMargin'] = $this->ez['pageWidth'] - $this->ez['leftMargin'] - $width;
00307         }
00308 
00309         if ( $pageRequired )
00310         {
00311             // make a new page, setting the writing point back to the top
00312             $this->y = $this->ez['pageHeight']-$this->ez['topMargin'] - $this->getFontHeight();
00313             $this->ez['xOffset'] = 0;
00314             // make the new page with a call to the basic class.
00315             $this->ezPageCount++;
00316             if ( isset( $this->ez['insertMode'] ) && $this->ez['insertMode'] == 1 )
00317             {
00318                 $id = $this->ezPages[$this->ezPageCount] = $this->newPage( 1, $this->ez['insertOptions']['id'], $this->ez['insertOptions']['pos'] );
00319                 // then manipulate the insert options so that inserted pages follow each other
00320                 $this->ez['insertOptions']['id'] = $id;
00321                 $this->ez['insertOptions']['pos'] = 'after';
00322             }
00323             else
00324             {
00325                 $this->ezPages[$this->ezPageCount] = $this->newPage();
00326             }
00327         }
00328         else
00329         {
00330             $this->y = $this->ez['pageHeight']-$this->ez['topMargin'] - $this->getFontHeight();
00331             $this->ez['xOffset'] = 0;
00332         }
00333         $this->RightMarginArray = array();
00334         $this->LeftMarginArray = array();
00335     }
00336 
00337 // ------------------------------------------------------------------------------
00338 
00339     function ezSetMargins( $top, $bottom, $left, $right )
00340     {
00341         // sets the margins to new values
00342         $this->ez['topMargin'] = $top;
00343         $this->ez['bottomMargin'] = $bottom;
00344         $this->ez['leftMargin'] = $left;
00345         $this->ez['rightMargin'] = $right;
00346         $this->LeftMarginArray = array();
00347         $this->RightMarginArray = array();
00348         // check to see if this means that the current writing position is outside the
00349         // writable area
00350         if ( $this->y > $this->ez['pageHeight'] - $top )
00351         {
00352             // then move y down
00353             $this->ezSetY( $this->ez['pageHeight'] - $top );
00354         }
00355         if ( $this->y < $bottom )
00356         {
00357             // then make a new page
00358             $this->ezNewPage();
00359         }
00360     }
00361 
00362 // ------------------------------------------------------------------------------
00363 
00364     function ezGetCurrentPageNumber()
00365     {
00366         // return the strict numbering (1,2,3,4..) number of the current page
00367         return $this->ezPageCount;
00368     }
00369 
00370 // ------------------------------------------------------------------------------
00371 
00372     function ezStartPageNumbers( $x, $y, $size, $pos = 'left', $pattern = '{PAGENUM} of {TOTALPAGENUM}', $num = '' )
00373     {
00374         // put page numbers on the pages from here.
00375         // place then on the 'pos' side of the coordinates (x,y).
00376         // pos can be 'left' or 'right'
00377         // use the given 'pattern' for display, where (PAGENUM} and {TOTALPAGENUM} are replaced
00378         // as required.
00379         // if $num is set, then make the first page this number, the number of total pages will
00380         // be adjusted to account for this.
00381         // Adjust this function so that each time you 'start' page numbers then you effectively start a different batch
00382         // return the number of the batch, so that they can be stopped in a different order if required.
00383         if ( !$pos || !strlen( $pos ) )
00384         {
00385             $pos='left';
00386         }
00387         if ( !$pattern || !strlen( $pattern ) )
00388         {
00389             $pattern = '{PAGENUM} of {TOTALPAGENUM}';
00390         }
00391         if ( !isset( $this->ez['pageNumbering'] ) )
00392         {
00393             $this->ez['pageNumbering'] = array();
00394         }
00395         $i = count( $this->ez['pageNumbering'] );
00396         $this->ez['pageNumbering'][$i][$this->ezPageCount] = array( 'x' => $x, 'y' => $y, 'pos' => $pos, 'pattern' => $pattern, 'num' => $num, 'size' => $size );
00397         return $i;
00398     }
00399 
00400 // ------------------------------------------------------------------------------
00401 
00402     function ezWhatPageNumber( $pageNum, $i = 0 )
00403     {
00404         // given a particular generic page number (ie, document numbered sequentially from beginning),
00405         // return the page number under a particular page numbering scheme ($i)
00406         $num = 0;
00407         $start = 1;
00408         $startNum = 1;
00409         if ( !isset( $this->ez['pageNumbering'] ) )
00410         {
00411             $this->addMessage( 'WARNING: page numbering called for and wasn\'t started with ezStartPageNumbers' );
00412             return 0;
00413         }
00414         foreach ( $this->ez['pageNumbering'][$i] as $k => $v )
00415         {
00416             if ( $k <= $pageNum )
00417             {
00418                 if ( is_array( $v ) )
00419                 {
00420                     // start block
00421                     if ( strlen( $v['num'] ) )
00422                     {
00423                         // a start was specified
00424                         $start = $v['num'];
00425                         $startNum = $k;
00426                         $num = $pageNum - $startNum + $start;
00427                     }
00428                 }
00429                 else
00430                 {
00431                     // stop block
00432                     $num = 0;
00433                 }
00434             }
00435         }
00436         return $num;
00437     }
00438 
00439 // ------------------------------------------------------------------------------
00440 
00441     function ezStopPageNumbers( $stopTotal = 0, $next = 0, $i = 0 )
00442     {
00443         // if stopTotal=1 then the totalling of pages for this number will stop too
00444         // if $next=1, then do this page, but not the next, else do not do this page either
00445         // if $i is set, then stop that particular pagenumbering sequence.
00446         if ( !isset( $this->ez['pageNumbering'] ) )
00447         {
00448             $this->ez['pageNumbering'] = array();
00449         }
00450         if ( $next && isset( $this->ez['pageNumbering'][$i][$this->ezPageCount] ) &&
00451              is_array( $this->ez['pageNumbering'][$i][$this->ezPageCount] ) )
00452         {
00453             // then this has only just been started, this will over-write the start, and nothing will appear
00454             // add a special command to the start block, telling it to stop as well
00455             if ( $stopTotal )
00456             {
00457                 $this->ez['pageNumbering'][$i][$this->ezPageCount]['stoptn'] = 1;
00458             }
00459             else
00460             {
00461                 $this->ez['pageNumbering'][$i][$this->ezPageCount]['stopn'] = 1;
00462             }
00463         }
00464         else
00465         {
00466             if ( $stopTotal )
00467             {
00468                 $this->ez['pageNumbering'][$i][$this->ezPageCount] = 'stopt';
00469             }
00470             else
00471             {
00472                 $this->ez['pageNumbering'][$i][$this->ezPageCount] = 'stop';
00473             }
00474             if ( $next )
00475             {
00476                 $this->ez['pageNumbering'][$i][$this->ezPageCount] .= 'n';
00477             }
00478         }
00479     }
00480 
00481 // ------------------------------------------------------------------------------
00482 
00483     function ezPRVTpageNumberSearch( $lbl, &$tmp )
00484     {
00485         foreach ( $tmp as $i => $v )
00486         {
00487             if ( is_array( $v ) )
00488             {
00489                 if ( isset( $v[$lbl] ) )
00490                 {
00491                     return $i;
00492                 }
00493             }
00494             else
00495             {
00496                 if ( $v == $lbl )
00497                 {
00498                     return $i;
00499                 }
00500             }
00501         }
00502         return 0;
00503     }
00504 
00505 // ------------------------------------------------------------------------------
00506 
00507     function ezPRVTaddPageNumbers()
00508     {
00509         // this will go through the pageNumbering array and add the page numbers are required
00510         if ( isset( $this->ez['pageNumbering'] ) )
00511         {
00512             $totalPages1 = $this->ezPageCount;
00513             $tmp1 = $this->ez['pageNumbering'];
00514             $status = 0;
00515             foreach ( $tmp1 as $i => $tmp )
00516             {
00517                 // do each of the page numbering systems
00518                 // firstly, find the total pages for this one
00519                 $k = $this->ezPRVTpageNumberSearch( 'stopt', $tmp );
00520                 if ( $k && $k > 0 )
00521                 {
00522                     $totalPages = $k - 1;
00523                 }
00524                 else
00525                 {
00526                     $l = $this->ezPRVTpageNumberSearch( 'stoptn', $tmp );
00527                     if ( $l && $l > 0 )
00528                     {
00529                         $totalPages = $l;
00530                     }
00531                     else
00532                     {
00533                         $totalPages = $totalPages1;
00534                     }
00535                 }
00536                 foreach ( $this->ezPages as $pageNum => $id )
00537                 {
00538                     if ( isset( $tmp[$pageNum] ) )
00539                     {
00540                         if ( is_array( $tmp[$pageNum] ) )
00541                         {
00542                             // then this must be starting page numbers
00543                             $status = 1;
00544                             $info = $tmp[$pageNum];
00545                             $info['dnum'] = $info['num'] - $pageNum;
00546                             // also check for the special case of the numbering stopping and starting on the same page
00547                             if ( isset( $info['stopn'] ) || isset( $info['stoptn'] ) )
00548                             {
00549                                 $status = 2;
00550                             }
00551                         }
00552                         else if ( $tmp[$pageNum] == 'stop' || $tmp[$pageNum] == 'stopt' )
00553                         {
00554                             // then we are stopping page numbers
00555                             $status = 0;
00556                         }
00557                         else if ( $status == 1 && ( $tmp[$pageNum] == 'stoptn' || $tmp[$pageNum] == 'stopn' ) )
00558                         {
00559                             // then we are stopping page numbers
00560                             $status = 2;
00561                         }
00562                     }
00563                     if ( $status )
00564                     {
00565                         // then add the page numbering to this page
00566                         if ( strlen( $info['num'] ) )
00567                         {
00568                             $num = $pageNum + $info['dnum'];
00569                         }
00570                         else
00571                         {
00572                             $num = $pageNum;
00573                         }
00574                         $total = $totalPages + $num - $pageNum;
00575                         $pat = str_replace( '{PAGENUM}', $num, $info['pattern'] );
00576                         $pat = str_replace( '{TOTALPAGENUM}', $total, $pat );
00577                         $this->reopenObject( $id );
00578                         switch ( $info['pos'] )
00579                         {
00580                             case 'right':
00581                                 $this->addText( $info['x'], $info['y'], $info['size'], $pat );
00582                                 break;
00583                             default:
00584                                 $w = $this->getTextWidth( $info['size'], $pat );
00585                                 $this->addText( $info['x'] - $w, $info['y'], $info['size'], $pat );
00586                                 break;
00587                         }
00588                         $this->closeObject();
00589                     }
00590                     if ( $status == 2 )
00591                     {
00592                         $status = 0;
00593                     }
00594                 }
00595             }
00596         }
00597     }
00598 
00599 // ------------------------------------------------------------------------------
00600 
00601     function ezPRVTcleanUp()
00602     {
00603         $this->ezPRVTaddPageNumbers();
00604     }
00605 
00606 // ------------------------------------------------------------------------------
00607 
00608     function ezStream( $options = '' )
00609     {
00610         $this->ezPRVTcleanUp();
00611         $this->stream( $options );
00612     }
00613 
00614 // ------------------------------------------------------------------------------
00615 
00616     function ezOutput( $options = 0 )
00617     {
00618         $this->ezPRVTcleanUp();
00619         return $this->output( $options );
00620     }
00621 
00622 // ------------------------------------------------------------------------------
00623 
00624     function ezSetY( $y )
00625     {
00626         // used to change the vertical position of the writing point.
00627         $this->y = $y;
00628         $this->ez['xOffset'] = 0;
00629         if ( $this->y < $this->ez['bottomMargin'] )
00630         {
00631             // then make a new page
00632             $this->ezNewPage();
00633         }
00634     }
00635 
00636 // ------------------------------------------------------------------------------
00637 
00638     function ezSetDy( $dy, $mod = '' )
00639     {
00640         // used to change the vertical position of the writing point.
00641         // changes up by a positive increment, so enter a negative number to go
00642         // down the page
00643         // if $mod is set to 'makeSpace' and a new page is forced, then the pointed will be moved
00644         // down on the new page, this will allow space to be reserved for graphics etc.
00645         $this->y += $dy;
00646         $this->ez['xOffset'] = 0;
00647         if ( $this->y < $this->ez['bottomMargin'] )
00648         {
00649             // then make a new page
00650             $this->ezNewPage();
00651             if ( $mod == 'makeSpace' )
00652             {
00653                 $this->y += $dy;
00654             }
00655         }
00656     }
00657 
00658 // ------------------------------------------------------------------------------
00659 
00660     function ezPrvtTableDrawLines( $pos, $gap, $x0, $x1, $y0, $y1, $y2, $col, $inner, $outer, $opt = 1 )
00661     {
00662         $x0 = 1000;
00663         $x1 = 0;
00664         $this->setStrokeColorRGB( $col[0], $col[1], $col[2] );
00665         $cnt = 0;
00666         $n = count( $pos );
00667         foreach ( $pos as $x )
00668         {
00669             $cnt++;
00670             if ( $cnt == 1 || $cnt == $n )
00671             {
00672                 $this->setLineStyle( $outer );
00673             }
00674             else
00675             {
00676                 $this->setLineStyle( $inner );
00677             }
00678             $this->line( $x - $gap / 2, $y0, $x - $gap / 2, $y2 );
00679             if ( $x > $x1 )
00680             {
00681                 $x1 = $x;
00682             }
00683             if ( $x < $x0 )
00684             {
00685                 $x0 = $x;
00686             }
00687         }
00688         $this->setLineStyle( $outer );
00689         $this->line( $x0 - $gap / 2 - $outer / 2, $y0, $x1 - $gap / 2 + $outer / 2, $y0 );
00690         // only do the second line if it is different to the first, AND each row does not have
00691         // a line on it.
00692         if ( $y0 != $y1 && $opt < 2 )
00693         {
00694             $this->line( $x0 - $gap / 2, $y1, $x1 - $gap / 2, $y1 );
00695         }
00696         $this->line( $x0 - $gap / 2 - $outer / 2, $y2, $x1 - $gap / 2 + $outer / 2, $y2 );
00697     }
00698 
00699 // ------------------------------------------------------------------------------
00700 
00701     function ezPrvtTableColumnHeadings( $cols, $pos, $maxWidth, $height, $decender, $gap, $size, &$y, $optionsAll = array() )
00702     {
00703         // uses ezText to add the text, and returns the height taken by the largest heading
00704         // this page will move the headings to a new page if they will not fit completely on this one
00705         // transaction support will be used to implement this
00706 
00707         if ( isset( $optionsAll['cols'] ) )
00708         {
00709             $options = $optionsAll['cols'];
00710         }
00711         else
00712         {
00713             $options = array();
00714         }
00715 
00716         $mx = 0;
00717         $startPage = $this->ezPageCount;
00718         $secondGo = 0;
00719 
00720         // $y is the position at which the top of the table should start, so the base
00721         // of the first text, is $y-$height-$gap-$decender, but ezText starts by dropping $height
00722 
00723         // the return from this function is the total cell height, including gaps, and $y is adjusted
00724         // to be the postion of the bottom line
00725 
00726         // begin the transaction
00727         $this->transaction( 'start' );
00728         $ok = 0;
00729 //  $y-=$gap-$decender;
00730         $y -= $gap;
00731         while ( $ok == 0 )
00732         {
00733             foreach ( $cols as $colName => $colHeading )
00734             {
00735                 $this->ezSetY( $y );
00736                 if ( isset( $options[$colName] ) && isset( $options[$colName]['justification'] ) )
00737                 {
00738                     $justification = $options[$colName]['justification'];
00739                 }
00740                 else
00741                 {
00742                     $justification = $this->ez['justification'];
00743                 }
00744 //                $this->ezText($colHeading,$size,array('aleft'=> $pos[$colName],'aright'=>($maxWidth[$colName]+$pos[$colName]),'justification'=>$justification));
00745                 $dy = $y - $this->y;
00746                 if ( $dy > $mx )
00747                 {
00748                     $mx = $dy;
00749                 }
00750             }
00751             $y = $y - $mx - $gap + $decender;
00752 //    $y -= $mx-$gap+$decender;
00753 
00754             // now, if this has moved to a new page, then abort the transaction, move to a new page, and put it there
00755             // do not check on the second time around, to avoid an infinite loop
00756             if ( $this->ezPageCount != $startPage && $secondGo == 0 )
00757             {
00758                 $this->transaction( 'rewind' );
00759                 $this->ezNewPage();
00760                 $y = $this->y - $gap - $decender;
00761                 $ok = 0;
00762                 $secondGo = 1;
00763 //      $y = $store_y;
00764                 $mx = 0;
00765             }
00766             else
00767             {
00768                 $this->transaction( 'commit' );
00769                 $ok = 1;
00770             }
00771         }
00772 
00773         return $mx + $gap * 2 - $decender;
00774     }
00775 
00776 // ------------------------------------------------------------------------------
00777 
00778     /*!
00779      Get maximum length of single word in sentence.
00780 
00781      \param font size
00782      \param text ( sentence )
00783 
00784      \return maximum word width
00785     */
00786     function eZGetMaxWordWidth( $size, $text )
00787     {
00788         $mx = 0;
00789         $text = str_replace( '-', ' ', $text );
00790         $words = str_word_count( $text, 1 );
00791         foreach ( $words as $word )
00792         {
00793             $w = $this->getTextWidth($size,$word);
00794             if ( $w > $mx )
00795             {
00796                 $mx = $w;
00797             }
00798         }
00799         return $mx;
00800     }
00801 
00802     function ezPrvtGetTextWidth( $size, $text )
00803     {
00804         // will calculate the maximum width, taking into account that the text may be broken
00805         // by line breaks.
00806         $mx = 0;
00807         $lines = explode( "\n", $text );
00808         foreach ( $lines as $line )
00809         {
00810             $w = $this->getTextWidth( $size, $line );
00811             if ( $w > $mx )
00812             {
00813                 $mx = $w;
00814             }
00815         }
00816         return $mx;
00817     }
00818 
00819     /**
00820      Draw a shaded rectangle
00821 
00822      direction is optional and set to vertical by default
00823 
00824      \param x1
00825      \param y1
00826      \param width
00827      \param height
00828      \param col1
00829      \param col2
00830      \param direction ('vertical', 'horizontal', or angle)
00831     */
00832     function ezShadedRectangle( $x1, $y1, $width, $height, $col1, $col2, $direction = 'vertical' )
00833     {
00834         $this->shadedRectangle( $x1, $y1, $width, $height, array( 'orientation' => $direction,
00835                                                                   'color0' => $col1,
00836                                                                   'color1' => $col2,
00837                                                                   'size' => array( 'x1' => $x1,
00838                                                                                    'y1' => $y1,
00839                                                                                    'width' => $width,
00840                                                                                    'height' => $height ) ) );
00841     }
00842 
00843 // ------------------------------------------------------------------------------
00844     function ezProcessText( $text )
00845     {
00846         // this function will intially be used to implement underlining support, but could be used for a range of other
00847         // purposes
00848         $search = array( '<u>', '<U>', '</u>', '</U>' );
00849         $replace = array( '<c:uline>', '<c:uline>', '</c:uline>', '</c:uline>' );
00850         return str_replace( $search, $replace, $text );
00851     }
00852 
00853 // ------------------------------------------------------------------------------
00854 
00855     function ezText( $text, $size = 0, $options = array(), $test = 0 )
00856     {
00857         // this will add a string of text to the document, starting at the current drawing
00858         // position.
00859         // it will wrap to keep within the margins, including optional offsets from the left
00860         // and the right, if $size is not specified, then it will be the last one used, or
00861         // the default value (12 I think).
00862         // the text will go to the start of the next line when a return code "\n" is found.
00863         // possible options are:
00864         // 'left'=> number, gap to leave from the left margin
00865         // 'right'=> number, gap to leave from the right margin
00866         // 'aleft'=> number, absolute left position (overrides 'left')
00867         // 'aright'=> number, absolute right position (overrides 'right')
00868         // 'justification' => 'left','right','center','centre','full'
00869         // 'top_margin' => set top margin manualy
00870 
00871         // only set one of the next two items (leading overrides spacing)
00872         // 'leading' => number, defines the total height taken by the line, independent of the font height.
00873         // 'spacing' => a real number, though usually set to one of 1, 1.5, 2 (line spacing as used in word processing)
00874 
00875         // 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
00876 
00877         // apply the filtering which will make the underlining function.
00878         if ( strlen( $text ) == 0 )
00879             return $this->y;
00880 
00881         $text = $this->ezProcessText( $text );
00882 
00883         $newPage = false;
00884         $store_y = $this->y;
00885         $left = $angle = $adjust = 0;
00886 
00887         if ( is_array( $options ) && isset( $options['aright'] ) )
00888         {
00889             $right = $options['aright'];
00890         }
00891         else
00892         {
00893             $right = $this->ez['pageWidth'] - $this->rightMargin() - ( ( is_array( $options ) && isset( $options['right'] ) ) ? $options['right'] : 0 );
00894         }
00895         if ( $size <= 0 )
00896         {
00897             $size = $this->ez['fontSize'];
00898         }
00899         else
00900         {
00901             $this->ez['fontSize'] = $size;
00902         }
00903 
00904         if ( is_array( $options ) && isset( $options['top_margin'] ) )
00905         {
00906             $this->y = $this->ez['pageHeight'] - $options['top_margin'];
00907         }
00908 
00909         if ( is_array( $options ) && isset( $options['justification'] ) )
00910         {
00911             $just = $options['justification'];
00912         }
00913         else
00914         {
00915             $just = $this->ez['justification'];
00916         }
00917 
00918         // modifications to give leading and spacing based on those given by Craig Heydenburg 1/1/02
00919         if ( is_array( $options ) && isset( $options['leading'] ) )
00920         { // use leading instead of spacing
00921             $height = $options['leading'];
00922         }
00923         else if ( is_array( $options ) && isset( $options['spacing'] ) )
00924         {
00925             $height = $this->getFontHeight( $size ) * $options['spacing'];
00926         }
00927         else
00928         {
00929             $height = $this->getFontHeight( $size );
00930         }
00931 
00932         $lastOnlyDirective = false;
00933         $lines = explode( "\n", $text );
00934         if ( $text == "\n" )
00935         {
00936             $lines = array( "" );
00937         }
00938         foreach ( array_keys( $lines ) as $key )
00939         {
00940             $line = $lines[$key];
00941             if ( ( $key > 0 || strlen( $line ) == 0 ) &&
00942                  !$lastOnlyDirective )
00943             {
00944                 $this->y = $this->y - $height;
00945                 $this->ez['xOffset'] = 0;
00946             }
00947             $lastOnlyDirective = false;
00948             while ( strlen( $line ) )
00949             {
00950                 $noClose = 1;
00951                 while ( $noClose )
00952                 {
00953                     $f = 1;
00954                     $directiveArray = $this->PRVTcheckTextDirective( $line, 0, $f );
00955                     $noClose = $directiveArray['noClose'];
00956                     if ( $noClose )
00957                     {
00958                         if ( $this->ez['xOffset'] != 0 )
00959                         {
00960                             $left = $this->ez['xOffset'];
00961                         }
00962                         else
00963                         {
00964                             $left = $this->leftMargin() + ( (is_array( $options ) && isset( $options['left'] ) ) ? $options['left'] : 0 );
00965                         }
00966 
00967                         $textInfo = $this->addText( $left, $this->y, $size, substr( $line, 0, $directiveArray['directive'] ), $angle, $adjust );
00968                         $line = substr( $line, $directiveArray['directive'] );
00969                         if ( isset( $textInfo['width'] ) && $textInfo['width'] != 0 )
00970                         {
00971                             $this->setXOffset( $left + $textInfo['width'] );
00972                         }
00973                     }
00974                 }
00975 
00976                 if ( $this->y < $this->ez['bottomMargin'] )
00977                 {
00978                     if ( $test )
00979                     {
00980                         $newPage = true;
00981                     }
00982                     else if ( strlen( trim( $line ) ) )
00983                     {
00984                         $this->ezNewPage();
00985                         // and then re-calc the left and right, in case they have changed due to columns
00986                     }
00987                 }
00988                 if ( $this->ez['xOffset'] != 0 )
00989                 {
00990                     $left = $this->ez['xOffset'];
00991                 }
00992                 else
00993                 {
00994                     $left = $this->leftMargin() + ( ( is_array( $options ) && isset( $options['left'] ) ) ? $options['left'] : 0 );
00995                 }
00996 
00997                 if ( is_array( $options ) && isset( $options['aleft'] ) )
00998                 {
00999                     $left=$options['aleft'];
01000                 }
01001                 if ( is_array( $options ) && isset( $options['aright'] ) )
01002                 {
01003                     $right = $options['aright'];
01004                 }
01005                 else
01006                 {
01007                     $right = $this->ez['pageWidth'] - $this->rightMargin() - ( ( is_array( $options ) && isset( $options['right'] ) ) ? $options['right'] : 0 );
01008                 }
01009 
01010                 $textInfo = $this->addTextWrap( $left, $this->y, $right - $left, $size, $line, $just, 0, $test );
01011                 if ( isset( $textInfo['only_directive'] ) &&
01012                      $textInfo['only_directive'] === true )
01013                 {
01014                     $lastOnlyDirective = true;
01015                     $line = '';
01016                     continue;
01017                 }
01018                 $line = $textInfo['text'];
01019                 if ( strlen( $line ) || $textInfo['width'] == 0 )
01020                 {
01021                     $this->y = $this->y - $height;
01022                     $this->ez['xOffset'] = 0;
01023                 }
01024                 else if ( $textInfo['width'] != 0 )
01025                 {
01026                     $this->setXOffset( $left + $textInfo['width'] );
01027                 }
01028             }
01029         }
01030 
01031         if ( $test )
01032         {
01033             $this->y = $store_y;
01034             return $newPage;
01035         }
01036         else
01037         {
01038             return $this->y;
01039         }
01040     }
01041 
01042 // ------------------------------------------------------------------------------
01043 
01044     function ezImage( $image, $pad = 5, $width = 0, $resize = 'full', $just = 'center', $border = '' )
01045     {
01046         // beta ezimage function
01047         if ( stristr( $image, '://' ) ) //copy to temp file
01048         {
01049             $fp = @fopen( $image, "rb" );
01050             while( !feof( $fp ) )
01051             {
01052                 $cont.= fread( $fp, 1024 );
01053             }
01054             fclose( $fp );
01055             $image = tempnam ( "/tmp", "php-pdf" );
01056             $fp2 = @fopen( $image, "w" );
01057             fwrite( $fp2, $cont );
01058             fclose( $fp2 );
01059             $temp = true;
01060         }
01061 
01062         if ( !( file_exists( $image ) ) )
01063             return false; // return immediately if image file does not exist
01064         $imageInfo = getimagesize( $image );
01065         switch ( $imageInfo[2] )
01066         {
01067             case 2:
01068                 $type = "jpeg";
01069                 break;
01070             case 3:
01071                 $type = "png";
01072                 break;
01073             default:
01074                 return false; // return if file is not jpg or png
01075         }
01076         if ( $width == 0 )
01077             $width = $imageInfo[0]; // set width
01078         $ratio = $imageInfo[0] / $imageInfo[1];
01079 
01080         //get maximum width of image
01081         if ( isset( $this->ez['columns'] ) && $this->ez['columns']['on'] == 1 )
01082         {
01083             $bigwidth = $this->ez['columns']['width'] - ( $pad * 2 );
01084         }
01085         else
01086         {
01087             $bigwidth = $this->ez['pageWidth'] - ( $pad * 2 );
01088         }
01089         //fix width if larger than maximum or if $resize=full
01090         if ( $resize == 'full' || $resize == 'width' || $width > $bigwidth )
01091         {
01092             $width = $bigwidth;
01093         }
01094 
01095         $height = ( $width / $ratio ); //set height
01096 
01097         //fix size if runs off page
01098         if ( $height > ( $this->y - $this->ez['bottomMargin'] - ( $pad * 2 ) ) )
01099         {
01100             if ( $resize != 'full' )
01101             {
01102                 $this->ezNewPage();
01103             }
01104             else
01105             {
01106                 $height = ( $this->y - $this->ez['bottomMargin'] - ( $pad * 2 ) ); // shrink height
01107                 $width = ( $height * $ratio ); // fix width
01108             }
01109         }
01110 
01111         // fix x-offset if image smaller than bigwidth
01112         if ( $width < $bigwidth )
01113         {
01114             // center if justification=center
01115             if ( $just == 'center' )
01116             {
01117                 $offset = ( $bigwidth - $width ) / 2;
01118             }
01119             //move to right if justification=right
01120             if ( $just == 'right' )
01121             {
01122                 $offset = ( $bigwidth - $width );
01123             }
01124             //leave at left if justification=left
01125             if ( $just == 'left' )
01126             {
01127                 $offset = 0;
01128             }
01129         }
01130 
01131 
01132         // call appropriate function
01133         if ( $type == "jpeg" )
01134         {
01135             $this->addJpegFromFile( $image, $this->leftMargin() + $pad + $offset, $this->y + $this->getFontHeight( $this->ez['fontSize'] ) - $pad - $height, $width );
01136         }
01137 
01138         if ( $type == "png" )
01139         {
01140             $this->addPngFromFile( $image, $this->leftMargin() + $pad + $offset, $this->y + $this->getFontHeight( $this->ez['fontSize'] ) - $pad - $height, $width );
01141         }
01142         //draw border
01143         if ( $border != '' )
01144         {
01145             if ( !( isset( $border['color'] ) ) )
01146             {
01147                 $border['color']['red'] = .5;
01148                 $border['color']['blue'] = .5;
01149                 $border['color']['green'] = .5;
01150             }
01151             if ( !( isset( $border['width'] ) ) )
01152                 $border['width'] = 1;
01153             if ( !( isset( $border['cap'] ) ) )
01154                 $border['cap'] = 'round';
01155             if ( !( isset( $border['join']) ) )
01156                 $border['join'] = 'round';
01157 
01158             $this->setStrokeColorRGB( $border['color']['red'], $border['color']['green'], $border['color']['blue'] );
01159             $this->setLineStyle( $border['width'], $border['cap'], $border['join'] );
01160             $this->rectangle( $this->leftMargin() + $pad + $offset, $this->y + $this->getFontHeight( $this->ez['fontSize'] ) - $pad - $height, $width, $height );
01161 
01162         }
01163         // move y below image
01164         $this->y = $this->y - $pad - $height;
01165         $this->ez['xOffset'] = 0;
01166         //remove tempfile for remote images
01167         if ( $temp == true )
01168             unlink( $image );
01169 
01170     }
01171 // ------------------------------------------------------------------------------
01172 
01173 // note that templating code is still considered developmental - have not really figured
01174 // out a good way of doing this yet.
01175     function loadTemplate( $templateFile )
01176     {
01177         // this function will load the requested template ($file includes full or relative pathname)
01178         // the code for the template will be modified to make it name safe, and then stored in
01179         // an array for later use
01180         // The id of the template will be returned for the user to operate on it later
01181         if ( !file_exists( $templateFile ) )
01182         {
01183             return -1;
01184         }
01185 
01186         $code = implode( '', file( $templateFile ) );
01187         if ( !strlen( $code ) )
01188         {
01189             return;
01190         }
01191 
01192         $code = trim( $code );
01193         if ( substr( $code, 0, 5 ) == '<?php' )
01194         {
01195             $code = substr( $code, 5 );
01196         }
01197         if ( substr( $code, -2 ) == '?>' )
01198         {
01199             $code = substr( $code, 0, strlen( $code ) - 2 );
01200         }
01201         if ( isset( $this->ez['numTemplates'] ) )
01202         {
01203             $newNum = $this->ez['numTemplates'];
01204             $this->ez['numTemplates']++;
01205         }
01206         else
01207         {
01208             $newNum = 0;
01209             $this->ez['numTemplates'] = 1;
01210             $this->ez['templates'] = array();
01211         }
01212 
01213         $this->ez['templates'][$newNum]['code'] = $code;
01214 
01215         return $newNum;
01216     }
01217 
01218 // ------------------------------------------------------------------------------
01219 
01220     function execTemplate( $id, $data = array(), $options = array() )
01221     {
01222         // execute the given template on the current document.
01223         if ( !isset( $this->ez['templates'][$id] ) )
01224         {
01225             return;
01226         }
01227         eval( $this->ez['templates'][$id]['code'] );
01228     }
01229 
01230 // ------------------------------------------------------------------------------
01231     function ilink( $info )
01232     {
01233         return $this->alink( $info, 1 );
01234     }
01235 
01236     function alink( $info, $internal = 0 )
01237     {
01238         // a callback function to support the formation of clickable links within the document
01239         $lineFactor = 0.05; // the thickness of the line as a proportion of the height. also the drop of the line.
01240         switch( $info['status'] )
01241         {
01242             case 'start':
01243             case 'sol':
01244                 // the beginning of the link
01245                 // this should contain the URl for the link as the 'p' entry, and will also contain the value of 'nCallback'
01246                 if (!isset($this->ez['links']))
01247                 {
01248                     $this->ez['links'] = array();
01249                 }
01250                 $i = $info['nCallback'];
01251 
01252                 $this->ez['links'][$i] = array( 'x' => $info['x'],
01253                                                 'y' => $info['y'],
01254                                                 'angle' => $info['angle'],
01255                                                 'decender' => $info['decender'],
01256                                                 'height' => $info['height'],
01257                                                 'url'=>rawurldecode( $info['p'] ) );
01258                 if ( $internal == 0 )
01259                 {
01260                     $this->saveState();
01261                     $this->setColorRGB( 0, 0, 1 );
01262                     $this->setStrokeColorRGB( 0, 0, 1 );
01263                     $thick = $info['height'] * $lineFactor;
01264                     $this->setLineStyle( $thick );
01265                 }
01266                 break;
01267             case 'end':
01268             case 'eol':
01269                 // the end of the link
01270                 // assume that it is the most recent opening which has closed
01271                 $i = $info['nCallback'];
01272                 $start = $this->ez['links'][$i];
01273                 // add underlining
01274                 if ($internal)
01275                 {
01276                     $this->addInternalLink( $start['url'], $start['x'], $start['y'] + $start['decender'], $info['x'], $start['y'] + $start['decender'] + $start['height'] );
01277                 }
01278                 else
01279                 {
01280                     $a = deg2rad( (float)$start['angle'] - 90.0 );
01281                     $drop = $start['height'] * $lineFactor * 1.5;
01282                     $dropx = cos( $a ) * $drop;
01283                     $dropy = -sin( $a ) * $drop;
01284                     $this->line( $start['x'] - $dropx, $start['y'] - $dropy, $info['x'] - $dropx, $info['y'] - $dropy );
01285                     $this->addLink( $start['url'], $start['x'], $start['y'] + $start['decender'], $info['x'], $start['y'] + $start['decender'] + $start['height'] );
01286                     $this->restoreState();
01287                 }
01288                 break;
01289         }
01290     }
01291 
01292 // ------------------------------------------------------------------------------
01293 
01294     function uline( $info )
01295     {
01296         // a callback function to support underlining
01297         $lineFactor = 0.05; // the thickness of the line as a proportion of the height. also the drop of the line.
01298         switch ( $info['status'] )
01299         {
01300             case 'start':
01301             case 'sol':
01302                 // the beginning of the underline zone
01303                 if ( !isset( $this->ez['links'] ) )
01304                 {
01305                     $this->ez['links'] = array();
01306                 }
01307                 $i = $info['nCallback'];
01308                 $this->ez['links'][$i] = array( 'x' => $info['x'],
01309                                                 'y' => $info['y'],
01310                                                 'angle' => $info['angle'],
01311                                                 'decender' => $info['decender'],
01312                                                 'height' => $info['height'] );
01313                 $this->saveState();
01314                 $thick = $info['height'] * $lineFactor;
01315                 $this->setLineStyle( $thick );
01316                 break;
01317 
01318             case 'end':
01319             case 'eol':
01320                 // the end of the link
01321                 // assume that it is the most recent opening which has closed
01322                 $i = $info['nCallback'];
01323                 $start = $this->ez['links'][$i];
01324                 // add underlining
01325                 $a = deg2rad( (float) $start['angle'] - 90.0 );
01326                 $drop = $start['height'] * $lineFactor * 1.5;
01327                 $dropx = cos( $a ) * $drop;
01328                 $dropy = -sin( $a ) * $drop;
01329                 $this->line( $start['x'] - $dropx, $start['y'] - $dropy, $info['x'] - $dropx, $info['y'] - $dropy );
01330                 $this->restoreState();
01331                 break;
01332         }
01333     }
01334 
01335 // ------------------------------------------------------------------------------
01336 // 2003-11-04 Kåre Køhler Høvik ( eZ Systems, http://ez.no )
01337 // Set fontsize
01338 
01339     function strike( $info )
01340     {
01341         // a callback function to support underlining
01342         $lineFactor = 0.05; // the thickness of the line as a proportion of the height. also the drop of the line.
01343         switch ( $info['status'] )
01344         {
01345             case 'start':
01346             case 'sol':
01347                 // the beginning of the underline zone
01348                 if ( !isset( $this->ez['links'] ) )
01349                 {
01350                     $this->ez['links'] = array();
01351                 }
01352                 $i = $info['nCallback'];
01353                 $this->ez['links'][$i] = array( 'x' => $info['x'],
01354                                                 'y' => $info['y'],
01355                                                 'angle' => $info['angle'],
01356                                                 'decender' => $info['decender'],
01357                                                 'height' => $info['height'] );
01358                 $this->saveState();
01359                 $thick = $info['height'] * $lineFactor;
01360                 $this->setLineStyle( $thick );
01361                 break;
01362 
01363             case 'end':
01364             case 'eol':
01365                 // the end of the link
01366                 // assume that it is the most recent opening which has closed
01367                 $i = $info['nCallback'];
01368                 $start = $this->ez['links'][$i];
01369                 // add underlining
01370                 $a = deg2rad( (float) $start['angle'] - 90.0 );
01371                 $drop = $start['height'] / 2;
01372                 $dropx = cos( $a ) * $drop;
01373                 $dropy = -sin( $a ) * $drop;
01374                 $this->line( $start['x'] - $dropx, $start['y'] + $dropy, $info['x'] - $dropx, $info['y'] + $dropy );
01375                 $this->restoreState();
01376                 break;
01377         }
01378     }
01379 
01380     /**
01381      * Get current line height
01382      */
01383     function lineHeight( $options = array() )
01384     {
01385         if ( is_array( $options ) && isset( $options['size'] ) )
01386         {
01387             $size = $options['size'];
01388         }
01389         else
01390         {
01391             $size = $this->ez['fontSize'];
01392         }
01393 
01394         if ( is_array( $options ) && isset( $options['leading'] ) )
01395         {   // use leading instead of spacing
01396             $height = $options['leading'];
01397         }
01398         else if ( is_array( $options ) && isset( $options['spacing'] ) )
01399         {
01400             $height = $this->getFontHeight( $size ) * $options['spacing'];
01401         }
01402         else
01403         {
01404             $height = $this->getFontHeight( $size );
01405         }
01406 
01407         return $height;
01408     }
01409 
01410     /*!
01411      Get right margin, page offset
01412 
01413      \param y offset ( optional )
01414      \return right margin
01415     */
01416     function rightMargin( $yOffset = false )
01417     {
01418         if ( $yOffset === false )
01419         {
01420             $yOffset = $this->yOffset();
01421         }
01422 
01423         foreach ( $this->RightMarginArray as $rightMargin )
01424         {
01425             if ( $yOffset > $rightMargin['start'] &&
01426                  $yOffset < $rightMargin['stop'] )
01427             {
01428                 return $rightMargin['margin'];
01429             }
01430         }
01431 
01432         return $this->ez['rightMargin'];
01433     }
01434 
01435     /*!
01436      Get left margin, page offset
01437 
01438      \param y offset ( optional )
01439      \return left margin
01440     */
01441     function leftMargin( $yOffset = false )
01442     {
01443         $maxMargin = $this->ez['leftMargin'];
01444 
01445         if ( $yOffset === false )
01446         {
01447             $yOffset = $this->yOffset();
01448         }
01449 
01450         foreach ( $this->LeftMarginArray as $leftMargin )
01451         {
01452             if ( $yOffset > $leftMargin['start'] &&
01453                  $yOffset < $leftMargin['stop']  &&
01454                  $leftMargin['margin'] > $maxMargin )
01455             {
01456                 $maxMargin = $leftMargin['margin'];
01457             }
01458         }
01459 
01460         return $maxMargin;
01461     }
01462 
01463     /*!
01464      Set left margin for limited range
01465 
01466      \param y start
01467      \param y stop
01468      \param new left margin
01469     */
01470     function setLimitedLeftMargin( $startY, $stopY, $leftMargin )
01471     {
01472         $this->LeftMarginArray[] = array( 'start' => $startY,
01473                                           'stop' => $stopY,
01474                                           'margin' => $leftMargin );
01475     }
01476 
01477     /*!
01478      Set right margin for limited range
01479 
01480      \param y start
01481      \param y stop
01482      \param new right margin
01483     */
01484     function setLimitedRightMargin( $startY, $stopY, $rightMargin )
01485     {
01486         $this->RightMarginArray[] = array( 'start' => $startY,
01487                                            'stop' => $stopY,
01488                                            'margin' => $rightMargin );
01489     }
01490 
01491     public $LeftMarginArray = array();
01492     public $RightMarginArray = array();
01493 }
01494 
01495 // ------------------------------------------------------------------------------
01496 
01497 
01498 ?>