Changeset 19716 for branches/version-2_5-dev/data/module/fpdf/fpdi.php
- Timestamp:
- 2010/12/11 12:15:20 (13 years ago)
- Location:
- branches/version-2_5-dev/data/module/fpdf
- Files:
-
- 1 added
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/version-2_5-dev/data/module/fpdf/fpdi.php
r17260 r19716 1 1 <?php 2 2 // 3 // FPDI - Version 1. 23 // FPDI - Version 1.4 4 4 // 5 // Copyright 2004-20 07Setasign - Jan Slabon5 // Copyright 2004-2010 Setasign - Jan Slabon 6 6 // 7 7 // Licensed under the Apache License, Version 2.0 (the "License"); … … 18 18 // 19 19 20 define('FPDI_VERSION','1.2'); 21 22 ini_set('auto_detect_line_endings',1); // Strongly required! 23 24 require_once("fpdf_tpl.php"); 25 require_once("fpdi_pdf_parser.php"); 20 define('FPDI_VERSION', '1.4'); 21 22 // Check for TCPDF and remap TCPDF to FPDF 23 if (class_exists('TCPDF', false)) { 24 require_once('fpdi2tcpdf_bridge.php'); 25 } 26 27 require_once('fpdf_tpl.php'); 28 require_once('fpdi_pdf_parser.php'); 26 29 27 30 … … 46 49 47 50 /** 48 * Highest version of imported PDF49 * @var double50 */51 var $importVersion = 1.3;52 53 /**54 51 * object stack 55 52 * @var array … … 76 73 77 74 /** 78 * Constructor 79 * See FPDF-Manual 80 */ 81 function FPDI($orientation='P',$unit='mm',$format='A4') { 82 parent::FPDF_TPL($orientation,$unit,$format); 83 } 75 * Cache for imported pages/template ids 76 * @var array 77 */ 78 var $_importedPages = array(); 84 79 85 80 /** … … 91 86 function setSourceFile($filename) { 92 87 $this->current_filename = $filename; 93 $fn =& $this->current_filename; 94 95 if (!isset($this->parsers[$fn])) 96 $this->parsers[$fn] =& new fpdi_pdf_parser($fn,$this); 97 $this->current_parser =& $this->parsers[$fn]; 98 99 return $this->parsers[$fn]->getPageCount(); 100 } 101 88 89 if (!isset($this->parsers[$filename])) 90 $this->parsers[$filename] = $this->_getPdfParser($filename); 91 $this->current_parser =& $this->parsers[$filename]; 92 93 return $this->parsers[$filename]->getPageCount(); 94 } 95 96 /** 97 * Returns a PDF parser object 98 * 99 * @param string $filename 100 * @return fpdi_pdf_parser 101 */ 102 function _getPdfParser($filename) { 103 return new fpdi_pdf_parser($filename, $this); 104 } 105 106 /** 107 * Get the current PDF version 108 * 109 * @return string 110 */ 111 function getPDFVersion() { 112 return $this->PDFVersion; 113 } 114 115 /** 116 * Set the PDF version 117 * 118 * @return string 119 */ 120 function setPDFVersion($version = '1.3') { 121 $this->PDFVersion = $version; 122 } 123 102 124 /** 103 125 * Import a page … … 106 128 * @return int Index of imported page - to use with fpdf_tpl::useTemplate() 107 129 */ 108 function importPage($pageno, $boxName ='/CropBox') {130 function importPage($pageno, $boxName = '/CropBox') { 109 131 if ($this->_intpl) { 110 return $this->error("Please import the desired pages before creating a new template."); 111 } 112 113 $fn =& $this->current_filename; 132 return $this->error('Please import the desired pages before creating a new template.'); 133 } 134 135 $fn = $this->current_filename; 136 137 // check if page already imported 138 $pageKey = $fn . ((int)$pageno) . $boxName; 139 if (isset($this->_importedPages[$pageKey])) 140 return $this->_importedPages[$pageKey]; 114 141 115 142 $parser =& $this->parsers[$fn]; 116 143 $parser->setPageno($pageno); 117 144 118 $this->tpl++;119 $this->tpls[$this->tpl] = array();120 $tpl =& $this->tpls[$this->tpl];121 $tpl['parser'] =& $parser;122 $tpl['resources'] = $parser->getPageResources();123 $tpl['buffer'] = $parser->getContent();124 125 145 if (!in_array($boxName, $parser->availableBoxes)) 126 return $this->Error(sprintf( "Unknown box: %s", $boxName));127 $pageboxes = $parser->getPageBoxes($pageno );146 return $this->Error(sprintf('Unknown box: %s', $boxName)); 147 $pageboxes = $parser->getPageBoxes($pageno, $this->k); 128 148 129 149 /** … … 134 154 * ArtBox: Default -> CropBox 135 155 */ 136 if (!isset($pageboxes[$boxName]) && ($boxName == "/BleedBox" || $boxName == "/TrimBox" || $boxName == "/ArtBox"))137 $boxName = "/CropBox";138 if (!isset($pageboxes[$boxName]) && $boxName == "/CropBox")139 $boxName = "/MediaBox";156 if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) 157 $boxName = '/CropBox'; 158 if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') 159 $boxName = '/MediaBox'; 140 160 141 161 if (!isset($pageboxes[$boxName])) … … 144 164 145 165 $box = $pageboxes[$boxName]; 166 167 $this->tpl++; 168 $this->tpls[$this->tpl] = array(); 169 $tpl =& $this->tpls[$this->tpl]; 170 $tpl['parser'] =& $parser; 171 $tpl['resources'] = $parser->getPageResources(); 172 $tpl['buffer'] = $parser->getContent(); 146 173 $tpl['box'] = $box; 147 174 148 175 // To build an array that can be used by PDF_TPL::useTemplate() 149 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box); 176 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); 177 150 178 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() 151 179 $tpl['x'] = 0; 152 180 $tpl['y'] = 0; 153 181 154 $page =& $parser->pages[$parser->pageno]; 155 156 // fix for rotated pages 182 // handle rotated pages 157 183 $rotation = $parser->getPageRotation($pageno); 184 $tpl['_rotationAngle'] = 0; 158 185 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { 159 186 $steps = $angle / 90; 160 187 161 188 $_w = $tpl['w']; … … 164 191 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; 165 192 166 if ($steps % 2 != 0) { 167 $x = $y = ($steps == 1 || $steps == -3) ? $tpl['h'] : $tpl['w']; 168 } else { 169 $x = $tpl['w']; 170 $y = $tpl['h']; 171 } 172 173 $cx=($x/2+$tpl['box']['x'])*$this->k; 174 $cy=($y/2+$tpl['box']['y'])*$this->k; 175 176 $angle*=-1; 177 178 $angle*=M_PI/180; 179 $c=cos($angle); 180 $s=sin($angle); 181 182 $tpl['buffer'] = sprintf('q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm %s Q',$c,$s,-$s,$c,$cx,$cy,-$cx,-$cy, $tpl['buffer']); 183 } 193 if ($angle < 0) 194 $angle += 360; 195 196 $tpl['_rotationAngle'] = $angle * -1; 197 } 198 199 $this->_importedPages[$pageKey] = $this->tpl; 184 200 185 201 return $this->tpl; … … 190 206 } 191 207 192 function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) { 193 $this->_out('q 0 J 1 w 0 j 0 G'); // reset standard values 208 function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0, $adjustPageSize = false) { 209 if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { 210 $size = $this->getTemplateSize($tplidx, $_w, $_h); 211 $format = array($size['w'], $size['h']); 212 if (is_subclass_of($this, 'TCPDF')) { 213 $this->setPageFormat($format, $format[0] > $format[1] ? 'L' : 'P'); 214 } else { 215 if ($format[0] != $this->CurPageFormat[0] || $format[1] != $this->CurPageFormat[1]) { 216 $this->w = $format[0]; 217 $this->h = $format[1]; 218 $this->wPt = $this->w * $this->k; 219 $this->hPt = $this->h * $this->k; 220 $this->PageBreakTrigger = $this->h - $this->bMargin; 221 $this->CurPageFormat = $format; 222 $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); 223 } 224 } 225 } 226 227 $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values 194 228 $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); 195 229 $this->_out('Q'); 230 196 231 return $s; 197 232 } … … 204 239 foreach($this->parsers AS $filename => $p) { 205 240 $this->current_parser =& $this->parsers[$filename]; 206 if (is _array($this->_obj_stack[$filename])) {207 while( $n = key($this->_obj_stack[$filename])) {208 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]);241 if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { 242 while(($n = key($this->_obj_stack[$filename])) !== null) { 243 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]); 209 244 210 245 $this->_newobj($this->_obj_stack[$filename][$n][0]); 211 246 212 247 if ($nObj[0] == PDF_TYPE_STREAM) { 213 $this->pdf_write_value 248 $this->pdf_write_value($nObj); 214 249 } else { 215 $this->pdf_write_value 250 $this->pdf_write_value($nObj[1]); 216 251 } 217 252 … … 226 261 } 227 262 228 /**229 * Sets the PDF Version to the highest of imported documents230 */231 function setVersion() {232 $this->PDFVersion = max($this->importVersion, $this->PDFVersion);233 }234 235 /**236 * Put resources237 */238 function _putresources() {239 $this->_putfonts();240 $this->_putimages();241 $this->_putformxobjects();242 $this->_putimportedobjects();243 //Resource dictionary244 $this->offsets[2]=strlen($this->buffer);245 $this->_out('2 0 obj');246 $this->_out('<<');247 $this->_putresourcedict();248 $this->_out('>>');249 $this->_out('endobj');250 }251 263 252 264 /** … … 259 271 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; 260 272 $this->_newobj(); 273 $cN = $this->n; // TCPDF/Protection: rem current "n" 274 261 275 $this->tpls[$tplidx]['n'] = $this->n; 262 $this->_out('<<' .$filter.'/Type /XObject');276 $this->_out('<<' . $filter . '/Type /XObject'); 263 277 $this->_out('/Subtype /Form'); 264 278 $this->_out('/FormType 1'); 265 279 266 $this->_out(sprintf('/BBox [%.2f %.2f %.2f %.2f]', 267 ($tpl['x'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, 268 ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y'])*$this->k, 269 ($tpl['w'] + (isset($tpl['box']['x'])?$tpl['box']['x']:0))*$this->k, 270 ($tpl['h'] + (isset($tpl['box']['y'])?$tpl['box']['y']:0) - $tpl['y']-$tpl['h'])*$this->k) 271 ); 272 273 if (isset($tpl['box'])) 274 $this->_out(sprintf('/Matrix [1 0 0 1 %.5f %.5f]',-$tpl['box']['x']*$this->k, -$tpl['box']['y']*$this->k)); 280 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', 281 (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, 282 (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, 283 (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, 284 (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k 285 )); 286 287 $c = 1; 288 $s = 0; 289 $tx = 0; 290 $ty = 0; 291 292 if (isset($tpl['box'])) { 293 $tx = -$tpl['box']['llx']; 294 $ty = -$tpl['box']['lly']; 295 296 if ($tpl['_rotationAngle'] <> 0) { 297 $angle = $tpl['_rotationAngle'] * M_PI/180; 298 $c=cos($angle); 299 $s=sin($angle); 300 301 switch($tpl['_rotationAngle']) { 302 case -90: 303 $tx = -$tpl['box']['lly']; 304 $ty = $tpl['box']['urx']; 305 break; 306 case -180: 307 $tx = $tpl['box']['urx']; 308 $ty = $tpl['box']['ury']; 309 break; 310 case -270: 311 $tx = $tpl['box']['ury']; 312 $ty = -$tpl['box']['llx']; 313 break; 314 } 315 } 316 } else if ($tpl['x'] != 0 || $tpl['y'] != 0) { 317 $tx = -$tpl['x']*2; 318 $ty = $tpl['y']*2; 319 } 320 321 $tx *= $this->k; 322 $ty *= $this->k; 323 324 if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { 325 $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', 326 $c, $s, -$s, $c, $tx, $ty 327 )); 328 } 275 329 276 330 $this->_out('/Resources '); … … 278 332 if (isset($tpl['resources'])) { 279 333 $this->current_parser =& $tpl['parser']; 280 $this->pdf_write_value($tpl['resources']); 334 $this->pdf_write_value($tpl['resources']); // "n" will be changed 281 335 } else { 282 336 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); … … 284 338 $this->_out('/Font <<'); 285 339 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) 286 $this->_out('/F' .$font['i'].' '.$font['n'].' 0 R');340 $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); 287 341 $this->_out('>>'); 288 342 } … … 293 347 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { 294 348 foreach($this->_res['tpl'][$tplidx]['images'] as $image) 295 $this->_out('/I' .$image['i'].' '.$image['n'].' 0 R');349 $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); 296 350 } 297 351 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { 298 352 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) 299 $this->_out($this->tplprefix .$i.' '.$tpl['n'].' 0 R');353 $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); 300 354 } 301 355 $this->_out('>>'); … … 304 358 } 305 359 306 $this->_out('/Length '.strlen($p).' >>'); 360 $nN = $this->n; // TCPDF: rem new "n" 361 $this->n = $cN; // TCPDF: reset to current "n" 362 $this->_out('/Length ' . strlen($p) . ' >>'); 307 363 $this->_putstream($p); 308 364 $this->_out('endobj'); 309 } 365 $this->n = $nN; // TCPDF: reset to new "n" 366 } 367 368 $this->_putimportedobjects(); 310 369 } 311 370 … … 313 372 * Rewritten to handle existing own defined objects 314 373 */ 315 function _newobj($obj_id =false,$onlynewobj=false) {374 function _newobj($obj_id = false, $onlynewobj = false) { 316 375 if (!$obj_id) { 317 376 $obj_id = ++$this->n; 318 377 } 319 378 320 379 //Begin a new object 321 380 if (!$onlynewobj) { 322 $this->offsets[$obj_id] = strlen($this->buffer);323 $this->_out($obj_id .' 0 obj');381 $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); 382 $this->_out($obj_id . ' 0 obj'); 324 383 $this->_current_obj_id = $obj_id; // for later use with encryption 325 384 } 326 385 386 return $obj_id; 327 387 } 328 388 … … 335 395 function pdf_write_value(&$value) 336 396 { 337 397 if (is_subclass_of($this, 'TCPDF')) { 398 parent::pdf_write_value($value); 399 } 400 338 401 switch ($value[0]) { 339 402 340 case PDF_TYPE_NUMERIC : 341 case PDF_TYPE_TOKEN : 342 // A numeric value or a token. 343 // Simply output them 344 $this->_out($value[1]." ", false); 345 break; 346 347 case PDF_TYPE_ARRAY : 403 case PDF_TYPE_TOKEN: 404 $this->_straightOut($value[1] . ' '); 405 break; 406 case PDF_TYPE_NUMERIC: 407 case PDF_TYPE_REAL: 408 if (is_float($value[1]) && $value[1] != 0) { 409 $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); 410 } else { 411 $this->_straightOut($value[1] . ' '); 412 } 413 break; 414 415 case PDF_TYPE_ARRAY: 348 416 349 417 // An array. Output the proper 350 418 // structure and move on. 351 419 352 $this->_ out("[",false);420 $this->_straightOut('['); 353 421 for ($i = 0; $i < count($value[1]); $i++) { 354 422 $this->pdf_write_value($value[1][$i]); 355 423 } 356 424 357 $this->_out( "]");358 break; 359 360 case PDF_TYPE_DICTIONARY 425 $this->_out(']'); 426 break; 427 428 case PDF_TYPE_DICTIONARY: 361 429 362 430 // A dictionary. 363 $this->_ out("<<",false);431 $this->_straightOut('<<'); 364 432 365 433 reset ($value[1]); 366 434 367 435 while (list($k, $v) = each($value[1])) { 368 $this->_ out($k . " ",false);436 $this->_straightOut($k . ' '); 369 437 $this->pdf_write_value($v); 370 438 } 371 439 372 $this->_ out(">>");373 break; 374 375 case PDF_TYPE_OBJREF 440 $this->_straightOut('>>'); 441 break; 442 443 case PDF_TYPE_OBJREF: 376 444 377 445 // An indirect object reference 378 446 // Fill the object stack if needed 379 447 $cpfn =& $this->current_parser->filename; 448 380 449 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { 381 $this->_newobj(false,true);382 383 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 450 $this->_newobj(false, true); 451 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 452 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! 384 453 } 385 454 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; 386 455 387 $this->_out( "{$objid} 0 R"); //{$value[2]}388 break; 389 390 case PDF_TYPE_STRING 456 $this->_out($objid . ' 0 R'); 457 break; 458 459 case PDF_TYPE_STRING: 391 460 392 461 // A string. 393 $this->_ out('('.$value[1].')');394 395 break; 396 397 case PDF_TYPE_STREAM 462 $this->_straightOut('(' . $value[1] . ')'); 463 464 break; 465 466 case PDF_TYPE_STREAM: 398 467 399 468 // A stream. First, output the … … 401 470 // stream data itself. 402 471 $this->pdf_write_value($value[1]); 403 $this->_out( "stream");472 $this->_out('stream'); 404 473 $this->_out($value[2][1]); 405 $this->_out( "endstream");406 break; 407 case PDF_TYPE_HEX :408 409 $this->_ out("<".$value[1].">");474 $this->_out('endstream'); 475 break; 476 477 case PDF_TYPE_HEX: 478 $this->_straightOut('<' . $value[1] . '>'); 410 479 break; 411 480 412 case PDF_TYPE_NULL : 481 case PDF_TYPE_BOOLEAN: 482 $this->_straightOut($value[1] ? 'true ' : 'false '); 483 break; 484 485 case PDF_TYPE_NULL: 413 486 // The null object. 414 487 415 $this->_ out("null");488 $this->_straightOut('null '); 416 489 break; 417 490 } … … 420 493 421 494 /** 422 * Private Method 423 */ 424 function _out($s,$ln=true) { 425 //Add a line to the document 426 if ($this->state==2) { 427 if (!$this->_intpl) 428 $this->pages[$this->page] .= $s.($ln == true ? "\n" : ''); 429 else 430 $this->tpls[$this->tpl]['buffer'] .= $s.($ln == true ? "\n" : ''); 431 } else { 432 $this->buffer.=$s.($ln == true ? "\n" : ''); 433 } 495 * Modified so not each call will add a newline to the output. 496 */ 497 function _straightOut($s) { 498 if (!is_subclass_of($this, 'TCPDF')) { 499 if($this->state==2) 500 $this->pages[$this->page] .= $s; 501 else 502 $this->buffer .= $s; 503 } else { 504 if ($this->state == 2) { 505 if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { 506 // puts data before page footer 507 $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]); 508 $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]); 509 $this->setPageBuffer($this->page, $page . ' ' . $s . "\n" . $footer); 510 } else { 511 $this->setPageBuffer($this->page, $s, true); 512 } 513 } else { 514 $this->setBuffer($s); 515 } 516 } 434 517 } 435 518 … … 457 540 return false; 458 541 } 459 460 542 } 461 462 // for PHP5463 if (version_compare("5", PHP_VERSION, "<")) {464 if (!class_exists('fpdi')) {465 class fpdi extends FPDI {}466 }467 }468 ?>
Note: See TracChangeset
for help on using the changeset viewer.