|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZPDFTable class. 00004 * 00005 * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved. 00006 * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2 00007 * @version //autogentag// 00008 * @package lib 00009 */ 00010 00011 /*! 00012 \class eZPDFTable class.ezpdftable.php 00013 \ingroup eZPDF 00014 \brief eZPDFTable adds extra support for tables 00015 */ 00016 00017 class eZPDFTable extends Cezpdf 00018 { 00019 const NEWLINE = '<C:callNewLine>'; 00020 const SPACE = '<C:callSpace>'; 00021 const TAB = '<C:callTab>'; 00022 00023 const PAGENUM = '#page'; 00024 const TOTAL_PAGENUM = '#total'; 00025 const HEADER_LEVEL = '#level'; 00026 const HEADER_LEVEL_INDEX = '#indexLevel'; 00027 00028 /** 00029 Constructor. This class is only used to encapsulate a table. 00030 */ 00031 function eZPDFTable($paper='a4',$orientation='portrait') 00032 { 00033 $this->Cezpdf($paper, $orientation); 00034 $this->TOC = array(); 00035 $this->KeywordArray = array(); 00036 $this->PageCounter = array(); 00037 $this->initFrameMargins(); 00038 00039 $this->ez['textStack'] = array(); 00040 00041 $this->PreStack = array(); 00042 $this->DocSpecification = array(); 00043 $this->pushStack(); 00044 $this->FrontpageID = null; 00045 } 00046 00047 /*! 00048 * \private 00049 * Initialize footer and header frame margins. Called by constructor 00050 */ 00051 function initFrameMargins() 00052 { 00053 $this->ezFrame = array(); 00054 00055 $config = eZINI::instance( 'pdf.ini' ); 00056 00057 $this->ezFrame['header'] = array( 'y0' => $this->ez['pageHeight'], 00058 'leftMargin' => $config->variable( 'Header', 'LeftMargin' ), 00059 'rightMargin' => $config->variable( 'Header', 'RightMargin' ), 00060 'topMargin' => $config->variable( 'Header', 'TopMargin' ), 00061 'bottomMargin' => $config->variable( 'Header', 'BottomMargin' ) ); 00062 $this->ezFrame['footer'] = array( 'y0' => $this->ez['bottomMargin'], 00063 'leftMargin' => $config->variable( 'Footer', 'LeftMargin' ), 00064 'rightMargin' => $config->variable( 'Footer', 'RightMargin' ), 00065 'topMargin' => $config->variable( 'Footer', 'TopMargin' ), 00066 'bottomMargin' => $config->variable( 'Footer', 'BottomMargin' ) ); 00067 } 00068 00069 /** 00070 Get the current Y offset 00071 */ 00072 function yOffset() 00073 { 00074 return $this->y; 00075 } 00076 00077 /** 00078 Get the current X offset 00079 */ 00080 function xOffset() 00081 { 00082 $xOffset = $this->ez['xOffset']; 00083 if ( $xOffset == 0 || 00084 $this->leftMargin() > $this->ez['xOffset'] ) 00085 { 00086 $xOffset = $this->leftMargin(); 00087 } 00088 return $xOffset; 00089 } 00090 00091 function setYOffset( $yOffset ) 00092 { 00093 $this->y = $yOffset; 00094 } 00095 00096 function setXOffset( $xOffset ) 00097 { 00098 if ( $xOffset > $this->ez['pageWidth'] - $this->rightMargin() ) 00099 { 00100 $this->ez['xOffset'] = 0; 00101 } 00102 else 00103 { 00104 $this->ez['xOffset'] = $xOffset; 00105 } 00106 } 00107 00108 /*! 00109 * add a table of information to the pdf document 00110 * $data is a two dimensional array 00111 * $cols (optional) is an associative array, the keys are the names of the columns from $data 00112 * to be presented (and in that order), the values are the titles to be given to the columns 00113 * $title (optional) is the title to be put on the top of the table 00114 * 00115 * $options is an associative array which can contain: 00116 * 'cellData' => array( <coord> => array( 'size' => array( <width>, <height>), 00117 * 'justification' => <left|right|center> ), 00118 * <coord>....) 00119 * All non specified coords will be threated with default settings. Coord is text, offset 0, ex: '5,6' 00120 * Coord 'x,0' is table header 00121 * 'showLines'=> 0,1,2, default is 1 (show outside and top lines only), 2=> lines on each row 00122 * 'showHeadings' => 0 or 1 00123 * 'repeatTableHeader' => 0 or 1, if set to 1, the table header will be repeated when a table stretches over multiple pages. ( default 0 ) 00124 * 'shaded'=> 0,1,2,3 default is 1 (1->alternate lines are shaded, 0->no shading, 2-> both shaded, second uses shadeCol2) 00125 * 'shadeCol' => (CMYK) array, defining the colour of the shading 00126 * 'shadeCol2' => (CMYK) array, defining the colour of the shading of the other blocks 00127 * 'fontSize' => 10 00128 * 'textCol' => (CMYK) array, text colour 00129 * 'titleFontSize' => 12 00130 * 'rowGap' => 2 , the space added at the top and bottom of each row, between the text and the lines 00131 * 'colGap' => 5 , the space on the left and right sides of each cell 00132 * 'lineCol' => (r,g,b) array, defining the colour of the lines, default, black. 00133 * 'xPos' => 'left','right','center','centre',or coordinate, reference coordinate in the x-direction 00134 * 'xOrientation' => 'left','right','center','centre', position of the table w.r.t 'xPos' 00135 * 'width'=> <number> which will specify the width of the table, if it turns out to not be this 00136 * wide, then it will stretch the table to fit, if it is wider then each cell will be made 00137 * proportionalty smaller, and the content may have to wrap. 00138 * 'maxWidth'=> <number> similar to 'width', but will only make table smaller than it wants to be 00139 * 'options' => array(<colname>=>array('justification'=>'left','width'=>100,'link'=>linkDataName),<colname>=>....) 00140 * allow the setting of other paramaters for the individual columns 00141 * 'minRowSpace'=> the minimum space between the bottom of each row and the bottom margin, in which a new row will be started 00142 * if it is less, then a new page would be started, default=-100 00143 * 'innerLineThickness'=>1 00144 * 'outerLineThickness'=>1 00145 * 'splitRows'=>0, 0 or 1, whether or not to allow the rows to be split across page boundaries 00146 * 'protectRows'=>number, the number of rows to hold with the heading on page, ie, if there less than this number of 00147 * rows on the page, then move the whole lot onto the next page, default=1 00148 * 00149 * note that the user will have had to make a font selection already or this will not 00150 * produce a valid pdf file. 00151 */ 00152 function ezTable(&$data,$cols='',$title='',$options='') 00153 { 00154 if (!is_array($data)){ 00155 return; 00156 } 00157 00158 $tableStartY = $this->y; 00159 00160 // Get total column count and column indexes 00161 if (!is_array($cols)){ 00162 // take the columns from the first row of the data set 00163 reset($data); 00164 list($k,$v)=each($data); 00165 if (!is_array($v)){ 00166 return; 00167 } 00168 $cols=array(); 00169 00170 $realCount = 0; 00171 for ( $c = 0; $c < count($v); $c++ ) 00172 { 00173 if ( isset( $options['cellData'][$realCount.',0']['size'] ) ) 00174 { 00175 $incCount = $options['cellData'][$realCount.',0']['size']; 00176 for ( $innerCount = 0; $innerCount < $incCount; ++$innerCount ) 00177 { 00178 $cols[$realCount] = $realCount++; 00179 } 00180 } 00181 else 00182 { 00183 $cols[$realCount] = $realCount++; 00184 } 00185 } 00186 } 00187 00188 if (!is_array($options)){ 00189 $options=array(); 00190 } 00191 00192 $defaults = array( 00193 'cellPadding' => 0, 00194 'shaded' => 0, 00195 'showLines' => 1, 00196 'shadeCol' => eZMath::rgbToCMYK2( 0.8, 0.8, 0.8 ), 00197 'shadeCol2' => eZMath::rgbToCMYK2( 0.7, 0.7, 0.7 ), 00198 'repeatTableHeader' => 0, 00199 'fontSize' => 10, 00200 'titleFontSize' => 12, 00201 'titleGap' => 5, 00202 'lineCol' => array( 0, 0, 0 ), 00203 'gap' => 5, 00204 'xPos' => 'centre', 00205 'xOrientation' => 'centre', 00206 'showHeadings' => 1, 00207 'textCol' => eZMath::rgbToCMYK2( 0, 0, 0 ), 00208 'titleTextCMYK' => eZMath::rgbToCMYK2( 0, 0, 0 ), 00209 'width' => 0, 00210 'maxWidth' => 0, 00211 'cols' => array(), 00212 'minRowSpace' => -100, 00213 'rowGap' => 2, 00214 'colGap' => 5, 00215 'innerLineThickness' => 1, 00216 'outerLineThickness' => 1, 00217 'splitRows' => 0, 00218 'protectRows'=> 1, 00219 'firstRowTitle' => false, 00220 'titleFontSize' => 10, 00221 'test' => 0, 00222 'yBottom' => 0 ); 00223 00224 foreach($defaults as $key=>$value){ 00225 if (is_array($value)){ 00226 if (!isset($options[$key]) || !is_array($options[$key])){ 00227 $options[$key]=$value; 00228 } 00229 } else { 00230 if (!isset($options[$key])){ 00231 $options[$key]=$value; 00232 } 00233 } 00234 } 00235 $options['gap']=2*$options['colGap']; 00236 $middle = ($this->ez['pageWidth']- $this->rightMargin() - $this->leftMargin() )/2+$this->leftMargin(); 00237 // figure out the maximum widths of the text within each column 00238 $maxWidth = array(); 00239 $minWidth = array(); 00240 00241 $maxRowCount = 0; 00242 // find the maximum cell widths based on the data 00243 foreach ( $data as $rowCount=>$row) 00244 { 00245 $realColCount = 0; 00246 for( $columnCount = 0; $columnCount < count( $row ); $columnCount++ ) 00247 { 00248 $wMax = 0; // total maximum width of table column 00249 $wMix = 0; // minimum width of table column 00250 $data[$rowCount][$columnCount] = $this->fixupTableCellText( $row[$columnCount] ); 00251 $row[$columnCount] = $data[$rowCount][$columnCount]; 00252 // get col span 00253 $colSpan = 1; 00254 if ( isset( $options['cellData'][$realColCount.','.$rowCount]['size'] ) ) 00255 { 00256 $colSpan = $options['cellData'][$realColCount.','.$rowCount]['size']; 00257 } 00258 00259 //get and set max width 00260 if ( ( $rowCount == 0 && $options['firstRowTitle'] ) || 00261 ( isset( $options['cellData'][$realColCount.','.$rowCount]['title'] ) && $options['cellData'][$realColCount.','.$rowCount]['title'] ) ) 00262 { 00263 $wMax = $this->ezPrvtGetTextWidth( $options['titleFontSize'], (string)$row[$columnCount] ) * 1.01; 00264 $wMin = $this->eZGetMaxWordWidth( $options['titleFontSize'], (string)$row[$columnCount] ) * 1.01; 00265 $options['cellData'][$realColCount.','.$rowCount]['title'] = true; 00266 } 00267 else 00268 { 00269 $wMax = $this->ezPrvtGetTextWidth( $options['fontSize'], (string)$row[$columnCount] ) * 1.01; 00270 $wMin = $this->eZGetMaxWordWidth( $options['fontSize'], (string)$row[$columnCount] ) * 1.01; 00271 } 00272 00273 if ( isset( $maxWidth[$colSpan][$realColCount] ) ) 00274 { 00275 if ( $wMax > $maxWidth[$colSpan][$realColCount] ) 00276 { 00277 $maxWidth[$colSpan][$realColCount] = $wMax; 00278 } 00279 } 00280 else 00281 { 00282 if ( !isset( $maxWidth[$colSpan] ) ) 00283 { 00284 $maxWidth[$colSpan] = array(); 00285 } 00286 $maxWidth[$colSpan][$realColCount] = $wMax; 00287 } 00288 00289 if ( isset( $minWidth[$colSpan][$realColCount] ) ) 00290 { 00291 if ( $wMin > $minWidth[$colSpan][$realColCount] ) 00292 { 00293 $minWidth[$colSpan][$realColCount] = $wMin; 00294 } 00295 } 00296 else 00297 { 00298 if ( !isset( $minWidth[$colSpan] ) ) 00299 { 00300 $minWidth[$colSpan] = array(); 00301 } 00302 $minWidth[$colSpan][$realColCount] = $wMin; 00303 } 00304 00305 $realColCount += $colSpan; 00306 00307 if ( $realColCount > $maxRowCount ) 00308 { 00309 $maxRowCount = $realColCount; 00310 } 00311 } 00312 } 00313 00314 // calculate the start positions of each of the columns 00315 // Set pre defined max column width data 00316 for ( $columnCount = 0; $columnCount < count( $cols ); $columnCount++ ){ 00317 if ( isset( $options['cols'][$columnCount] ) && isset($options['cols'][$columnCount]['width']) && $options['cols'][$colName]['width']>0) 00318 { 00319 $colSpan = 1; 00320 if ( isset( $options['cellData'][$realColCount.',0']['size'] ) ) 00321 { 00322 $colSpan = $options['cellData'][$realColCount.',0']['size']; 00323 } 00324 00325 $maxWidth[$colSpan][$columnCount] = $options['cols'][$colName]['width'] - $options['gap'] - 2*$options['cellPadding']; 00326 } 00327 } 00328 00329 // Scale column widths 00330 $pos=array(); 00331 $columnWidths = array(); 00332 $minWidthArray = array(); 00333 for ( $offset = 0; $offset < count( $cols ); ++$offset ) 00334 { 00335 $columnWidths[$offset] = 0; 00336 $minWidthArray[$offset] = 0; 00337 } 00338 $x=0; 00339 $t=$x; 00340 $adjustmentWidth=0; 00341 $setWidth=0; 00342 foreach ( $maxWidth as $span => $tmp1 ) 00343 { 00344 foreach ( $maxWidth[$span] as $offset => $tmp2 ) 00345 { 00346 $currentWidth = 0; 00347 $currentMinWidth = 0; 00348 for ( $innerCount = 0; $innerCount < $span; $innerCount++ ) 00349 { 00350 $currentWidth += $columnWidths[$offset+$innerCount]; 00351 $currentMinWidth += $minWidthArray[$offset + $innerCount]; 00352 } 00353 if ( $maxWidth[$span][$offset] > $currentWidth ) 00354 { 00355 if ( $currentWidth == 0 ) // no width set 00356 { 00357 for ( $i = 0; $i < $span; $i++ ) 00358 { 00359 $columnWidths[$offset + $i] = ceil( $maxWidth[$span][$offset] / $span ); 00360 $minWidthArray[$offset + $i] = ceil( $minWidth[$span][$offset] / $span ); 00361 } 00362 } 00363 else // scale previous set widths 00364 { 00365 for ( $i = 0; $i < $span; $i++ ) 00366 { 00367 $columnWidths[$offset + $i] = ceil( $maxWidth[$span][$offset] / $currentWidth * $columnWidths[$offset+$i] ); 00368 $minWidthArray[$offset + $i] = ceil( $minWidth[$span][$offset] / $currentMinWidth * $minWidthArray[$offset+$i] ); 00369 } 00370 } 00371 } 00372 } 00373 } 00374 00375 $t = 0; 00376 foreach ( $columnWidths as $count => $width ) 00377 { 00378 $pos[$count]=$t; 00379 // if the column width has been specified then set that here, also total the 00380 $t += $width + $options['gap'] + 2*$options['cellPadding']; 00381 $adjustmentWidth += $width; 00382 $setWidth += $options['gap'] + 2*$options['cellPadding']; 00383 $pos[$count+1]=$t; 00384 } 00385 $pos['_end_'] = $t; 00386 00387 // if maxWidth is specified, and the table is too wide, and the width has not been set, 00388 // then set the width. 00389 if ($options['width']==0 && $options['maxWidth'] && $pos['_end_']>$options['maxWidth']){ 00390 // then need to make this one smaller 00391 $options['width']=$options['maxWidth']; 00392 } 00393 00394 // calculate total table width before limiting 00395 $totalTableWidth = 0; 00396 foreach ( array_keys( $columnWidths ) as $idx ){ 00397 $totalTableWidth += $columnWidths[$idx]; 00398 } 00399 00400 if ( $options['width'] == 0 && 00401 $totalTableWidth > $this->ez['pageWidth'] - $this->leftMargin() - $this->rightMargin() ) 00402 { 00403 $options['width'] = $this->ez['pageWidth'] - $this->leftMargin() - $this->rightMargin(); 00404 } 00405 00406 // calculated width as forced. Shrink or enlarge. 00407 $newColumnSize = $this->eZCalculateColumnWidth( $columnWidths, $options, $setWidth, $minWidthArray, $adjustmentWidth ); 00408 if ( $newColumnSize !== false ) 00409 { 00410 $pos = $newColumnSize; 00411 $t = $pos['_end_']; 00412 } 00413 00414 /* Calculate max column widths */ 00415 foreach ( array_keys ( $maxWidth ) as $colspan ) 00416 { 00417 foreach ( array_keys( $maxWidth[$colspan] ) as $offset ) 00418 { 00419 $maxWidth[$colspan][$offset] = 0; 00420 for ( $columnCount = $offset; $columnCount < $offset + $colspan; $columnCount ++ ) 00421 { 00422 if ( $maxWidth[$colspan][$offset] == 0 ) 00423 { 00424 $maxWidth[$colspan][$offset] -= ( $options['gap'] + 2*$options['cellPadding'] ); 00425 } 00426 $maxWidth[$colspan][$offset] += ( $pos[$columnCount + 1] - $pos[$columnCount] ); 00427 } 00428 } 00429 } 00430 00431 // now adjust the table to the correct location across the page 00432 switch ($options['xPos']){ 00433 case 'left': 00434 $xref = $this->leftMargin(); 00435 break; 00436 case 'right': 00437 $xref = $this->ez['pageWidth'] - $this->rightMargin(); 00438 break; 00439 case 'centre': 00440 case 'center': 00441 $xref = $middle; 00442 break; 00443 default: 00444 $xref = $options['xPos']; 00445 break; 00446 } 00447 switch ($options['xOrientation']){ 00448 case 'left': 00449 case 'right': 00450 $dx = $xref; 00451 break; 00452 case 'centre': 00453 case 'center': 00454 $dx = $xref-$t/2; 00455 break; 00456 } 00457 00458 foreach($pos as $key=>$value){ 00459 $pos[$key] += $dx + $options['gap']/2; 00460 } 00461 $x0=$x+$dx + $options['gap']/2; 00462 $x1=$t+$dx + $options['gap']/2; 00463 00464 $baseLeftMargin = $this->leftMargin(); 00465 $basePos = $pos; 00466 $baseX0 = $x0; 00467 $baseX1 = $x1; 00468 00469 // ok, just about ready to make me a table 00470 $this->setColor( $options['textCol'] ); 00471 00472 $middle = ($x1+$x0)/2; 00473 00474 // start a transaction which will be used to regress the table, if there are not enough rows protected 00475 if ($options['protectRows']>0){ 00476 $this->transaction('start'); 00477 $movedOnce=0; 00478 } 00479 $abortTable = 1; 00480 00481 if ( $options['yBottom'] > 0 ) // for aligning table to bottom 00482 { 00483 $options['test'] = 1; 00484 } 00485 00486 while ($abortTable){ 00487 $abortTable=0; 00488 00489 $dm = $this->ez['leftMargin']-$baseLeftMargin; 00490 foreach($basePos as $key=>$value){ 00491 $pos[$key] += $dm; 00492 } 00493 $x0=$baseX0+$dm; 00494 $x1=$baseX1+$dm; 00495 $middle = ($x1+$x0)/2; 00496 00497 // margins may have changed on the newpage 00498 $dm = $this->ez['leftMargin']-$baseLeftMargin; 00499 foreach($basePos as $key => $value){ 00500 $pos[$key] += $dm; 00501 } 00502 $x0=$baseX0+$dm; 00503 $x1=$baseX1+$dm; 00504 00505 $y=$this->y; // to simplify the code a bit 00506 $startY = $y; 00507 00508 // make the table 00509 $height = $this->getFontHeight($options['fontSize']); 00510 $decender = $this->getFontDecender($options['fontSize']); 00511 00512 $y0=$y+$decender; 00513 $dy=0; 00514 if ($options['showHeadings']){ 00515 // this function will move the start of the table to a new page if it does not fit on this one 00516 $headingHeight = $this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options); 00517 $y0 = $y+$headingHeight; 00518 $y1 = $y; 00519 00520 $dm = $this->leftMargin()-$baseLeftMargin; 00521 foreach($basePos as $k=>$v){ 00522 $pos[$k]=$v+$dm; 00523 } 00524 $x0=$baseX0+$dm; 00525 $x1=$baseX1+$dm; 00526 00527 } else { 00528 $y1 = $y0; 00529 } 00530 $firstLine=1; 00531 00532 00533 $isHelperObjectNeeded = ( !$options['test'] && ( $options['shaded'] || isset( $options['titleCellCMYK'] ) ) ); 00534 // open an object here so that the text can be put in over the shading 00535 if ( $isHelperObjectNeeded ){ 00536 $this->saveState(); 00537 $textObjectId = $this->openObject(); 00538 $this->closeObject(); 00539 $this->addObject($textObjectId); 00540 $this->reopenObject($textObjectId); 00541 } 00542 00543 $cnt=0; 00544 $newPage=0; 00545 $newPageLine = 0; 00546 $tableHeaderRow = array(); 00547 $maxRowCount = count( $data ); 00548 $oldRowCount = -1; 00549 00550 $leftOvers=array(); 00551 00552 for ( $rowCount = 0; $rowCount < $maxRowCount; ++$rowCount ) 00553 { 00554 if ( $oldRowCount != -1) 00555 { 00556 $rowCount = $oldRowCount; 00557 $oldRowCount = -1; 00558 } 00559 00560 $row = $data[$rowCount]; 00561 00562 $cnt++; 00563 // the transaction support will be used to prevent rows being split 00564 if ($options['splitRows']==0){ 00565 $pageStart = $this->ezPageCount; 00566 if (isset($this->ez['columns']) && $this->ez['columns']['on']==1){ 00567 $columnStart = $this->ez['columns']['colNum']; 00568 } 00569 if ( !$options['test'] ) 00570 { 00571 $this->transaction('start'); 00572 } 00573 $row_orig = $data[$rowCount]; 00574 $y_orig = $y; 00575 $y0_orig = $y0; 00576 $y1_orig = $y1; 00577 } 00578 $ok=0; 00579 $secondTurn=0; 00580 while(!$abortTable && $ok == 0){ 00581 00582 $maxRowHeight=0; 00583 $newRow=1; 00584 while(!$abortTable && ($newPage || $newRow)){ 00585 00586 $resetLeftOvers = true; 00587 if ( count( $leftOvers ) > 0 ) 00588 $row = $leftOvers; 00589 00590 if ($newPage || $y<$this->ez['bottomMargin'] || (isset($options['minRowSpace']) && $y<($this->ez['bottomMargin']+$options['minRowSpace'])) ){ 00591 // check that enough rows are with the heading 00592 if ($options['protectRows']>0 && $movedOnce==0 && $cnt<=$options['protectRows']){ 00593 // then we need to move the whole table onto the next page 00594 $movedOnce = 1; 00595 $abortTable = 1; 00596 } 00597 00598 $y2=$y-$maxRowHeight+2*$height+$decender-$newRow*$height; 00599 if ($options['showLines']){ 00600 if (!$options['showHeadings']){ 00601 $y0=$y1; 00602 } 00603 } 00604 if ( $isHelperObjectNeeded ) 00605 { 00606 $this->closeObject(); 00607 $this->restoreState(); 00608 } 00609 $this->ezNewPage(); 00610 // and the margins may have changed, this is due to the possibility of the columns being turned on 00611 // as the columns are managed by manipulating the margins 00612 00613 $dm = $this->leftMargin()-$baseLeftMargin; 00614 foreach($basePos as $k=>$v){ 00615 $pos[$k]=$v+$dm; 00616 } 00617 00618 $x0=$baseX0+$dm; 00619 $x1=$baseX1+$dm; 00620 00621 if ( $isHelperObjectNeeded ) 00622 { 00623 $this->saveState(); 00624 $textObjectId = $this->openObject(); 00625 $this->closeObject(); 00626 $this->addObject($textObjectId); 00627 $this->reopenObject($textObjectId); 00628 } 00629 $this->setColor( $options['textCol'], 1 ); 00630 $y = $this->ez['pageHeight']-$this->ez['topMargin']; 00631 $y0=$y+$decender; 00632 $maxRowHeight=0; 00633 if ($options['showHeadings']){ 00634 $this->ezPrvtTableColumnHeadings($cols,$pos,$maxWidth,$height,$decender,$options['rowGap'],$options['fontSize'],$y,$options); 00635 $y1=$y; 00636 } else { 00637 $y1=$y0; 00638 } 00639 $firstLine=1; 00640 $y -= $height; 00641 00642 if ( $options['repeatTableHeader'] && $oldRowCount == -1) 00643 { 00644 $oldRowCount = $rowCount; 00645 $rowCount = 0; 00646 $row = $data[$rowCount]; 00647 $resetLeftOvers = false; 00648 } 00649 } 00650 00651 $newRow=0; 00652 // write the actual data 00653 // if these cells need to be split over a page, then $newPage will be set, and the remaining 00654 // text will be placed in $leftOvers 00655 $newPage=0; 00656 if ( $resetLeftOvers ) 00657 $leftOvers=array(); 00658 00659 $realColumnCount = 0; 00660 00661 $bgTitleX = 2147483647; 00662 $bgTitleY = -2147483647; 00663 $bgTitleW = 0; 00664 $bgTitleH = 0; 00665 00666 for ( $columnCount = 0; $columnCount < count ( $row ); $columnCount++ ) 00667 { 00668 // Get colSpan 00669 if ( isset( $options['cellData'][$realColumnCount.','.$rowCount]['size'] ) ) 00670 { 00671 $colSpan = $options['cellData'][$realColumnCount.','.$rowCount]['size']; 00672 } 00673 else 00674 { 00675 $colSpan = 1; 00676 } 00677 00678 $this->ezSetY($y+$height); 00679 $colNewPage=0; 00680 00681 $row[$columnCount] = $this->fixWhitespace( $row[$columnCount] ); 00682 $lines = explode("\n",$row[$columnCount]); 00683 $this->y -= $options['rowGap'] + $options['cellPadding']; 00684 $this->setXOffset( $pos[$realColumnCount] ); 00685 $leftMargin = $this->ez['leftMargin']; 00686 $this->ez['leftMargin'] = $pos[$realColumnCount]; 00687 00688 foreach ($lines as $line) 00689 { 00690 $line = $this->ezProcessText($line); 00691 $start=1; 00692 00693 while (strlen($line) || $start){ 00694 $start=0; 00695 if (!$colNewPage){ 00696 $this->y-=$height; 00697 } 00698 if ($this->y < $this->ez['bottomMargin']){ 00699 $newPage=1; 00700 $newPageLine = 1; 00701 $colNewPage=1; 00702 } 00703 if ($colNewPage){ 00704 if (isset($leftOvers[$realColumnCount])){ 00705 $leftOvers[$realColumnCount].="\n".$line; 00706 } else { 00707 $leftOvers[$realColumnCount] = $line; 00708 } 00709 $line=''; 00710 } else { 00711 if (isset($options['cols'][$realColumnCount]) && isset($options['cols'][$realColumnCount]['justification']) ){ 00712 $just = $options['cols'][$realColumnCount]['justification']; 00713 } else { 00714 $just='left'; 00715 } 00716 $storeY = $this->y; 00717 if ( isset( $options['cellData'][$realColumnCount.','.$rowCount] ) && 00718 $options['cellData'][$realColumnCount.','.$rowCount]['title'] === true ) 00719 { 00720 $this->setColor( $options['titleTextCMYK'] ); 00721 $fontSize = $options['titleFontSize']; 00722 } 00723 else 00724 { 00725 $this->setColor( $options['textCol'], 1 ); 00726 $fontSize = $options['fontSize']; 00727 } 00728 00729 $textInfo = $this->addTextWrap( $pos[$realColumnCount], 00730 $this->y, 00731 $maxWidth[$colSpan][$realColumnCount], 00732 $fontSize, 00733 $line, 00734 $just, 00735 0, 00736 $options['test'] ); 00737 00738 $this->y = $storeY; 00739 if ( isset( $textInfo['text'] ) ) 00740 $line = $textInfo['text']; 00741 else 00742 $line = ''; 00743 00744 if ( $line == '' ) 00745 { 00746 if ( isset( $textInfo['height'] ) ) 00747 $this->y -= $textInfo['height']; 00748 } 00749 } 00750 } 00751 } 00752 $this->ez['leftMargin'] = $leftMargin; 00753 00754 $dy=$y-$this->y+$options['rowGap']+$options['cellPadding']; 00755 if ($dy>$maxRowHeight) 00756 { 00757 $maxRowHeight=$dy; 00758 } 00759 00760 ///////////////////////////////////////////////////////////////// 00761 // calc title's background rect 00762 ///////////////////////////////////////////////////////////////// 00763 if ( isset( $options['cellData'][$realColumnCount.','.$rowCount] ) && 00764 $options['cellData'][$realColumnCount.','.$rowCount]['title'] === true && 00765 isset( $options['titleCellCMYK'] ) ) 00766 { 00767 $cellX = $pos[$realColumnCount] - $options['gap']/2; 00768 $cellY = $y+$decender+$height; 00769 $cellW = $maxWidth[$colSpan][$realColumnCount] + $options['gap']; 00770 $cellH = -$maxRowHeight; 00771 00772 if ( $bgTitleX > $cellX ) 00773 $bgTitleX = $cellX; 00774 00775 if ( $bgTitleY < $cellY ) 00776 $bgTitleY = $cellY; 00777 00778 $bgTitleW += $cellW; 00779 00780 if ( $bgTitleH > $cellH ) 00781 $bgTitleH = $cellH; 00782 } 00783 ///////////////////////////////////////////////////////////////// 00784 00785 $realColumnCount += $colSpan; 00786 00787 } // End for ( ... count( $row ) ... ) 00788 00789 if ( !$options['test'] ) 00790 { 00791 //////////////////////////////////////////////////////////// 00792 // draw title's background 00793 //////////////////////////////////////////////////////////// 00794 if( $bgTitleW != 0 && $bgTitleH != 0 ) 00795 { 00796 // we have non-empty rect 00797 $this->closeObject(); 00798 $this->setColor( $options['titleCellCMYK'], true ); 00799 $this->filledRectangle( $bgTitleX, $bgTitleY, $bgTitleW, $bgTitleH ); 00800 $this->reopenObject($textObjectId); 00801 } 00802 //////////////////////////////////////////////////////////// 00803 00804 if ( isset( $options['cellData'][$realColumnCount.','.$rowCount] ) && 00805 $options['cellData'][$realColumnCount.','.$rowCount]['title'] === true ) 00806 { 00807 $shadeCol = $options['titleCellCMYK']; 00808 } 00809 else 00810 { 00811 if( $cnt % 2 == 0 ) 00812 { 00813 $shadeCol = $options['shadeCol']; 00814 } 00815 else 00816 { 00817 $shadeCol = $options['shadeCol2']; 00818 } 00819 } 00820 00821 $rowHeight = $maxRowHeight; 00822 $realColumnCount = 0; 00823 for ( $columnCount = 0; $realColumnCount < $maxRowCount; $columnCount++ ) 00824 { 00825 if ( isset( $options['cellData'][$realColumnCount.','.$rowCount]['size'] ) ) 00826 { 00827 $colSpan = $options['cellData'][$realColumnCount.','.$rowCount]['size']; 00828 } 00829 else 00830 { 00831 $colSpan = 1; 00832 } 00833 00834 if ( $options['shaded'] && $cnt % 2 == 0 ) 00835 { 00836 $this->closeObject(); 00837 $this->setColor( $shadeCol ); 00838 $this->filledRectangle($pos[$realColumnCount] - $options['cellPadding'], 00839 $y, 00840 $maxWidth[$colSpan][$realColumnCount] + 2*$options['cellPadding'], 00841 -$rowHeight ); 00842 $this->reopenObject($textObjectId); 00843 } 00844 00845 if ($options['shaded']==2 && $cnt%2==1){ 00846 $this->closeObject(); 00847 $this->setColor( $shadeCol ); 00848 $this->filledRectangle($pos[$realColumnCount] - $options['cellPadding'], 00849 $y, 00850 $maxWidth[$colSpan][$realColumnCount] + 2*$options['cellPadding'], 00851 -$rowHeight ); 00852 $this->reopenObject($textObjectId); 00853 } 00854 00855 $realColumnCount += $colSpan; 00856 } 00857 00858 // now add the shading underneath 00859 // Draw lines for each row and above 00860 if ( $options['showLines'] > 0 ) 00861 { 00862 $this->saveState(); 00863 $this->setStrokeColorRGB($options['lineCol'][0],$options['lineCol'][1],$options['lineCol'][2],1); 00864 00865 if ( $rowCount == 0 || $newPageLine == 1 ) 00866 { 00867 $this->line( $x0-$options['gap']/2, $y+$decender+$height, $x1-$options['gap']/2, $y+$decender+$height ); 00868 } 00869 $this->line( $x0-$options['gap']/2, $y+$decender+$height, $x0-$options['gap']/2, $y+$decender+$height-$maxRowHeight ); 00870 $this->line( $x1-$options['gap']/2, $y+$decender+$height, $x1-$options['gap']/2, $y+$decender+$height-$maxRowHeight ); 00871 00872 if ( $options['showLines'] > 1 ) 00873 { 00874 // draw inner lines 00875 $this->line( $x0-$options['gap']/2, $y+$decender+$height-$maxRowHeight, $x1-$options['gap']/2, $y+$decender+$height-$maxRowHeight ); 00876 00877 for ( $posOffset = 0; $posOffset < count( $pos ) - 2; ) 00878 { 00879 $colSpan = 1; 00880 if ( isset( $options['cellData'][$posOffset.','.$rowCount]['size'] ) ) 00881 { 00882 $colSpan = $options['cellData'][$posOffset.','.$rowCount]['size']; 00883 } 00884 $this->line( $pos[$posOffset+$colSpan]-$options['gap']/2, $y+$decender+$height, 00885 $pos[$posOffset+$colSpan]-$options['gap']/2, $y+$decender+$height-$maxRowHeight ); 00886 $posOffset += $colSpan; 00887 } 00888 } 00889 else if ( $rowCount == count( $data ) - 1 ) 00890 { 00891 $this->line( $x0-$options['gap']/2, $y+$decender+$height-$maxRowHeight, $x1-$options['gap']/2, $y+$decender+$height-$maxRowHeight ); 00892 } 00893 $this->restoreState(); 00894 } 00895 if ($options['showLines']>1){ 00896 $this->saveState(); 00897 $this->setStrokeColorRGB($options['lineCol'][0],$options['lineCol'][1],$options['lineCol'][2],1); 00898 00899 if ($firstLine){ 00900 $this->setLineStyle($options['outerLineThickness']); 00901 $firstLine=0; 00902 } else { 00903 $this->setLineStyle($options['innerLineThickness']); 00904 } 00905 $this->line($x0-$options['gap']/2,$y+$decender+$height-$maxRowHeight,$x1-$options['gap']/2,$y+$decender+$height-$maxRowHeight); 00906 $this->restoreState(); 00907 } 00908 } 00909 } // end of while 00910 $y=$y-$maxRowHeight; 00911 00912 // checking row split over pages 00913 if ( $options['splitRows'] == 0 ) 00914 { 00915 if ( ( ($this->ezPageCount != $pageStart) || (isset($this->ez['columns']) && $this->ez['columns']['on']==1 && $columnStart != $this->ez['columns']['colNum'] )) && $secondTurn==0){ 00916 // then we need to go back and try that again ! 00917 $newPage=1; 00918 $newPageLine = 1; 00919 $secondTurn=1; 00920 $this->transaction('rewind'); 00921 $row = $row_orig; 00922 $y = $y_orig; 00923 $y0 = $y0_orig; 00924 $y1 = $y1_orig; 00925 $ok=0; 00926 00927 $dm = $this->leftMargin()-$baseLeftMargin; 00928 foreach($basePos as $k=>$v){ 00929 $pos[$k]=$v+$dm; 00930 } 00931 $x0=$baseX0+$dm; 00932 $x1=$baseX1+$dm; 00933 00934 } else { 00935 $this->transaction('commit'); 00936 $ok=1; 00937 } 00938 } 00939 else 00940 { 00941 $ok=1; // don't go round the loop if splitting rows is allowed 00942 } 00943 00944 } // end of while to check for row splitting 00945 if ($abortTable){ 00946 if ($ok==0){ 00947 $this->transaction('abort'); 00948 } 00949 // only the outer transaction should be operational 00950 $this->transaction('rewind'); 00951 $this->ezNewPage(); 00952 break; 00953 } 00954 00955 } // end of ( ... $rowCount < $maxRowCount ... ) 00956 00957 if ( isset ( $options['yBottom'] ) && $options['yBottom'] > 0 ) 00958 { 00959 $tableHeight = $startY - $y; 00960 $this->y = $options['yBottom'] + $tableHeight; 00961 $yBottom = $options['yBottom']; 00962 unset( $options['yBottom'] ); 00963 $options['test'] = 0; 00964 $this->transaction('rewind'); 00965 // $this->transaction('start'); 00966 $abortTable = 1; 00967 continue; 00968 } 00969 00970 } // end of while ($abortTable) 00971 00972 // table has been put on the page, the rows guarded as required, commit. 00973 $this->transaction('commit'); 00974 00975 $y2=$y+$decender; 00976 if ($options['showLines']){ 00977 if (!$options['showHeadings']){ 00978 $y0=$y1; 00979 } 00980 // $this->ezPrvtTableDrawLines($pos,$options['gap'],$x0,$x1,$y0,$y1,$y2,$options['lineCol'],$options['innerLineThickness'],$options['outerLineThickness'],$options['showLines']); 00981 } 00982 00983 // close the object for drawing the text on top 00984 if ( $isHelperObjectNeeded ){ 00985 $this->closeObject(); 00986 $this->restoreState(); 00987 } 00988 00989 if ( $options['overwrite'] > 0 ) 00990 { 00991 $this->y=$tableStartY; 00992 } 00993 else 00994 { 00995 $this->y=$y; 00996 } 00997 00998 return $this->y; 00999 } 01000 01001 /*! 01002 \private 01003 Calculate Table column widths 01004 01005 \param ColumnWidth Array 01006 \param Table options 01007 \param Total Width 01008 \param Margin Width 01009 \param minimum Table width Array 01010 \param Position array ( for private use only ). 01011 \return Array of fixed column sizes ( returned ) 01012 */ 01013 function eZCalculateColumnWidth( $columnWidthArray, 01014 $options, 01015 $marginWidth, 01016 $minWidthArray, 01017 $totalWidth, 01018 $fixedSizeArray = array() ) 01019 { 01020 $newWidth = 0; 01021 if ( $options['width'] && $totalWidth>0 ){ 01022 $newCleanWidth = $options['width'] - $marginWidth; 01023 $t = 0; 01024 $pos = array(); 01025 foreach ( $columnWidthArray as $count => $width ) 01026 { 01027 $pos[$count] = $t; 01028 01029 if ( isset( $fixedSizeArray[(string)$count] ) ) 01030 { 01031 $t += $fixedSizeArray[(string)$count] + $options['gap'] + 2*$options['cellPadding']; 01032 continue; 01033 } 01034 01035 $newWidth = round( $newCleanWidth/$totalWidth * $columnWidthArray[$count] ); 01036 01037 if ( $newWidth < $minWidthArray[$count] && 01038 count( $fixedSizeArray ) < count( $columnWidthArray ) ) 01039 { 01040 $fixedSizeArray[(string)$count] = $minWidthArray[$count]; 01041 01042 return $this->eZCalculateColumnWidth( $columnWidthArray, 01043 $options, 01044 $marginWidth + $minWidthArray[$count], 01045 $minWidthArray, 01046 $totalWidth - $minWidthArray[$count], 01047 $fixedSizeArray ); 01048 } 01049 $t += $newWidth + $options['gap'] + 2*$options['cellPadding']; 01050 } 01051 $pos[]=$t; 01052 $pos['_end_']=$t; 01053 return $pos; 01054 } 01055 01056 return false; 01057 } 01058 01059 function ezPrvtTableDrawLines($pos,$gap,$x0,$x1,$y0,$y1,$y2,$col,$inner,$outer,$opt=1){ 01060 $x0=1000; 01061 $x1=0; 01062 $this->setStrokeColorRGB($col[0],$col[1],$col[2]); 01063 $cnt=0; 01064 $n = count($pos); 01065 foreach($pos as $x){ 01066 $cnt++; 01067 if ($cnt==1 || $cnt==$n){ 01068 $this->setLineStyle($outer); 01069 } else { 01070 $this->setLineStyle($inner); 01071 } 01072 $this->line($x-$gap/2,$y0,$x-$gap/2,$y2); 01073 if ($x>$x1){ $x1=$x; }; 01074 if ($x<$x0){ $x0=$x; }; 01075 } 01076 $this->setLineStyle($outer); 01077 $this->line($x0-$gap/2-$outer/2,$y0,$x1-$gap/2+$outer/2,$y0); 01078 // only do the second line if it is different to the first, AND each row does not have 01079 // a line on it. 01080 if ($y0!=$y1 && $opt<2){ 01081 $this->line($x0-$gap/2,$y1,$x1-$gap/2,$y1); 01082 } 01083 $this->line($x0-$gap/2-$outer/2,$y2,$x1-$gap/2+$outer/2,$y2); 01084 } 01085 01086 /** 01087 * Callback function to set anchor 01088 */ 01089 function callAnchor( $info ) 01090 { 01091 $paramArray = explode( ':', $info['p'] ); 01092 01093 $this->addDestination( $paramArray[0], $paramArray[1], $this->yOffset() + $this->getFontHeight( $this->fontSize ) ); 01094 } 01095 01096 /** 01097 * Callback function to set header 01098 */ 01099 function callHeader( $params ) 01100 { 01101 $options = array(); 01102 01103 if ( isset( $params['size'] ) ) 01104 { 01105 $options['fontSize'] = $params['size']; 01106 } 01107 01108 if ( isset( $params['justification'] ) ) 01109 { 01110 $options['justification'] = $params['justification']; 01111 } 01112 01113 if ( isset( $params['fontName'] ) ) 01114 { 01115 $options['fontName'] = 'lib/ezpdf/classes/fonts/'. $params['fontName']; 01116 } 01117 01118 $this->addToPreStack( $options ); 01119 01120 $label = $params['label']; 01121 $level = $params['level']; 01122 01123 return '<C:callInsertTOC:'. $label .','. $level .'>'; 01124 } 01125 01126 /** 01127 * Function for insert image 01128 */ 01129 function callImage( $info ) 01130 { 01131 $params = array(); 01132 $leftMargin = false; 01133 $rightMargin = false; 01134 01135 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01136 01137 $filename = rawurldecode( $params['src'] ); 01138 01139 $mimetype = eZMimeType::findByFileContents( $filename ); 01140 01141 $this->transaction( 'start' ); 01142 01143 if ( !isset( $params['static'] ) ) 01144 { 01145 $params['static'] = false; 01146 } 01147 01148 if ( $this->yOffset()-$params['height'] < $this->ez['bottomMargin'] ) 01149 { 01150 $this->ezNewPage(); 01151 } 01152 01153 if ( isset( $params['dpi'] ) ) 01154 { 01155 $newWidth = (int)( $params['width'] * ( (int)$params['dpi'] / 72 ) ); 01156 $newHeight = (int)( $params['height'] * ( (int)$params['dpi'] / 72 ) ); 01157 $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg'; 01158 while( file_exists( $newFilename ) ) 01159 { 01160 $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg'; 01161 } 01162 01163 $img = eZImageManager::factory(); 01164 $newImg = $img->convert( $filename, 01165 $newFilename, 01166 false, 01167 array( 'filters' => array( array( 'name' => 'geometry/scaledownonly', 01168 'data' => array( $newWidth, $newHeight ) ) ) ) ); 01169 $filename = $newFilename['url']; 01170 } 01171 01172 $drawableAreaWidth = $this->ez['pageWidth'] - $this->ez['leftMargin'] - $this->ez['rightMargin']; 01173 01174 switch( $params['align'] ) 01175 { 01176 case 'right': 01177 { 01178 $xOffset = $this->ez['pageWidth'] - ( $this->rightMargin() + $params['width'] ); 01179 $rightMargin = $this->rightMargin() + $params['width']; 01180 if ( $rightMargin > ( $drawableAreaWidth + $this->rightMargin() ) ) 01181 { 01182 // the image is equal or larger then width of the page(of the drawable area) => no point 01183 // to set $rightMargin and next object(text, image, ...) should be outputted below the image. 01184 $rightMargin = false; 01185 } 01186 } break; 01187 01188 case 'center': 01189 { 01190 $xOffset = ( $this->ez['pageWidth'] - $this->rightMargin() - $this->leftMargin() ) / 2 + $this->leftMargin() - $params['width'] / 2; 01191 } break; 01192 01193 case 'left': 01194 default: 01195 { 01196 $xOffset = $this->leftMargin(); 01197 $leftMargin = $this->leftMargin() + $params['width']; 01198 if ( $leftMargin > ( $drawableAreaWidth + $this->leftMargin() ) ) 01199 { 01200 // the image is equal or larger then width of the page(of the drawable area) => no point 01201 // to set $leftMargin and next object(text, image, ...) should be outputted below the image. 01202 $leftMargin = false; 01203 } 01204 01205 } break; 01206 } 01207 01208 if ( isset( $params['x'] ) ) 01209 { 01210 $xOffset = $params['x']; 01211 $leftMargin = false; 01212 $rightMargin = false; 01213 } 01214 01215 $yOffset = $this->yOffset(); 01216 $whileCount = 0; 01217 01218 if ( $params['width'] < $drawableAreaWidth ) 01219 { 01220 while ( $this->leftMargin( $yOffset ) > $xOffset && 01221 ++$whileCount < 100 ) 01222 { 01223 $yOffset -= 10; 01224 } 01225 } 01226 01227 $yOffset -= $params['height']; 01228 $yOffset += $this->lineHeight()/2; 01229 if ( isset( $params['y'] ) ) 01230 { 01231 $yOffset = $params['y']; 01232 } 01233 01234 if ( $leftMargin !== false ) 01235 { 01236 $this->setLimitedLeftMargin( $yOffset - 7, $yOffset + $params['height'] + 7, $leftMargin + 7 ); 01237 } 01238 if ( $rightMargin !== false ) 01239 { 01240 $this->setLimitedRightMargin( $yOffset- 7, $yOffset + $params['height'] + 7, $rightMargin + 7 ); 01241 } 01242 01243 switch( $mimetype['name'] ) 01244 { 01245 case 'image/gif': 01246 { 01247 $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg'; 01248 while( file_exists( $newFilename ) ) 01249 { 01250 $newFilename = eZSys::cacheDirectory() . '/' . md5( mt_rand() ) . '.jpg'; 01251 } 01252 $newMimetype = eZMimeType::findByURL( $newFilename ); 01253 01254 $img = eZImageManager::factory(); 01255 $newImg = $img->convert( $mimetype, 01256 $newMimetype, 01257 false, 01258 array() ); 01259 $this->addJpegFromFile( $newMimetype['url'], 01260 $xOffset, 01261 $yOffset, 01262 $params['width'], 01263 $params['height'] ); 01264 } break; 01265 01266 case 'image/jpeg': 01267 { 01268 $this->addJpegFromFile( $filename, 01269 $xOffset, 01270 $yOffset, 01271 $params['width'], 01272 $params['height'] ); 01273 } break; 01274 01275 case 'image/png': 01276 { 01277 if ( $this->addPngFromFile( $filename, 01278 $xOffset, 01279 $yOffset, 01280 $params['width'], 01281 $params['height'] ) === false ) 01282 { 01283 $this->transaction('abort'); 01284 return; 01285 } 01286 } break; 01287 01288 default: 01289 { 01290 eZDebug::writeError( 'Unsupported image file type, '. $mimetype['name'], __METHOD__ ); 01291 $this->transaction( 'abort' ); 01292 return; 01293 } break; 01294 } 01295 01296 $this->transaction( 'commit' ); 01297 01298 if ( !$leftMargin && !$rightMargin && !$params['static'] ) 01299 { 01300 $this->y -= $params['height'] + $this->lineHeight(); 01301 } 01302 01303 return array( 'y' => $params['height'] + $this->lineHeight() ); 01304 } 01305 01306 01307 /** 01308 * function for inserting keyword 01309 */ 01310 function callKeyword( $info ) 01311 { 01312 $keyWord = $this->fixWhitespace( rawurldecode( $info['p'] ) ); 01313 $page = $this->ezWhatPageNumber($this->ezGetCurrentPageNumber()); 01314 01315 if ( !isset( $this->KeywordArray[$keyWord] ) ) 01316 { 01317 $this->KeywordArray[$keyWord] = array(); 01318 } 01319 01320 if ( !isset( $this->KeywordArray[$keyWord][(string)$page] ) ) 01321 { 01322 $label = $info['p'] .':'. $page; 01323 $this->KeywordArray[$keyWord][(string)$page] = array( 'label' => $label ); 01324 01325 $this->addDestination( 'keyword:'.$label, 01326 'FitH', 01327 $this->yOffset() ); 01328 } 01329 } 01330 01331 /** 01332 * function for inserting TOC 01333 */ 01334 function callInsertTOC( $info ) 01335 { 01336 $params = explode( ',', $info['p'] ); 01337 01338 $label = $params[0]; 01339 $level = $params[1]; 01340 01341 $tocCount = count( $this->TOC ); 01342 $this->TOC[] = array( 'label' => $this->fixWhitespace( rawurldecode( $label ) ), 01343 'localPageNumber' => $this->ezWhatPageNumber( $this->ezGetCurrentPageNumber() ), 01344 'level' => $level, 01345 'pageNumber' => $this->ezGetCurrentPageNumber() ); 01346 $this->addDestination( 'toc'. $tocCount, 01347 'FitH', 01348 $this->yOffset() + $this->getFontHeight( $this->fontSize() ) ); 01349 } 01350 01351 /** 01352 * Callback function for inserting TOC 01353 */ 01354 function callTOC( $info ) 01355 { 01356 $params = array(); 01357 01358 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01359 01360 $sizes = isset( $params['size'] ) ? explode( ',', $params['size'] ) : ''; 01361 $indents = isset( $params['indent'] ) ? explode( ',', $params['indent'] ) : ''; 01362 $dots = isset( $params['dots'] ) ? $params['dots'] : ''; 01363 $contentText = isset( $params['contentText'] ) ? $params['contentText'] : ezpI18n::tr( 'lib/ezpdf/classes', 'Contents', 'Table of contents' ); 01364 01365 $this->insertTOC( $sizes, $indents, $dots, $contentText ); 01366 } 01367 01368 /** 01369 * Callback function for creating new page 01370 */ 01371 function callNewPage( $info ) 01372 { 01373 $this->ezNewPage(); 01374 } 01375 01376 function callIndex( $info ) 01377 { 01378 $this->ezNewPage(); 01379 $fontSize = $this->fontSize(); 01380 Cezpdf::ezText( ezpI18n::tr( 'lib/ezpdf/classes', 'Index', 'Keyword index name' ) . '<C:callInsertTOC:Index,1>'."\n", 26, array('justification'=>'centre')); 01381 01382 if ( count( $this->KeywordArray ) == 0 ) 01383 return; 01384 01385 ksort( $this->KeywordArray ); 01386 reset( $this->KeywordArray ); 01387 01388 $this->ezColumnsStart( array( 'num' => 2 ) ); 01389 01390 foreach( array_keys( $this->KeywordArray ) as $keyWord ) 01391 { 01392 Cezpdf::ezText( $keyWord, 01393 $fontSize, 01394 array( 'justification' => 'left' ) ); 01395 01396 foreach( array_keys( $this->KeywordArray[$keyWord] ) as $page ) 01397 { 01398 Cezpdf::ezText( '<c:ilink:keyword:'. $this->KeywordArray[$keyWord][$page]['label'] .'> '. $page .'</c:ilink>', 01399 $fontSize, 01400 array( 'justification' => 'right' ) ); 01401 } 01402 } 01403 01404 $this->ezColumnsStop(); 01405 $this->setFontSize( $fontSize ); 01406 } 01407 01408 /*! 01409 Create Table Of Contents (TOC) 01410 01411 \param size array, element 0 define size of header level 1, etc. 01412 \param indent, element 0 define indent of header level 1, etc. 01413 \param dots, if true, generate dots between name and pagenumber 01414 \param content text 01415 \param level, how many header levels to generate toc form 01416 */ 01417 function insertTOC( $sizeArray = array( 20, 18, 16, 14, 12 ), 01418 $indentArray = array( 0, 4, 6, 8, 10 ), 01419 $dots = true, 01420 $contentText = '', 01421 $level = 3 ) 01422 { 01423 $fontSize = $this->fontSize(); 01424 $this->ezStopPageNumbers(1,1); 01425 01426 $this->ezInsertMode(1,1,'before'); 01427 $this->ezNewPage(); 01428 Cezpdf::ezText( $contentText ."\n", 26, array('justification'=>'centre')); 01429 01430 foreach($this->TOC as $k=>$v){ 01431 if ( $v['level'] <= $level ) 01432 { 01433 if ( $dots ) 01434 { 01435 Cezpdf::ezText( '<c:ilink:toc'. $k .'>'. $v['label'] .'</c:ilink>', 01436 $sizeArray[$v['level']-1], 01437 array( 'left' => $indentArray[$v['level']-1], 01438 'right' => 100 ) ); 01439 Cezpdf::ezText( '<C:dots:'. $sizeArray[$v['level']-1].$v['localPageNumber'] .'>', 01440 $sizeArray[$v['level']-1] ); 01441 Cezpdf::ezText( "\n", $sizeArray[$v['level']-1] ); 01442 } 01443 else 01444 { 01445 Cezpdf::ezText( '<c:ilink:toc'. $k .'>'.$v['label'].'</c:ilink>', 01446 $sizeArray[$v['level']-1], 01447 array( 'left' => $indentArray[$v['level']-1] ) ); 01448 Cezpdf::ezText( '<c:ilink:toc'. $k .'>'. $v['localPageNumber'] .'</c:ilink>', 01449 $sizeArray[$v['level']-1], 01450 array( 'justification' => 'right' ) ); 01451 } 01452 } 01453 } 01454 01455 $this->setFontSize( $fontSize ); 01456 $this->ezInsertMode(0); 01457 } 01458 01459 function dots($info) 01460 { 01461 // draw a dotted line over to the right and put on a page number 01462 $tmp = $info['p']; 01463 $size = substr($tmp, 0, 2); 01464 $thick=1; 01465 $lbl = substr($tmp,2); 01466 $xpos = $this->ez['pageWidth'] - $this->rightMargin() - $this->leftMargin(); 01467 01468 $this->saveState(); 01469 $this->setLineStyle($thick,'round','',array(0,10)); 01470 $this->line($xpos,$info['y'],$info['x']+5,$info['y']); 01471 $this->restoreState(); 01472 $this->addText($xpos+5,$info['y'],$size,$lbl); 01473 $this->setXOffset( $xpos+5+$this->getTextWidth($lbl, $size) ); 01474 } 01475 01476 /** 01477 * Callback function to set font 01478 */ 01479 function callFont( $params ) 01480 { 01481 $options = array(); 01482 01483 $keyArray = array ( 'c', 'm', 'y', 'k' ); 01484 if ( isset( $params['cmyk'] ) ) 01485 { 01486 $params['cmyk'] = explode( ',', $params['cmyk'] ); 01487 foreach ( array_keys( $params['cmyk'] ) as $key ) 01488 { 01489 $options['cmyk'][$keyArray[$key]] = $params['cmyk'][$key]; 01490 } 01491 $this->setStrokeColor( $params['cmyk'] ); 01492 } 01493 01494 if ( isset( $params['name'] ) ) 01495 { 01496 $options['fontName'] = 'lib/ezpdf/classes/fonts/'. $params['name']; 01497 } 01498 01499 if ( isset( $params['size'] ) ) 01500 { 01501 $options['fontSize'] = $params['size']; 01502 } 01503 01504 if ( isset( $params['justification'] ) ) 01505 { 01506 $options['justification'] = $params['justification']; 01507 } 01508 01509 $this->addToPreStack( $options ); 01510 01511 return ''; 01512 } 01513 01514 function &fixWhitespace( &$text ) 01515 { 01516 $text = str_replace( array( self::SPACE, 01517 self::TAB, 01518 self::NEWLINE ), 01519 array( ' ', 01520 "\t", 01521 "\n" ), 01522 $text ); 01523 return $text; 01524 } 01525 01526 /** 01527 * Function overriding the default ezText function for doing preprocessing of text 01528 */ 01529 function ezText( $text, $size=0, $options=array(), $test=0) 01530 { 01531 $text = eZPDFTable::fixWhitespace( $text ); 01532 01533 $textLen = strlen( $text ); 01534 $newText = ''; 01535 for ( $offSet = 0; $offSet < $textLen; $offSet++ ) 01536 { 01537 if ( $text[$offSet] == '<' ) 01538 { 01539 if ( strcmp( substr($text, $offSet+1, strlen( 'ezCall' ) ), 'ezCall' ) == 0 ) // ez library preprocessing call. 01540 { 01541 $newTextLength = strlen( $newText ); 01542 if ( $newTextLength > 0 && $newText[$newTextLength - 1] == "\n" ) 01543 { 01544 $newText = rtrim( $newText, "\n" ); 01545 $this->addDocSpecification( $newText ); 01546 $newText = "\n"; 01547 } 01548 else 01549 { 01550 $this->addDocSpecification( $newText ); 01551 $newText = ''; 01552 } 01553 01554 $params = array(); 01555 $funcName = ''; 01556 01557 $offSet = eZPDFTable::extractFunction( $text, $offSet, $funcName, $params, 'ezCall' ); 01558 01559 $newText .= $this->$funcName( $params ); 01560 01561 continue; 01562 } 01563 else if ( strcmp( substr($text, $offSet+1, strlen( '/ezCall' ) ), '/ezCall' ) == 0 ) 01564 { 01565 $this->addDocSpecification( $newText ); 01566 array_pop( $this->PreStack ); 01567 $offSet = strpos( $text, '>', $offSet ); 01568 $newText = ''; 01569 continue; 01570 } 01571 else if ( strcmp( substr($text, $offSet+1, strlen( 'ezGroup' ) ), 'ezGroup' ) == 0 ) // special call for processing whole text group, used by extends table. 01572 { 01573 $newTextLength = strlen( $newText ); 01574 if ( $newTextLength > 0 && $newText[$newTextLength - 1] == "\n" ) 01575 { 01576 $newText = rtrim( $newText, "\n" ); 01577 $this->addDocSpecification( $newText ); 01578 $newText = "\n"; 01579 } 01580 else 01581 { 01582 $this->addDocSpecification( $newText ); 01583 $newText = ''; 01584 } 01585 01586 $params = array(); 01587 $funcName = ''; 01588 01589 $offSet = eZPDFTable::extractFunction( $text, $offSet, $funcName, $params, 'ezGroup' ); 01590 $offSet++; 01591 $endGroup = strpos( $text, '</ezGroup:', $offSet ); 01592 $groupText = substr( $text, $offSet, $endGroup - $offSet ); 01593 $groupText = urldecode( $groupText ); 01594 01595 $this->$funcName( $params, $groupText ); 01596 01597 $offSet = strpos( $text, '>', $endGroup ); 01598 continue; 01599 } 01600 } 01601 $newText .= $text[$offSet]; 01602 } 01603 if ( strlen( $newText ) > 0 ) 01604 { 01605 $this->addDocSpecification( $newText ); 01606 } 01607 01608 $this->outputDocSpecification(); 01609 } 01610 01611 /*! 01612 \private 01613 Fixup table cell text. Removes ezCall tags, and first C:callNewLine if they exists. 01614 01615 \param text 01616 01617 \return text without ezgroup/ezcall tags 01618 */ 01619 function fixupTableCellText( $text ) 01620 { 01621 $text = preg_replace( "/^" . self::NEWLINE . "/i", "", $text ); 01622 $text = preg_replace( "/" . self::NEWLINE . "$/i", "", $text ); 01623 return preg_replace( "'<[\/]*?ezCall:[^<>]*?>'si", "", $text ); 01624 } 01625 01626 /*! 01627 Function for drawing rectangle in document 01628 01629 \param parameters 01630 */ 01631 function callRectangle( $info ) 01632 { 01633 $params = array(); 01634 01635 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01636 01637 $keyArray = array ( 'c', 'm', 'y', 'k' ); 01638 $cmykColor = explode( ',', $params['cmyk'] ); 01639 01640 foreach ( array_keys( $cmykColor ) as $key ) 01641 { 01642 $cmykColor[$keyArray[$key]] = $cmykColor[$key]; 01643 unset( $cmykColor[$key] ); 01644 } 01645 01646 $stackColor = $this->currentStrokeColour; 01647 $this->setStrokeColor( $cmykColor ); 01648 01649 if ( isset( $params['x'] ) ) 01650 { 01651 $x1 = $params['x']; 01652 $x2 = $x1 + $params['width']; 01653 } 01654 if ( isset( $params['y'] ) ) 01655 { 01656 $y1 = $params['y']; 01657 $y2 = $y1 + $params['height']; 01658 } 01659 01660 if ( isset( $params['topY'] ) ) 01661 { 01662 $y2 = $params['topY']; 01663 if ( $params['height'] > 0 ) 01664 { 01665 $y1 = $params['topY'] - $params['height']; 01666 } 01667 else 01668 { 01669 $y1 = $this->yOffset() + $params['height']; 01670 } 01671 } 01672 01673 $this->setLineStyle( $params['line_width'] ); 01674 01675 if ( $params['corner'] ) 01676 { 01677 $factor = $params['corner']; 01678 $degree = 0; 01679 01680 $this->line( $x1 + $factor, $y1, $x2 - $factor, $y1 ); 01681 $this->line( $x2, $y1 + $factor, $x2, $y2 - $factor ); 01682 $this->line( $x2 - $factor, $y2, $x1 + $factor, $y2 ); 01683 $this->line( $x1, $y2 - $factor, $x1, $y1 + $factor ); 01684 01685 $this->curve( $x2 - $factor, $y1, 01686 $x2, $y1 - $degree * $factor, 01687 $x2 + $degree * $factor, $y1, 01688 $x2, $y1 + $factor ); 01689 $this->curve( $x2, $y2 - $factor, 01690 $x2 + $degree * $factor, $y2, 01691 $x2, $y2 + $degree * $factor, 01692 $x2 - $factor, $y2 ); 01693 $this->curve( $x1 + $factor, $y2, 01694 $x1, $y2 + $degree * $factor, 01695 $x1 - $degree * $factor, $y2, 01696 $x1, $y2 - $factor ); 01697 $this->curve( $x1, $y1 + $factor, 01698 $x1 - $degree * $factor, $y1, 01699 $x1, $y1 - $degree * $factor, 01700 $x1 + $factor, $y1 ); 01701 } 01702 else 01703 { 01704 $this->rectangle( $x1, $y1, $params['width'], $params['height'] ); 01705 } 01706 01707 $this->setColor( $stackColor ); 01708 } 01709 01710 /*! 01711 Set new margins 01712 */ 01713 function callSetMargin( $info ) 01714 { 01715 $options = array(); 01716 01717 eZPDFTable::extractParameters( $info['p'], 0, $options, true ); 01718 01719 if ( isset( $options['left'] ) ) 01720 { 01721 $this->ez['leftMargin'] = (float)$options['left']; 01722 } 01723 01724 if ( isset( $options['delta_left'] ) ) 01725 { 01726 $this->ez['leftMargin'] += $options['delta_left']; 01727 } 01728 01729 if ( isset( $options['right'] ) ) 01730 { 01731 $this->ez['rightMargin'] = (float)$options['right']; 01732 } 01733 01734 if ( isset( $options['delta_right'] ) ) 01735 { 01736 $this->ez['rightMargin'] += $options['delta_right']; 01737 } 01738 01739 if ( isset( $options['bottom'] ) ) 01740 { 01741 $this->ez['bottomMargin'] = (float)$options['bottom']; 01742 } 01743 01744 if ( isset( $options['line_space'] ) ) 01745 { 01746 $this->ez['lineSpace'] = (float)$options['line_space']; 01747 } 01748 01749 if ( isset( $options['top'] ) ) 01750 { 01751 $this->ez['topMargin'] = (float)$options['top']; 01752 if ( $this->yOffset() < $this->ez['topMargin'] ) 01753 { 01754 $this->ez['yOffset'] = (float)$options['y']; 01755 $this->y = (float)$options['y']; 01756 } 01757 } 01758 01759 if ( isset( $options['x'] ) ) 01760 { 01761 $this->setXOffset( (float)$options['x'] ); 01762 } 01763 01764 if ( isset( $options['y'] ) ) 01765 { 01766 $this->ez['yOffset'] = (float)$options['y']; 01767 $this->y = (float)$options['y']; 01768 } 01769 01770 return array( 'x' => $this->xOffset() ); 01771 } 01772 01773 /*! 01774 Draw filled circle 01775 */ 01776 function callCircle( $info ) 01777 { 01778 $params = array(); 01779 $forceYPos = true; 01780 01781 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01782 01783 $keyArray = array ( 'c', 'm', 'y', 'k' ); 01784 $cmykColor = explode( ',', $params['cmyk'] ); 01785 01786 foreach ( array_keys( $cmykColor ) as $key ) 01787 { 01788 $cmykColor[$keyArray[$key]] = $cmykColor[$key]; 01789 unset( $cmykColor[$key] ); 01790 } 01791 01792 $strokeStackColor = $this->currentStrokeColour; 01793 $this->setStrokeColor( $cmykColor ); 01794 $stackColor = $this->currentColour; 01795 $this->setColor( $cmykColor ); 01796 01797 if ( $params['x'] == -1 ) 01798 { 01799 $params['x'] = $this->xOffset() + $params['radius']; 01800 } 01801 if ( $params['y'] == -1 ) 01802 { 01803 $forceYPos = false; 01804 $params['y'] = $this->yOffset(); 01805 } 01806 if ( isset( $params['yOffset'] ) ) 01807 { 01808 if ( $params['yOffset'] == -1 ) 01809 { 01810 $params['y'] += $this->getFontHeight( $this->fontSize() )/2 - $params['radius']; 01811 } 01812 else 01813 { 01814 $params['y'] += $params['yOffset']; 01815 } 01816 } 01817 01818 if ( $params['y'] - $this->getFontHeight( $this->fontSize() ) < $this->ez['bottomMargin'] && 01819 !$forceYPos ) 01820 { 01821 $this->ezNewPage(); 01822 return $this->callCircle( $info ); 01823 } 01824 01825 $params['x'] += $params['pre_indent']; 01826 01827 $this->filledEllipse( $params['x'], $params['y'], $params['radius'] ); 01828 01829 $this->setStrokeColor( $strokeStackColor ); 01830 $this->setColor( $stackColor ); 01831 01832 if ( isset( $params['indent'] ) ) 01833 { 01834 return array( 'x' => $params['x'] + $params['radius'] * 2 + $params['indent'] ); 01835 } 01836 else 01837 { 01838 return array( 'x' => $params['x'] + $params['radius'] * 2 ); 01839 } 01840 01841 } 01842 01843 /*! 01844 Function for drawing filled rectangle in document 01845 01846 \param params 01847 */ 01848 function callFilledRectangle( $info ) 01849 { 01850 $params = array(); 01851 01852 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01853 01854 $keyArray = array ( 'c', 'm', 'y', 'k' ); 01855 $cmykTop = explode( ',', $params['cmykTop'] ); 01856 $cmykBottom = explode( ',', $params['cmykBottom'] ); 01857 01858 foreach ( array_keys( $cmykBottom ) as $key ) 01859 { 01860 $cmykBottom[$keyArray[$key]] = $cmykBottom[$key]; 01861 unset( $cmykBottom[$key] ); 01862 $cmykTop[$keyArray[$key]] = $cmykTop[$key]; 01863 unset( $cmykTop[$key] ); 01864 } 01865 01866 $this->ezShadedRectangle( $params['x'], $params['y'], $params['width'], $params['height'], $cmykTop, $cmykBottom ); 01867 } 01868 01869 /*! 01870 Function for adding footer definition to PDF document. creates call on stack for ezInsertFooter 01871 01872 \param parameters 01873 \text inside ezGroup Tags 01874 */ 01875 function callBlockFrame( $params, $text ) 01876 { 01877 if ( strlen( $text ) > 0 ) 01878 { 01879 $this->addDocSpecFunction( 'ezInsertBlockFrame', array( $text, $params) ); 01880 } 01881 } 01882 01883 /*! 01884 Function for adding footer definition to PDF document. creates call on stack for ezInsertFooter 01885 01886 \param parameters 01887 \text inside ezGroup Tags 01888 */ 01889 function callFrame( $params, $text ) 01890 { 01891 if ( strlen( $text ) > 0 ) 01892 { 01893 $this->addDocSpecFunction( 'ezInsertFrame', array( $this->fixWhitespace( $text ), $params) ); 01894 } 01895 } 01896 01897 /*! 01898 Add line to all pages 01899 */ 01900 function callLine( $params, $text ) 01901 { 01902 $this->addDocSpecFunction( 'ezInsertLine', array( $params ) ); 01903 } 01904 01905 /*! 01906 Draw line on current page in PDF document 01907 */ 01908 function callDrawLine( $info ) 01909 { 01910 $params = array(); 01911 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01912 01913 $this->setLineStyle( $params['thickness'] ); 01914 $this->line( $params['x1'], $params['y1'], $params['x2'], $params['y2'] ); 01915 } 01916 01917 /*! 01918 Function for setting frame margins. Frames are used to define for example footer and header areas 01919 01920 \param info, standard ezpdf callback function 01921 */ 01922 function callFrameMargins( $info ) 01923 { 01924 $params = array(); 01925 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 01926 01927 if( isset( $this->ezFrame[$params['identifier']] ) ) 01928 { 01929 $this->ezFrame[$params['identifier']] = array_merge( $this->ezFrame[$params['identifier']], 01930 $params ); 01931 } 01932 else 01933 { 01934 $this->ezFrame[$params['identifier']] = $params; 01935 } 01936 } 01937 01938 /*! 01939 Insert line onto every page 01940 01941 \param line parameters 01942 */ 01943 function ezInsertLine( $params ) 01944 { 01945 reset( $this->ezPages ); 01946 foreach ( $this->ezPages as $pageNum => $pageID ) 01947 { 01948 $this->reopenObject($pageID); 01949 $this->line( $params['x1'], $params['y1'], $params['x2'], $params['y2'] ); 01950 $this->closeObject(); 01951 } 01952 reset( $this->ezPages ); 01953 } 01954 01955 /*! 01956 Insert footer/header into PDF document 01957 01958 \param text 01959 \param text parameters 01960 */ 01961 function ezInsertBlockFrame( $text, $textParameters ) 01962 { 01963 $header = false; 01964 switch( $textParameters['location'] ) 01965 { 01966 case 'footer_block': 01967 { 01968 $frameCoords = $this->ezFrame['footer']; 01969 } break; 01970 01971 case 'header_block': 01972 { 01973 $header = true; 01974 $frameCoords = $this->ezFrame['header']; 01975 } break; 01976 } 01977 01978 $text = str_replace( array( ' ', "\t", "\r\n", "\n" ), 01979 '', 01980 urldecode( $text ) ); 01981 01982 foreach ( $this->ezPages as $pageNum => $pageID ) 01983 { 01984 $this->pushStack(); 01985 01986 if ( $header ) 01987 { 01988 foreach( $frameCoords as $key => $value ) 01989 { 01990 $this->ez[$key] = $value; 01991 } 01992 $this->setYOffset( $this->ez['pageHeight'] - $this->ez['topMargin'] ); 01993 } 01994 else 01995 { 01996 $this->ez['topMargin'] = $this->ez['pageHeight'] - $this->ez['bottomMargin'] + $frameCoords['topMargin']; 01997 foreach( $frameCoords as $key => $value ) 01998 { 01999 if ( $key != 'topMargin' ) 02000 { 02001 $this->ez[$key] = $value; 02002 } 02003 } 02004 } 02005 02006 $this->setXOffset( 0 ); 02007 02008 $frameText = $text; //Create copy of text 02009 if( $textParameters['page'] == 'even' && 02010 $pageNum % 2 == 1 ) 02011 continue; 02012 else if ( $textParameters['page'] == 'odd' && 02013 $pageNum % 2 == 0 ) 02014 continue; 02015 02016 if ( strstr( $frameText, self::PAGENUM ) !== false ) 02017 { 02018 foreach ( array_keys( $this->PageCounter ) as $identifier ) 02019 { 02020 if ( $this->PageCounter[$identifier]['start'] <= $pageNum && 02021 $this->PageCounter[$identifier]['stop'] >= $pageNum ) 02022 { 02023 $frameText = str_replace( self::PAGENUM, 02024 $this->ezWhatPageNumber( $pageNum, $identifier ), 02025 $frameText ); 02026 02027 if ( strstr( $frameText, self::TOTAL_PAGENUM ) !== false ) 02028 { 02029 $frameText = str_replace( self::TOTAL_PAGENUM, 02030 $this->PageCounter[$identifier]['stop'] - $this->PageCounter[$identifier]['start'] + 1, 02031 $frameText ); 02032 } 02033 } 02034 } 02035 } 02036 02037 for( $levelCount = 0; $levelCount < 9; $levelCount++ ) 02038 { 02039 if ( strstr( $frameText, self::HEADER_LEVEL.$levelCount ) !== false ) 02040 { 02041 $frameText = str_replace( self::HEADER_LEVEL.$levelCount, 02042 $this->headerLabel( $pageNum, $levelCount ), 02043 $frameText ); 02044 } 02045 02046 if ( strstr( $frameText, self::HEADER_LEVEL_INDEX.$levelCount ) !== false ) 02047 { 02048 $frameText = str_replace( self::HEADER_LEVEL_INDEX.$levelCount, 02049 $this->headerIndex( $pageNum, $levelCount ), 02050 $frameText ); 02051 } 02052 } 02053 02054 $this->reopenObject($pageID); 02055 $this->ezText( $frameText ); 02056 $this->closeObject(); 02057 $this->popStack(); 02058 } 02059 } 02060 02061 /*! 02062 Insert footer/header into PDF document 02063 02064 \param text 02065 \param text parameters 02066 */ 02067 function ezInsertFrame( $text, $textParameters ) 02068 { 02069 $size = $this->fontSize(); 02070 if ( isset( $textParameters['size'] ) ) 02071 { 02072 $size = $textParameters['size']; 02073 } 02074 02075 $previousFont = $this->currentFont(); 02076 if ( isset( $textParameters['font'] ) ) 02077 { 02078 $this->selectFont( $textParameters['font'] ); 02079 } 02080 02081 $justification = $this->justification(); 02082 if ( isset( $textParameters['justification'] ) ) 02083 { 02084 $justification = $textParameters['justification']; 02085 } 02086 02087 switch( $textParameters['location'] ) 02088 { 02089 case 'footer': 02090 { 02091 $frameCoords =& $this->ezFrame['footer']; 02092 } break; 02093 02094 case 'frame_header': 02095 { 02096 $frameCoords =& $this->ezFrame['header']; 02097 } break; 02098 02099 default: 02100 { 02101 $frameCoords =& $this->ezFrame[0]; 02102 } break; 02103 } 02104 02105 foreach ( $this->ezPages as $pageNum => $pageID ) 02106 { 02107 if ( $pageNum < $textParameters['pageOffset'] ) 02108 continue; 02109 02110 $frameText = $text; //Create copy of text 02111 if( $textParameters['page'] == 'even' && 02112 $pageNum % 2 == 1 ) 02113 continue; 02114 else if ( $textParameters['page'] == 'odd' && 02115 $pageNum % 2 == 0 ) 02116 continue; 02117 02118 $countIdentifier = ''; 02119 if ( strstr( $frameText, self::PAGENUM ) !== false ) 02120 { 02121 foreach ( array_keys( $this->PageCounter ) as $identifier ) 02122 { 02123 if ( $this->PageCounter[$identifier]['start'] <= $pageNum && 02124 $this->PageCounter[$identifier]['stop'] >= $pageNum ) 02125 { 02126 $frameText = str_replace( self::PAGENUM, 02127 $this->ezWhatPageNumber( $pageNum, $identifier ), 02128 $frameText ); 02129 02130 if ( strstr( $frameText, self::TOTAL_PAGENUM ) !== false ) 02131 { 02132 $frameText = str_replace( self::TOTAL_PAGENUM, 02133 $this->PageCounter[$identifier]['stop'] - $this->PageCounter[$identifier]['start'] + 1, 02134 $frameText ); 02135 } 02136 } 02137 } 02138 } 02139 02140 for( $levelCount = 0; $levelCount < 9; $levelCount++ ) 02141 { 02142 if ( strstr( $frameText, self::HEADER_LEVEL.$levelCount ) !== false ) 02143 { 02144 $frameText = str_replace( self::HEADER_LEVEL.$levelCount, 02145 $this->headerLabel( $pageNum, $levelCount ), 02146 $frameText ); 02147 } 02148 02149 if ( strstr( $frameText, self::HEADER_LEVEL_INDEX.$levelCount ) !== false ) 02150 { 02151 $frameText = str_replace( self::HEADER_LEVEL_INDEX.$levelCount, 02152 $this->headerIndex( $pageNum, $levelCount ), 02153 $frameText ); 02154 } 02155 } 02156 02157 $yOffset = $frameCoords['y0'] - $frameCoords['topMargin']; 02158 if ( $textParameters['newline'] ) 02159 { 02160 $yOffset -= $this->getFontHeight( $size ); 02161 } 02162 02163 $yOffset -= $this->getFontHeight( $size ); 02164 $xOffset = $frameCoords['leftMargin']; 02165 $pageWidth = $this->ez['pageWidth'] - $frameCoords['leftMargin'] - $frameCoords['rightMargin']; 02166 02167 $this->reopenObject($pageID); 02168 02169 $lines = explode( "\n", $frameText ); 02170 foreach ( array_keys( $lines ) as $key ) 02171 { 02172 $start=1; 02173 $line = $lines[$key]; 02174 while (strlen($line) || $start){ 02175 $start = 0; 02176 $textInfo = $this->addTextWrap( $xOffset, $yOffset, $pageWidth, $size, $line, $justification ); 02177 $line = $textInfo['text']; 02178 02179 if ( strlen( $line ) ) 02180 { 02181 $yOffset -= $this->getFontHeight( $size ); 02182 } 02183 } 02184 } 02185 02186 $this->closeObject(); 02187 } 02188 02189 $this->selectFont( $previousFont ); 02190 } 02191 02192 /*! 02193 * Function for inserting frontpage into document. Called by ezGroup specification 02194 * 02195 * \param parameters 02196 * \param text in ezGroup 02197 */ 02198 function callFrontpage( $params, $text ) 02199 { 02200 $this->addDocSpecFunction( 'insertFrontpage', array( $params, $text ) ); 02201 } 02202 02203 /*! 02204 * Insert front page 02205 */ 02206 function insertFrontpage( $params, $text ) 02207 { 02208 $this->saveState(); 02209 $closeObject = false; 02210 if ( $this->FrontpageID == null ) 02211 { 02212 $this->ezInsertMode(1,1,'before'); 02213 $this->ezNewPage(); 02214 $this->FrontpageID = $this->currentPage; 02215 } 02216 else if( $this->currentPage != $this->FrontpageID ) 02217 { 02218 $this->reopenObject( $this->FrontpageID ); 02219 $closeObject = true; 02220 } 02221 02222 $fontSize = $this->fontSize(); 02223 02224 $text = $this->fixWhitespace( $text ); 02225 $this->setXOffset( 0 ); 02226 02227 Cezpdf::ezText( $text, $params['size'], array( 'justification' => $params['justification'], 02228 'top_margin' => $params['top_margin'] ) ); 02229 02230 $this->setFontSize( $fontSize ); 02231 02232 if ( $closeObject ) 02233 { 02234 $this->closeObject(); 02235 } 02236 $this->restoreState(); 02237 } 02238 02239 /*! 02240 * Function for generating table definition. Called by ezGroup specification 02241 * 02242 * \param parameters 02243 * \param text in ezGroup 02244 */ 02245 function callTable( $params, $text ) 02246 { 02247 $textLen = strlen( $text ); 02248 $tableData = array(); 02249 $cellData = array(); 02250 $showLines = 2; 02251 $rowCount = 0; 02252 $columnCount = 0; 02253 02254 $columnText = ''; 02255 02256 $keyArray = array ( 'c', 'm', 'y', 'k' ); 02257 if ( isset( $params['titleCellCMYK'] ) ) 02258 { 02259 $params['titleCellCMYK'] = explode( ',', $params['titleCellCMYK'] ); 02260 foreach ( array_keys( $params['titleCellCMYK'] ) as $key ) 02261 { 02262 $params['titleCellCMYK'][$keyArray[$key]] = $params['titleCellCMYK'][$key]; 02263 unset( $params['titleCellCMYK'][$key] ); 02264 } 02265 } 02266 02267 if ( isset( $params['cellCMYK'] ) ) 02268 { 02269 $params['cellCMYK'] = explode( ',', $params['cellCMYK'] ); 02270 foreach ( array_keys( $params['cellCMYK'] ) as $key ) 02271 { 02272 $params['cellCMYK'][$keyArray[$key]] = $params['cellCMYK'][$key]; 02273 unset( $params['cellCMYK'][$key] ); 02274 } 02275 $params['shaded'] = 2; 02276 $params['shadeCol'] = $params['cellCMYK']; 02277 $params['shadeCol2'] = $params['cellCMYK']; 02278 } 02279 02280 if ( isset( $params['textCMYK'] ) ) 02281 { 02282 $params['textCMYK'] = explode( ',', $params['textCMYK'] ); 02283 foreach ( array_keys( $params['textCMYK'] ) as $key ) 02284 { 02285 $params['textCMYK'][$keyArray[$key]] = $params['textCMYK'][$key]; 02286 unset( $params['textCMYK'][$key] ); 02287 } 02288 $params['textCol'] = $params['textCMYK']; 02289 } 02290 02291 if ( isset( $params['titleTextCMYK'] ) ) 02292 { 02293 $params['titleTextCMYK'] = explode( ',', $params['titleTextCMYK'] ); 02294 foreach ( array_keys( $params['titleTextCMYK'] ) as $key ) 02295 { 02296 $params['titleTextCMYK'][$keyArray[$key]] = $params['titleTextCMYK'][$key]; 02297 unset( $params['titleTextCMYK'][$key] ); 02298 } 02299 $params['titleTextCMYK'] = $params['titleTextCMYK']; 02300 } 02301 02302 if ( isset( $params['showLines'] ) ) 02303 { 02304 $showLines = $params['showLines']; 02305 } 02306 02307 for ( $offSet = 0; $offSet < $textLen; $offSet++ ) 02308 { 02309 if ( $text[$offSet] == '<' ) 02310 { 02311 if ( strcmp( substr($text, $offSet+1, strlen( 'tr' ) ), 'tr' ) == 0 ) 02312 { 02313 $tableData[] = array(); 02314 $offSet++; 02315 $offSet += strlen( 'tr' ); 02316 continue; 02317 } 02318 else if ( strcmp( substr($text, $offSet+1, strlen( 'td' ) ), 'td' ) == 0 ) 02319 { 02320 $tdParams = array(); 02321 $offSet++; 02322 $offSet += strlen( 'td' ); 02323 $offSet = eZPDFTable::extractParameters( $text, $offSet, $tdParams ); 02324 02325 if ( count( $tdParams ) > 0 ) 02326 { 02327 $cellData[$columnCount. ',' .$rowCount] = array(); 02328 if ( isset( $tdParams['colspan'] ) ) 02329 { 02330 $cellData[$columnCount. ',' .$rowCount]['size'] = (int)$tdParams['colspan']; 02331 } 02332 if ( isset( $tdParams['align'] ) ) 02333 { 02334 $cellData[$columnCount. ',' .$rowCount]['justification'] = $tdParams['align']; 02335 } 02336 if ( isset( $tdParams['width'] ) ) 02337 { 02338 $cellData[$columnCount. ',' .$rowCount]['width'] = $tdParams['width']; 02339 } 02340 } 02341 continue; 02342 } 02343 else if ( strcmp( substr($text, $offSet+1, strlen( 'th' ) ), 'th' ) == 0 ) 02344 { 02345 $thParams = array(); 02346 $offSet++; 02347 $offSet += strlen( 'th' ); 02348 $offSet = eZPDFTable::extractParameters( $text, $offSet, $thParams ); 02349 02350 $cellData[$columnCount. ',' .$rowCount] = array(); 02351 $cellData[$columnCount.','.$rowCount]['title'] = true; 02352 if ( isset( $thParams['colspan'] ) ) 02353 { 02354 $cellData[$columnCount. ',' .$rowCount]['size'] = (int)$thParams['colspan']; 02355 } 02356 if ( isset( $thParams['align'] ) ) 02357 { 02358 $cellData[$columnCount. ',' .$rowCount]['justification'] = $thParams['align']; 02359 } 02360 if ( isset( $thParams['width'] ) ) 02361 { 02362 $cellData[$columnCount. ',' .$rowCount]['width'] = $thParams['width']; 02363 } 02364 continue; 02365 } 02366 else if ( strcmp( substr($text, $offSet+1, strlen( '/tr' ) ), '/tr' ) == 0 ) 02367 { 02368 $rowCount++; 02369 $columnCount = 0; 02370 $offSet++; 02371 $offSet += strlen( '/tr' ); 02372 continue; 02373 } 02374 else if ( strcmp( substr($text, $offSet+1, strlen( '/td' ) ), '/td' ) == 0 ) 02375 { 02376 if ( $columnCount == 0 ) 02377 { 02378 $tableData[$rowCount] = array(); 02379 } 02380 $tableData[$rowCount][$columnCount] = $columnText; 02381 $columnText = ''; 02382 $columnCount++; 02383 $offSet++; 02384 $offSet += strlen( '/td' ); 02385 continue; 02386 } 02387 else if ( strcmp( substr($text, $offSet+1, strlen( '/th' ) ), '/th' ) == 0 ) 02388 { 02389 if ( $columnCount == 0 ) 02390 { 02391 $tableData[$rowCount] = array(); 02392 } 02393 $tableData[$rowCount][$columnCount] = $columnText; 02394 $columnText = ''; 02395 $columnCount++; 02396 $offSet++; 02397 $offSet += strlen( '/th' ); 02398 continue; 02399 } 02400 } 02401 $columnText .= $text[$offSet]; 02402 } 02403 $this->addDocSpecFunction( 'ezTable', array( &$tableData, '', '', array_merge( array( 'cellData' => $cellData, 02404 'showLines' => $showLines ), 02405 $params ) ) ); 02406 } 02407 02408 /** 02409 * Function for extracting function name and parameters from text. 02410 * 02411 * \param text 02412 * \param offset 02413 * \param function name (reference) 02414 * \param parameters array (reference) 02415 * 02416 * \return end offset of function 02417 */ 02418 function extractFunction( &$text, $offSet, &$functionName, &$parameters, $type='ezCall' ) 02419 { 02420 $offSet++; 02421 $offSet += strlen( $type.':' ); 02422 $funcEnd = strpos( $text, ':', $offSet ); 02423 if ( $funcEnd === false || strpos( $text, '>', $offSet ) < $funcEnd ) 02424 { 02425 $funcEnd = strpos( $text, '>', $offSet ); 02426 } 02427 $functionName = substr( $text, $offSet, $funcEnd - $offSet ); 02428 02429 return eZPDFTable::extractParameters( $text, $funcEnd, $parameters ); 02430 } 02431 02432 /** 02433 * Function for extracting parameters from : separated key:value list callback functions 02434 * 02435 * \param text 02436 * \param offset 02437 * \param parameters array (reference) 02438 * 02439 * \return end offset of function 02440 */ 02441 function extractParameters( &$text, $offSet, &$parameters, $skipFirstChar=false ) 02442 { 02443 $endOffset = strpos( $text, '>', $offSet ); 02444 if ( $endOffset === false ) 02445 { 02446 $endOffset = strlen( $text ); 02447 } 02448 02449 if ( $skipFirstChar === false ) 02450 $offSet++; 02451 while ( $offSet < $endOffset ) 02452 { 02453 $nameEnd = strpos( $text, ':', $offSet ); 02454 $valueEnd = strpos( $text, ':', $nameEnd+1 ); 02455 if ( $valueEnd > $endOffset || $valueEnd === false ) 02456 { 02457 $valueEnd = $endOffset; 02458 } 02459 $paramName = substr( $text, $offSet, $nameEnd-$offSet); 02460 ++$nameEnd; 02461 $paramValue = substr( $text, $nameEnd, $valueEnd-$nameEnd ); 02462 $parameters[$paramName] = $paramValue; 02463 $offSet = ++$valueEnd; 02464 } 02465 02466 return $endOffset; 02467 } 02468 02469 /** 02470 Loop through all document specification settings and print specified text 02471 02472 \return new Y offset 02473 */ 02474 function outputDocSpecification() 02475 { 02476 foreach( array_keys( $this->DocSpecification ) as $key ) 02477 { 02478 $outputElement =& $this->DocSpecification[$key]; 02479 02480 $documentSpec =& $outputElement['docSpec']; 02481 02482 if ( isset( $documentSpec['fontName'] ) ) 02483 { 02484 $this->selectFont( $documentSpec['fontName'] ); 02485 } 02486 02487 if ( isset( $documentSpec['fontSize'] ) ) 02488 { 02489 $size = $documentSpec['fontSize']; 02490 } 02491 else 02492 { 02493 $size = $this->fontSize(); 02494 } 02495 02496 if ( isset( $documentSpec['cmyk'] ) ) 02497 { 02498 $this->setColor( $documentSpec['cmyk'] ); 02499 } 02500 02501 if ( isset( $outputElement['isFunction'] ) && $outputElement['isFunction'] === true ) 02502 { 02503 $return = call_user_func_array( array( &$this, $outputElement['functionName'] ), $outputElement['parameters'] ); 02504 } 02505 else 02506 { 02507 $return = Cezpdf::ezText( $outputElement['text'], 02508 $size, 02509 array( 'justification' => $documentSpec['justification'] ) ); 02510 } 02511 } 02512 return $return; 02513 } 02514 02515 /*! 02516 Insert text at specified position 02517 */ 02518 function callTextBox( $params, $text ) 02519 { 02520 $this->addDocSpecFunction( 'insertTextBox', array( $params, $text ) ); 02521 } 02522 02523 function insertTextBox( $params, $text ) 02524 { 02525 $this->pushStack(); 02526 02527 $this->setYOffset( $params['y'] ); 02528 $this->setXOffset( $params['x'] ); 02529 02530 $marginText = '<C:callSetMargin'; 02531 $marginText .= ':left:' . ( $params['x'] ); 02532 $marginText .= ':right:' . ( $this->ez['pageWidth'] - $params['width'] - $params['x'] ); 02533 $marginText .= '>'; 02534 $marginText .= '<ezCall:callText'; 02535 $marginText .= ':size:' . ( isset( $params['size'] ) ? $params['size'] : $this->fontSize() ); 02536 $marginText .= ':justification:' . ( isset( $params['align'] ) ? $params['align'] : 'left' ); 02537 $marginText .= '>'; 02538 02539 $this->ezText( $marginText . $text . '</ezCall:callText>' ); 02540 02541 $this->popStack(); 02542 } 02543 02544 /*! 02545 Callback function for adding text frame. 02546 */ 02547 function callTextFrame( $params, $text ) 02548 { 02549 $this->addDocSpecFunction( 'insertTextFrame', array( $params, $text ) ); 02550 } 02551 02552 /*! 02553 Callback function for adding text frame. 02554 */ 02555 function insertTextFrame( $params, $text ) 02556 { 02557 $prevColor = $this->currentColour; 02558 $prevFontSize = $this->fontSize(); 02559 $prevFont = $this->currentFont(); 02560 02561 if ( isset( $params['fontSize'] ) ) 02562 { 02563 $this->setFontSize( $params['fontSize'] ); 02564 } 02565 02566 if ( isset( $params['fontName'] ) ) 02567 { 02568 $this->selectFont( $params['fontName'] ); 02569 } 02570 02571 $cmykKeys = array( 'c', 'm', 'y', 'k' ); 02572 if ( isset( $params ['frameCMYK'] ) ) 02573 { 02574 $params['frameCMYK'] = explode( ',', $params['frameCMYK'] ); 02575 foreach ( $cmykKeys as $oldKey => $newKey ) 02576 { 02577 $params['frameCMYK'][$newKey] = $params['frameCMYK'][$oldKey]; 02578 unset( $params['frameCMYK'][$oldKey] ); 02579 } 02580 } 02581 if ( isset( $params['textCMYK'] ) ) 02582 { 02583 $params['textCMYK'] = explode( ',', $params['textCMYK'] ); 02584 foreach ( $cmykKeys as $oldKey => $newKey ) 02585 { 02586 $params['textCMYK'][$newKey] = $params['textCMYK'][$oldKey]; 02587 unset( $params['textCMYK'][$oldKey] ); 02588 } 02589 } 02590 02591 $padding = 0; 02592 if ( isset( $params['padding'] ) ) 02593 { 02594 $padding = $params['padding']; 02595 } 02596 02597 $leftPadding = $padding; 02598 $rightPadding = $padding; 02599 $topPadding = $padding; 02600 $bottomPadding = $padding; 02601 02602 if ( isset( $params['leftPadding'] ) ) 02603 { 02604 $leftPadding = $params['leftPadding']; 02605 } 02606 if ( isset( $params['rightPadding'] ) ) 02607 { 02608 $rightPadding = $params['rightPadding']; 02609 } 02610 if ( isset( $params['topPadding'] ) ) 02611 { 02612 $topPadding = $params['topPadding']; 02613 } 02614 if ( isset( $params['bottomPadding'] ) ) 02615 { 02616 $bottomPadding = $params['bottomPadding']; 02617 } 02618 02619 $yOffset = $this->yOffset(); 02620 $xOffset = $this->xOffset(); 02621 02622 $fontHeight = $this->getFontHeight( $this->ez['fontSize'] ); 02623 $fontDecender = $this->getFontDecender( $this->ez['fontSize'] ); 02624 $textWidth = $this->getTextWidth( $this->ez['fontSize'], $text ); 02625 02626 $totalHeight = $fontHeight + $topPadding; 02627 $totalWidth = $textWidth + $leftPadding + $rightPadding; 02628 02629 if ( $rightPadding == -1 ) 02630 { 02631 $totalWidth = $leftPadding + $this->ez['pageWidth'] - $xOffset + 10; 02632 } 02633 02634 if ( isset( $params['frameCMYK'] ) ) 02635 { 02636 $this->setColor( $params['frameCMYK'] ); 02637 } 02638 $this->filledRectangle( $xOffset - $leftPadding, 02639 $yOffset - $bottomPadding, 02640 $totalWidth, 02641 $totalHeight ); 02642 02643 if ( isset( $params['roundEnds'] ) ) 02644 { 02645 if ( $rightPadding != -1 ) 02646 { 02647 $this->filledEllipse( $xOffset + $textWidth + $rightPadding, $yOffset - $bottomPadding + ( $totalHeight / 2 ), $totalHeight / 2 ); 02648 } 02649 if ( $leftPadding != -1 ) 02650 { 02651 $this->filledEllipse( $xOffset - $leftPadding, $yOffset - $bottomPadding + ( $totalHeight / 2 ), $totalHeight / 2 ); 02652 } 02653 } 02654 02655 if ( isset( $params['textCMYK'] ) ) 02656 { 02657 $this->setColor( $params['textCMYK'] ); 02658 } 02659 else 02660 { 02661 $this->setColor( $prevColor ); 02662 } 02663 $this->addText( $xOffset, $yOffset, $this->fontSize(), $text ); 02664 02665 $this->setColor( $prevColor ); 02666 $this->setFontSize( $prevFontSize ); 02667 $this->selectFont( $prevFont ); 02668 } 02669 02670 /** 02671 * Callback function for adding text 02672 */ 02673 function callText( $params ) 02674 { 02675 $options = array(); 02676 02677 if ( isset( $params['font'] ) ) 02678 { 02679 $options['fontName'] = 'lib/ezpdf/classes/fonts/'. $params['font']; 02680 } 02681 02682 if ( isset( $params['size'] ) ) 02683 { 02684 $options['fontSize'] = $params['size']; 02685 } 02686 02687 if ( isset( $params['justification'] ) ) 02688 { 02689 $options['justification'] = $params['justification']; 02690 } 02691 02692 if ( isset( $params['cmyk'] ) ) 02693 { 02694 $keyArray = array ( 'c', 'm', 'y', 'k' ); 02695 $options['cmyk'] = array(); 02696 $params['cmyk'] = explode( ',', $params['cmyk'] ); 02697 foreach ( array_keys( $params['cmyk'] ) as $key ) 02698 { 02699 $options['cmyk'][$keyArray[$key]] = $params['cmyk'][$key]; 02700 } 02701 } 02702 02703 $this->addToPreStack( $options ); 02704 02705 return ''; 02706 } 02707 02708 /*! 02709 * Add and build Stack for function calls and document specification Stack 02710 02711 \param countinues text, set to false to insert independent frames. DEfault true 02712 */ 02713 function pushStack( $continous = true) 02714 { 02715 $docSpecArray = array( 'DocSpec' => $this->DocSpecification, 02716 'PreStack' => $this->PreStack, 02717 'LeftMarginArray' => $this->LeftMarginArray, 02718 'RightMarginArray' => $this->RightMarginArray, 02719 'LeftMargin' => $this->ez['leftMargin'], 02720 'RightMargin' => $this->ez['rightMargin'], 02721 'TopMargin' => $this->ez['topMargin'], 02722 'BottomMargin' => $this->ez['bottomMargin'], 02723 'LineSpace' => $this->ez['lineSpace'], 02724 'Continous' => $continous, 02725 'FontSize' => $this->fontSize(), 02726 'Justification' => $this->justification() ); 02727 if ( $continous ) 02728 { 02729 $docSpecArray['YPos'] = $this->yOffset(); 02730 $docSpecArray['XPos'] = $this->xOffset(); 02731 } 02732 02733 $this->DocSpecStack[] = $docSpecArray; 02734 02735 $this->PreStack = array( array( 'justification' => $this->justification(), 02736 'fontSize' => $this->fontSize(), 02737 'fontName' => 'lib/ezpdf/classes/fonts/Helvetica', 02738 'cmyk' => eZMath:: rgbToCMYK2( 0, 0, 0 ) ) ); 02739 $this->DocSpecification = array(); 02740 } 02741 02742 /*! 02743 Pop Specification stack. 02744 */ 02745 function popStack() 02746 { 02747 $stackArray = array_pop( $this->DocSpecStack ); 02748 $this->DocSpecification = $stackArray['DocSpec']; 02749 $this->PreStack = $stackArray['PreStack']; 02750 $this->LeftMarginArray = $stackArray['LeftMarginArray']; 02751 $this->RightMarginArray = $stackArray['RightMarginArray']; 02752 $this->ez['leftMargin'] = $stackArray['LeftMargin']; 02753 $this->ez['rightMargin'] = $stackArray['RightMargin']; 02754 $this->ez['topMargin'] = $stackArray['TopMargin']; 02755 $this->ez['bottomMargin'] = $stackArray['BottomMargin']; 02756 $this->ez['lineSpace'] = $stackArray['LineSpace']; 02757 $this->setFontSize( $stackArray['FontSize'] ); 02758 $this->setJustification( $stackArray['justification'] ); 02759 02760 if ( $stackArray['continous'] ) 02761 { 02762 $this->setYOffset( $stackArray['YPos'] ); 02763 $this->setXOffset( $stackArray['XPos'] ); 02764 } 02765 } 02766 02767 /** 02768 * Function for adding text to doc specification 02769 * 02770 * param - text to add 02771 */ 02772 function addDocSpecification( $text ) 02773 { 02774 $docSpec = array_pop( $this->PreStack ); 02775 $this->DocSpecification[] = array ( 'docSpec' => $docSpec, 02776 'text' => $text ); 02777 $this->PreStack[] = $docSpec; 02778 } 02779 02780 /** 02781 * Function for adding function to doc specification 02782 * 02783 * param - text to add 02784 */ 02785 function addDocSpecFunction( $functionName, $parameters ) 02786 { 02787 $docSpec = array_pop( $this->PreStack ); 02788 $this->DocSpecification[] = array ( 'docSpec' => $docSpec, 02789 'isFunction' => true, 02790 'functionName' => $functionName, 02791 'parameters' => $parameters ); 02792 $this->PreStack[] = $docSpec; 02793 } 02794 02795 02796 /** 02797 * function for adding font specification to PreStack array 02798 * 02799 * Possible $options setting: 02800 * - justification 02801 * - fontSize 02802 * - fontName 02803 */ 02804 function addToPreStack( $options=array() ) 02805 { 02806 $currentElement = array(); 02807 02808 $prevElement = array_pop( $this->PreStack ); 02809 02810 if ( isset( $options['justification'] ) ) 02811 { 02812 $currentElement['justification'] = $options['justification']; 02813 } 02814 else 02815 { 02816 $currentElement['justification'] = $prevElement['justification']; 02817 } 02818 02819 if ( isset( $options['fontSize'] ) ) 02820 { 02821 $currentElement['fontSize'] = $options['fontSize']; 02822 } 02823 else 02824 { 02825 $currentElement['fontSize'] = $prevElement['fontSize']; 02826 } 02827 02828 if ( isset( $options['fontName'] ) ) 02829 { 02830 $currentElement['fontName'] = $options['fontName']; 02831 } 02832 else 02833 { 02834 $currentElement['fontName'] = $prevElement['fontName']; 02835 } 02836 02837 if ( isset( $options['cmyk'] ) ) 02838 { 02839 $currentElement['cmyk'] = $options['cmyk']; 02840 } 02841 else 02842 { 02843 $currentElement['cmyk'] = $prevElement['cmyk']; 02844 } 02845 02846 $this->PreStack[] = $prevElement; 02847 $this->PreStack[] = $currentElement; 02848 } 02849 02850 /*! 02851 Draw line related to a frame. 02852 */ 02853 function callFrameLine( $info ) 02854 { 02855 $parameters = array(); 02856 eZPDFTable::extractParameters( $info['p'], 0, $parameters, true ); 02857 02858 $location = $parameters['location']; 02859 $yOffset = $parameters['margin']; 02860 if ( $location == 'frame_header' ) 02861 { 02862 $yOffset = $this->ez['pageHeight'] - $parameters['margin']; 02863 } 02864 02865 $rightMargin = $this->rightMargin( $yOffset ); 02866 if ( isset( $parameters['rightMargin'] ) ) 02867 { 02868 $rightMargin = $parameters['rightMargin']; 02869 } 02870 02871 $leftMargin = $this->leftMargin( $yOffset ); 02872 if ( isset( $parameters['leftMargin'] ) ) 02873 { 02874 $leftMargin = $parameters['leftMargin']; 02875 } 02876 02877 $this->setLineStyle( $parameters['thickness'] ); 02878 02879 reset( $this->ezPages ); 02880 foreach ( $this->ezPages as $pageNum => $pageID ) 02881 { 02882 if( $pageNum < $parameters['pageOffset'] ) 02883 continue; 02884 02885 if ( $parameters['page'] == 'odd' && 02886 $pageNum % 2 == 0 ) 02887 continue; 02888 02889 if ( $parameters['page'] == 'even' && 02890 $pageNum % 2 == 1 ) 02891 continue; 02892 02893 $this->reopenObject( $pageID ); 02894 $this->line( $leftMargin, $yOffset, $this->ez['pageWidth'] - $rightMargin, $yOffset ); 02895 $this->closeObject(); 02896 } 02897 02898 $this->setLineStyle( 1 ); 02899 } 02900 02901 /*! 02902 Start page counter in PDF document 02903 02904 \param counter identifier 02905 */ 02906 function callStartPageCounter( $info ) 02907 { 02908 $params = array(); 02909 02910 eZPDFTable::extractParameters( $info['p'], 0, $params, true ); 02911 02912 $identifier = 'main'; 02913 if ( isset( $params['identifier'] ) ) 02914 { 02915 $identifier = $params['identifier']; 02916 } 02917 02918 if ( isset( $params['start'] ) ) 02919 { 02920 $this->PageCounter[$identifier] = array(); 02921 $this->PageCounter[$identifier]['start'] = $this->ezGetCurrentPageNumber(); 02922 } 02923 if ( isset( $params['stop'] ) ) 02924 { 02925 $this->PageCounter[$identifier]['stop'] = $this->ezGetCurrentPageNumber(); 02926 } 02927 } 02928 02929 /*! 02930 02931 \param real page number 02932 \param pagecounter identifier 02933 */ 02934 function ezWhatPageNumber( $pageNum, $identifier = false ) 02935 { 02936 if ( $identifier === false ) 02937 { 02938 foreach ( array_keys( $this->PageCounter ) as $identifier ) 02939 { 02940 if ( isset( $this->PageCounter[$identifier]['start'] ) && 02941 $this->PageCounter[$identifier]['start'] <= $pageNum && 02942 ( !isset( $this->PageCounter[$identifier]['stop'] ) || $this->PageCounter[$identifier]['stop'] >= $pageNum ) ) 02943 return $pageNum - $this->PageCounter[$identifier]['start'] + 1; 02944 } 02945 } 02946 else 02947 return $pageNum - $this->PageCounter[$identifier]['start'] + 1; 02948 } 02949 02950 /*! 02951 \private 02952 02953 Get header label of content on specified page and specified level 02954 02955 \param current page 02956 \param level 02957 */ 02958 function headerLabel( $page, $level ) 02959 { 02960 $headerLabel = ''; 02961 foreach ( array_keys( $this->TOC ) as $key ) 02962 { 02963 $header = $this->TOC[$key]; 02964 if ( $header['pageNumber'] > $page ) 02965 return $headerLabel; 02966 02967 if ( $header['level'] == $level ) 02968 { 02969 $headerLabel = $header['label']; 02970 } 02971 else if ( $header['level'] < $level ) 02972 { 02973 $headerLabel = ''; 02974 } 02975 } 02976 02977 return $headerLabel; 02978 } 02979 02980 /*! 02981 \private 02982 02983 Get header label of content on specified page and specified level 02984 02985 \param current page 02986 \param level 02987 */ 02988 function headerIndex( $page, $level ) 02989 { 02990 $headerIndex = 0; 02991 foreach ( array_keys( $this->TOC ) as $key ) 02992 { 02993 $header = $this->TOC[$key]; 02994 if ( $header['pageNumber'] > $page ) 02995 return ( $headerIndex != 0 ? $headerIndex : '' ); 02996 02997 if ( $header['level'] == $level ) 02998 { 02999 $headerIndex++; 03000 } 03001 else if ( $header['level'] < $level ) 03002 { 03003 $headerLabel = 0; 03004 } 03005 } 03006 03007 return ( $headerIndex != 0 ? $headerIndex : '' ); 03008 } 03009 03010 public $TOC; // Table of content array 03011 public $KeywordArray; // keyword array 03012 public $PageCounter; 03013 03014 public $FrontpageID; // Variable used to store reference to frontpage 03015 03016 public $ezFrame; // array containing frame definitions 03017 03018 /* Stack and array used for preprocessing document */ 03019 public $PreStack; 03020 public $DocSpecification; 03021 03022 /* Stack array for recursive ezText calls */ 03023 public $DocSpecStack = array(); 03024 } 03025 03026 03027 ?>