[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 // 3 // FPDI - Version 1.4.4 4 // 5 // Copyright 2004-2013 Setasign - Jan Slabon 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 // 19 20 define('FPDI_VERSION', '1.4.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'); 29 30 31 class FPDI extends FPDF_TPL { 32 /** 33 * Actual filename 34 * @var string 35 */ 36 var $current_filename; 37 38 /** 39 * Parser-Objects 40 * @var array 41 */ 42 var $parsers; 43 44 /** 45 * Current parser 46 * @var object 47 */ 48 var $current_parser; 49 50 /** 51 * object stack 52 * @var array 53 */ 54 var $_obj_stack; 55 56 /** 57 * done object stack 58 * @var array 59 */ 60 var $_don_obj_stack; 61 62 /** 63 * Current Object Id. 64 * @var integer 65 */ 66 var $_current_obj_id; 67 68 /** 69 * The name of the last imported page box 70 * @var string 71 */ 72 var $lastUsedPageBox; 73 74 /** 75 * Cache for imported pages/template ids 76 * @var array 77 */ 78 var $_importedPages = array(); 79 80 /** 81 * Set a source-file 82 * 83 * @param string $filename a valid filename 84 * @return int number of available pages 85 */ 86 function setSourceFile($filename) { 87 $this->current_filename = $filename; 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 124 /** 125 * Import a page 126 * 127 * @param int $pageno pagenumber 128 * @return int Index of imported page - to use with fpdf_tpl::useTemplate() 129 */ 130 function importPage($pageno, $boxName = '/CropBox') { 131 if ($this->_intpl) { 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]; 141 142 $parser =& $this->parsers[$fn]; 143 $parser->setPageno($pageno); 144 145 if (!in_array($boxName, $parser->availableBoxes)) 146 return $this->Error(sprintf('Unknown box: %s', $boxName)); 147 148 $pageboxes = $parser->getPageBoxes($pageno, $this->k); 149 150 /** 151 * MediaBox 152 * CropBox: Default -> MediaBox 153 * BleedBox: Default -> CropBox 154 * TrimBox: Default -> CropBox 155 * ArtBox: Default -> CropBox 156 */ 157 if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) 158 $boxName = '/CropBox'; 159 if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') 160 $boxName = '/MediaBox'; 161 162 if (!isset($pageboxes[$boxName])) 163 return false; 164 165 $this->lastUsedPageBox = $boxName; 166 167 $box = $pageboxes[$boxName]; 168 169 $this->tpl++; 170 $this->tpls[$this->tpl] = array(); 171 $tpl =& $this->tpls[$this->tpl]; 172 $tpl['parser'] =& $parser; 173 $tpl['resources'] = $parser->getPageResources(); 174 $tpl['buffer'] = $parser->getContent(); 175 $tpl['box'] = $box; 176 177 // To build an array that can be used by PDF_TPL::useTemplate() 178 $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl], $box); 179 180 // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() 181 $tpl['x'] = 0; 182 $tpl['y'] = 0; 183 184 // handle rotated pages 185 $rotation = $parser->getPageRotation($pageno); 186 $tpl['_rotationAngle'] = 0; 187 if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { 188 $steps = $angle / 90; 189 190 $_w = $tpl['w']; 191 $_h = $tpl['h']; 192 $tpl['w'] = $steps % 2 == 0 ? $_w : $_h; 193 $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; 194 195 if ($angle < 0) 196 $angle += 360; 197 198 $tpl['_rotationAngle'] = $angle * -1; 199 } 200 201 $this->_importedPages[$pageKey] = $this->tpl; 202 203 return $this->tpl; 204 } 205 206 /** 207 * Returns the last used page box 208 * 209 * @return string 210 */ 211 function getLastUsedPageBox() { 212 return $this->lastUsedPageBox; 213 } 214 215 216 function useTemplate($tplidx, $_x = null, $_y = null, $_w = 0, $_h = 0, $adjustPageSize = false) { 217 if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { 218 $size = $this->getTemplateSize($tplidx, $_w, $_h); 219 $orientation = $size['w'] > $size['h'] ? 'L' : 'P'; 220 $size = array($size['w'], $size['h']); 221 222 if (is_subclass_of($this, 'TCPDF')) { 223 $this->setPageFormat($size, $orientation); 224 } else { 225 $size = $this->_getpagesize($size); 226 227 if($orientation!=$this->CurOrientation || $size[0]!=$this->CurPageSize[0] || $size[1]!=$this->CurPageSize[1]) 228 { 229 // New size or orientation 230 if($orientation=='P') 231 { 232 $this->w = $size[0]; 233 $this->h = $size[1]; 234 } 235 else 236 { 237 $this->w = $size[1]; 238 $this->h = $size[0]; 239 } 240 $this->wPt = $this->w*$this->k; 241 $this->hPt = $this->h*$this->k; 242 $this->PageBreakTrigger = $this->h-$this->bMargin; 243 $this->CurOrientation = $orientation; 244 $this->CurPageSize = $size; 245 $this->PageSizes[$this->page] = array($this->wPt, $this->hPt); 246 } 247 } 248 } 249 250 $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values 251 $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); 252 $this->_out('Q'); 253 254 return $s; 255 } 256 257 /** 258 * Private method, that rebuilds all needed objects of source files 259 */ 260 function _putimportedobjects() { 261 if (is_array($this->parsers) && count($this->parsers) > 0) { 262 foreach($this->parsers AS $filename => $p) { 263 $this->current_parser =& $this->parsers[$filename]; 264 if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { 265 while(($n = key($this->_obj_stack[$filename])) !== null) { 266 $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c, $this->_obj_stack[$filename][$n][1]); 267 268 $this->_newobj($this->_obj_stack[$filename][$n][0]); 269 270 if ($nObj[0] == PDF_TYPE_STREAM) { 271 $this->pdf_write_value($nObj); 272 } else { 273 $this->pdf_write_value($nObj[1]); 274 } 275 276 $this->_out('endobj'); 277 $this->_obj_stack[$filename][$n] = null; // free memory 278 unset($this->_obj_stack[$filename][$n]); 279 reset($this->_obj_stack[$filename]); 280 } 281 } 282 } 283 } 284 } 285 286 287 /** 288 * Private Method that writes the form xobjects 289 */ 290 function _putformxobjects() { 291 $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; 292 reset($this->tpls); 293 foreach($this->tpls AS $tplidx => $tpl) { 294 $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; 295 $this->_newobj(); 296 $cN = $this->n; // TCPDF/Protection: rem current "n" 297 298 $this->tpls[$tplidx]['n'] = $this->n; 299 $this->_out('<<' . $filter . '/Type /XObject'); 300 $this->_out('/Subtype /Form'); 301 $this->_out('/FormType 1'); 302 303 $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', 304 (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, 305 (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, 306 (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, 307 (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k 308 )); 309 310 $c = 1; 311 $s = 0; 312 $tx = 0; 313 $ty = 0; 314 315 if (isset($tpl['box'])) { 316 $tx = -$tpl['box']['llx']; 317 $ty = -$tpl['box']['lly']; 318 319 if ($tpl['_rotationAngle'] <> 0) { 320 $angle = $tpl['_rotationAngle'] * M_PI/180; 321 $c=cos($angle); 322 $s=sin($angle); 323 324 switch($tpl['_rotationAngle']) { 325 case -90: 326 $tx = -$tpl['box']['lly']; 327 $ty = $tpl['box']['urx']; 328 break; 329 case -180: 330 $tx = $tpl['box']['urx']; 331 $ty = $tpl['box']['ury']; 332 break; 333 case -270: 334 $tx = $tpl['box']['ury']; 335 $ty = -$tpl['box']['llx']; 336 break; 337 } 338 } 339 } elseif ($tpl['x'] != 0 || $tpl['y'] != 0) { 340 $tx = -$tpl['x'] * 2; 341 $ty = $tpl['y'] * 2; 342 } 343 344 $tx *= $this->k; 345 $ty *= $this->k; 346 347 if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { 348 $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', 349 $c, $s, -$s, $c, $tx, $ty 350 )); 351 } 352 353 $this->_out('/Resources '); 354 355 if (isset($tpl['resources'])) { 356 $this->current_parser =& $tpl['parser']; 357 $this->pdf_write_value($tpl['resources']); // "n" will be changed 358 } else { 359 $this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); 360 if (isset($this->_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { 361 $this->_out('/Font <<'); 362 foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) 363 $this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); 364 $this->_out('>>'); 365 } 366 if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || 367 isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) 368 { 369 $this->_out('/XObject <<'); 370 if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { 371 foreach($this->_res['tpl'][$tplidx]['images'] as $image) 372 $this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); 373 } 374 if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { 375 foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) 376 $this->_out($this->tplprefix . $i . ' ' . $tpl['n'] . ' 0 R'); 377 } 378 $this->_out('>>'); 379 } 380 $this->_out('>>'); 381 } 382 383 $this->_out('/Group <</Type/Group/S/Transparency>>'); 384 385 $nN = $this->n; // TCPDF: rem new "n" 386 $this->n = $cN; // TCPDF: reset to current "n" 387 if (is_subclass_of($this, 'TCPDF')) { 388 $p = $this->_getrawstream($p); 389 $this->_out('/Length ' . strlen($p) . ' >>'); 390 $this->_out("stream\n" . $p . "\nendstream"); 391 } else { 392 $this->_out('/Length ' . strlen($p) . ' >>'); 393 $this->_putstream($p); 394 } 395 $this->_out('endobj'); 396 $this->n = $nN; // TCPDF: reset to new "n" 397 } 398 399 $this->_putimportedobjects(); 400 } 401 402 /** 403 * Rewritten to handle existing own defined objects 404 */ 405 function _newobj($obj_id = false, $onlynewobj = false) { 406 if (!$obj_id) { 407 $obj_id = ++$this->n; 408 } 409 410 //Begin a new object 411 if (!$onlynewobj) { 412 $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); 413 $this->_out($obj_id . ' 0 obj'); 414 $this->_current_obj_id = $obj_id; // for later use with encryption 415 } 416 417 return $obj_id; 418 } 419 420 /** 421 * Writes a value 422 * Needed to rebuild the source document 423 * 424 * @param mixed $value A PDF-Value. Structure of values see cases in this method 425 */ 426 function pdf_write_value(&$value) 427 { 428 if (is_subclass_of($this, 'TCPDF')) { 429 parent::pdf_write_value($value); 430 } 431 432 switch ($value[0]) { 433 434 case PDF_TYPE_TOKEN: 435 $this->_straightOut($value[1] . ' '); 436 break; 437 case PDF_TYPE_NUMERIC: 438 case PDF_TYPE_REAL: 439 if (is_float($value[1]) && $value[1] != 0) { 440 $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); 441 } else { 442 $this->_straightOut($value[1] . ' '); 443 } 444 break; 445 446 case PDF_TYPE_ARRAY: 447 448 // An array. Output the proper 449 // structure and move on. 450 451 $this->_straightOut('['); 452 for ($i = 0; $i < count($value[1]); $i++) { 453 $this->pdf_write_value($value[1][$i]); 454 } 455 456 $this->_out(']'); 457 break; 458 459 case PDF_TYPE_DICTIONARY: 460 461 // A dictionary. 462 $this->_straightOut('<<'); 463 464 reset ($value[1]); 465 466 while (list($k, $v) = each($value[1])) { 467 $this->_straightOut($k . ' '); 468 $this->pdf_write_value($v); 469 } 470 471 $this->_straightOut('>>'); 472 break; 473 474 case PDF_TYPE_OBJREF: 475 476 // An indirect object reference 477 // Fill the object stack if needed 478 $cpfn =& $this->current_parser->filename; 479 480 if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { 481 $this->_newobj(false, true); 482 $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); 483 $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! 484 } 485 $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; 486 487 $this->_out($objid . ' 0 R'); 488 break; 489 490 case PDF_TYPE_STRING: 491 492 // A string. 493 $this->_straightOut('(' . $value[1] . ')'); 494 495 break; 496 497 case PDF_TYPE_STREAM: 498 499 // A stream. First, output the 500 // stream dictionary, then the 501 // stream data itself. 502 $this->pdf_write_value($value[1]); 503 $this->_out('stream'); 504 $this->_out($value[2][1]); 505 $this->_out('endstream'); 506 break; 507 508 case PDF_TYPE_HEX: 509 $this->_straightOut('<' . $value[1] . '>'); 510 break; 511 512 case PDF_TYPE_BOOLEAN: 513 $this->_straightOut($value[1] ? 'true ' : 'false '); 514 break; 515 516 case PDF_TYPE_NULL: 517 // The null object. 518 519 $this->_straightOut('null '); 520 break; 521 } 522 } 523 524 525 /** 526 * Modified so not each call will add a newline to the output. 527 */ 528 function _straightOut($s) { 529 if (!is_subclass_of($this, 'TCPDF')) { 530 if($this->state==2) 531 $this->pages[$this->page] .= $s; 532 else 533 $this->buffer .= $s; 534 } else { 535 if ($this->state == 2) { 536 if ($this->inxobj) { 537 // we are inside an XObject template 538 $this->xobjects[$this->xobjid]['outdata'] .= $s; 539 } elseif ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { 540 // puts data before page footer 541 $pagebuff = $this->getPageBuffer($this->page); 542 $page = substr($pagebuff, 0, -$this->footerlen[$this->page]); 543 $footer = substr($pagebuff, -$this->footerlen[$this->page]); 544 $this->setPageBuffer($this->page, $page.$s.$footer); 545 // update footer position 546 $this->footerpos[$this->page] += strlen($s); 547 } else { 548 // set page data 549 $this->setPageBuffer($this->page, $s, true); 550 } 551 } elseif ($this->state > 0) { 552 // set general data 553 $this->setBuffer($s); 554 } 555 } 556 } 557 558 /** 559 * rewritten to close opened parsers 560 * 561 */ 562 function _enddoc() { 563 parent::_enddoc(); 564 $this->_closeParsers(); 565 } 566 567 /** 568 * close all files opened by parsers 569 */ 570 function _closeParsers() { 571 if ($this->state > 2 && count($this->parsers) > 0) { 572 $this->cleanUp(); 573 return true; 574 } 575 return false; 576 } 577 578 /** 579 * Removes cylced references and closes the file handles of the parser objects 580 */ 581 function cleanUp() { 582 foreach ($this->parsers as $k => $_){ 583 $this->parsers[$k]->cleanUp(); 584 $this->parsers[$k] = null; 585 unset($this->parsers[$k]); 586 } 587 } 588 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |