root / drupal7 / sites / all / libraries / fpdi-1.5.4 / fpdi.php @ 4b706e38
1 |
<?php
|
---|---|
2 |
//
|
3 |
// FPDI - Version 1.5.4
|
4 |
//
|
5 |
// Copyright 2004-2015 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 |
if (!class_exists('FPDF_TPL')) { |
21 |
require_once('fpdf_tpl.php'); |
22 |
} |
23 |
|
24 |
/**
|
25 |
* Class FPDI
|
26 |
*/
|
27 |
class FPDI extends FPDF_TPL |
28 |
{ |
29 |
/**
|
30 |
* FPDI version
|
31 |
*
|
32 |
* @string
|
33 |
*/
|
34 |
const VERSION = '1.5.3'; |
35 |
|
36 |
/**
|
37 |
* Actual filename
|
38 |
*
|
39 |
* @var string
|
40 |
*/
|
41 |
public $currentFilename; |
42 |
|
43 |
/**
|
44 |
* Parser-Objects
|
45 |
*
|
46 |
* @var fpdi_pdf_parser[]
|
47 |
*/
|
48 |
public $parsers = array(); |
49 |
|
50 |
/**
|
51 |
* Current parser
|
52 |
*
|
53 |
* @var fpdi_pdf_parser
|
54 |
*/
|
55 |
public $currentParser; |
56 |
|
57 |
/**
|
58 |
* The name of the last imported page box
|
59 |
*
|
60 |
* @var string
|
61 |
*/
|
62 |
public $lastUsedPageBox; |
63 |
|
64 |
/**
|
65 |
* Object stack
|
66 |
*
|
67 |
* @var array
|
68 |
*/
|
69 |
protected $_objStack; |
70 |
|
71 |
/**
|
72 |
* Done object stack
|
73 |
*
|
74 |
* @var array
|
75 |
*/
|
76 |
protected $_doneObjStack; |
77 |
|
78 |
/**
|
79 |
* Current Object Id.
|
80 |
*
|
81 |
* @var integer
|
82 |
*/
|
83 |
protected $_currentObjId; |
84 |
|
85 |
/**
|
86 |
* Cache for imported pages/template ids
|
87 |
*
|
88 |
* @var array
|
89 |
*/
|
90 |
protected $_importedPages = array(); |
91 |
|
92 |
/**
|
93 |
* Set a source-file.
|
94 |
*
|
95 |
* Depending on the PDF version of the used document the PDF version of the resulting document will
|
96 |
* be adjusted to the higher version.
|
97 |
*
|
98 |
* @param string $filename A valid path to the PDF document from which pages should be imported from
|
99 |
* @return int The number of pages in the document
|
100 |
*/
|
101 |
public function setSourceFile($filename) |
102 |
{ |
103 |
$_filename = realpath($filename); |
104 |
if (false !== $_filename) |
105 |
$filename = $_filename; |
106 |
|
107 |
$this->currentFilename = $filename; |
108 |
|
109 |
if (!isset($this->parsers[$filename])) { |
110 |
$this->parsers[$filename] = $this->_getPdfParser($filename); |
111 |
$this->setPdfVersion(
|
112 |
max($this->getPdfVersion(), $this->parsers[$filename]->getPdfVersion()) |
113 |
); |
114 |
} |
115 |
|
116 |
$this->currentParser = $this->parsers[$filename]; |
117 |
|
118 |
return $this->parsers[$filename]->getPageCount(); |
119 |
} |
120 |
|
121 |
/**
|
122 |
* Returns a PDF parser object
|
123 |
*
|
124 |
* @param string $filename
|
125 |
* @return fpdi_pdf_parser
|
126 |
*/
|
127 |
protected function _getPdfParser($filename) |
128 |
{ |
129 |
if (!class_exists('fpdi_pdf_parser')) { |
130 |
require_once('fpdi_pdf_parser.php'); |
131 |
} |
132 |
return new fpdi_pdf_parser($filename); |
133 |
} |
134 |
|
135 |
/**
|
136 |
* Get the current PDF version.
|
137 |
*
|
138 |
* @return string
|
139 |
*/
|
140 |
public function getPdfVersion() |
141 |
{ |
142 |
return $this->PDFVersion; |
143 |
} |
144 |
|
145 |
/**
|
146 |
* Set the PDF version.
|
147 |
*
|
148 |
* @param string $version
|
149 |
*/
|
150 |
public function setPdfVersion($version = '1.3') |
151 |
{ |
152 |
$this->PDFVersion = sprintf('%.1F', $version); |
153 |
} |
154 |
|
155 |
/**
|
156 |
* Import a page.
|
157 |
*
|
158 |
* The second parameter defines the bounding box that should be used to transform the page into a
|
159 |
* form XObject.
|
160 |
*
|
161 |
* Following values are available: MediaBox, CropBox, BleedBox, TrimBox, ArtBox.
|
162 |
* If a box is not especially defined its default box will be used:
|
163 |
*
|
164 |
* <ul>
|
165 |
* <li>CropBox: Default -> MediaBox</li>
|
166 |
* <li>BleedBox: Default -> CropBox</li>
|
167 |
* <li>TrimBox: Default -> CropBox</li>
|
168 |
* <li>ArtBox: Default -> CropBox</li>
|
169 |
* </ul>
|
170 |
*
|
171 |
* It is possible to get the used page box by the {@link getLastUsedPageBox()} method.
|
172 |
*
|
173 |
* @param int $pageNo The page number
|
174 |
* @param string $boxName The boundary box to use when transforming the page into a form XObject
|
175 |
* @param boolean $groupXObject Define the form XObject as a group XObject to support transparency (if used)
|
176 |
* @return int An id of the imported page/template to use with e.g. fpdf_tpl::useTemplate()
|
177 |
* @throws LogicException|InvalidArgumentException
|
178 |
* @see getLastUsedPageBox()
|
179 |
*/
|
180 |
public function importPage($pageNo, $boxName = 'CropBox', $groupXObject = true) |
181 |
{ |
182 |
if ($this->_inTpl) { |
183 |
throw new LogicException('Please import the desired pages before creating a new template.'); |
184 |
} |
185 |
|
186 |
$fn = $this->currentFilename; |
187 |
$boxName = '/' . ltrim($boxName, '/'); |
188 |
|
189 |
// check if page already imported
|
190 |
$pageKey = $fn . '-' . ((int)$pageNo) . $boxName; |
191 |
if (isset($this->_importedPages[$pageKey])) { |
192 |
return $this->_importedPages[$pageKey]; |
193 |
} |
194 |
|
195 |
$parser = $this->parsers[$fn]; |
196 |
$parser->setPageNo($pageNo); |
197 |
|
198 |
if (!in_array($boxName, $parser->availableBoxes)) { |
199 |
throw new InvalidArgumentException(sprintf('Unknown box: %s', $boxName)); |
200 |
} |
201 |
|
202 |
$pageBoxes = $parser->getPageBoxes($pageNo, $this->k); |
203 |
|
204 |
/**
|
205 |
* MediaBox
|
206 |
* CropBox: Default -> MediaBox
|
207 |
* BleedBox: Default -> CropBox
|
208 |
* TrimBox: Default -> CropBox
|
209 |
* ArtBox: Default -> CropBox
|
210 |
*/
|
211 |
if (!isset($pageBoxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) |
212 |
$boxName = '/CropBox'; |
213 |
if (!isset($pageBoxes[$boxName]) && $boxName == '/CropBox') |
214 |
$boxName = '/MediaBox'; |
215 |
|
216 |
if (!isset($pageBoxes[$boxName])) |
217 |
return false; |
218 |
|
219 |
$this->lastUsedPageBox = $boxName; |
220 |
|
221 |
$box = $pageBoxes[$boxName]; |
222 |
|
223 |
$this->tpl++;
|
224 |
$this->_tpls[$this->tpl] = array(); |
225 |
$tpl =& $this->_tpls[$this->tpl]; |
226 |
$tpl['parser'] = $parser; |
227 |
$tpl['resources'] = $parser->getPageResources(); |
228 |
$tpl['buffer'] = $parser->getContent(); |
229 |
$tpl['box'] = $box; |
230 |
$tpl['groupXObject'] = $groupXObject; |
231 |
if ($groupXObject) { |
232 |
$this->setPdfVersion(max($this->getPdfVersion(), 1.4)); |
233 |
} |
234 |
|
235 |
// To build an array that can be used by PDF_TPL::useTemplate()
|
236 |
$this->_tpls[$this->tpl] = array_merge($this->_tpls[$this->tpl], $box); |
237 |
|
238 |
// An imported page will start at 0,0 all the time. Translation will be set in _putformxobjects()
|
239 |
$tpl['x'] = 0; |
240 |
$tpl['y'] = 0; |
241 |
|
242 |
// handle rotated pages
|
243 |
$rotation = $parser->getPageRotation($pageNo); |
244 |
$tpl['_rotationAngle'] = 0; |
245 |
if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { |
246 |
$steps = $angle / 90; |
247 |
|
248 |
$_w = $tpl['w']; |
249 |
$_h = $tpl['h']; |
250 |
$tpl['w'] = $steps % 2 == 0 ? $_w : $_h; |
251 |
$tpl['h'] = $steps % 2 == 0 ? $_h : $_w; |
252 |
|
253 |
if ($angle < 0) |
254 |
$angle += 360; |
255 |
|
256 |
$tpl['_rotationAngle'] = $angle * -1; |
257 |
} |
258 |
|
259 |
$this->_importedPages[$pageKey] = $this->tpl; |
260 |
|
261 |
return $this->tpl; |
262 |
} |
263 |
|
264 |
/**
|
265 |
* Returns the last used page boundary box.
|
266 |
*
|
267 |
* @return string The used boundary box: MediaBox, CropBox, BleedBox, TrimBox or ArtBox
|
268 |
*/
|
269 |
public function getLastUsedPageBox() |
270 |
{ |
271 |
return $this->lastUsedPageBox; |
272 |
} |
273 |
|
274 |
/**
|
275 |
* Use a template or imported page in current page or other template.
|
276 |
*
|
277 |
* You can use a template in a page or in another template.
|
278 |
* You can give the used template a new size. All parameters are optional.
|
279 |
* The width or height is calculated automatically if one is given. If no
|
280 |
* parameter is given the origin size as defined in beginTemplate() or of
|
281 |
* the imported page is used.
|
282 |
*
|
283 |
* The calculated or used width and height are returned as an array.
|
284 |
*
|
285 |
* @param int $tplIdx A valid template-id
|
286 |
* @param int $x The x-position
|
287 |
* @param int $y The y-position
|
288 |
* @param int $w The new width of the template
|
289 |
* @param int $h The new height of the template
|
290 |
* @param boolean $adjustPageSize If set to true the current page will be resized to fit the dimensions
|
291 |
* of the template
|
292 |
*
|
293 |
* @return array The height and width of the template (array('w' => ..., 'h' => ...))
|
294 |
* @throws LogicException|InvalidArgumentException
|
295 |
*/
|
296 |
public function useTemplate($tplIdx, $x = null, $y = null, $w = 0, $h = 0, $adjustPageSize = false) |
297 |
{ |
298 |
if ($adjustPageSize == true && is_null($x) && is_null($y)) { |
299 |
$size = $this->getTemplateSize($tplIdx, $w, $h); |
300 |
$orientation = $size['w'] > $size['h'] ? 'L' : 'P'; |
301 |
$size = array($size['w'], $size['h']); |
302 |
|
303 |
if (is_subclass_of($this, 'TCPDF')) { |
304 |
$this->setPageFormat($size, $orientation); |
305 |
} else {
|
306 |
$size = $this->_getpagesize($size); |
307 |
|
308 |
if($orientation != $this->CurOrientation || |
309 |
$size[0] != $this->CurPageSize[0] || |
310 |
$size[1] != $this->CurPageSize[1] |
311 |
) { |
312 |
// New size or orientation
|
313 |
if ($orientation=='P') { |
314 |
$this->w = $size[0]; |
315 |
$this->h = $size[1]; |
316 |
} else {
|
317 |
$this->w = $size[1]; |
318 |
$this->h = $size[0]; |
319 |
} |
320 |
$this->wPt = $this->w * $this->k; |
321 |
$this->hPt = $this->h * $this->k; |
322 |
$this->PageBreakTrigger = $this->h - $this->bMargin; |
323 |
$this->CurOrientation = $orientation; |
324 |
$this->CurPageSize = $size; |
325 |
$this->PageSizes[$this->page] = array($this->wPt, $this->hPt); |
326 |
} |
327 |
} |
328 |
} |
329 |
|
330 |
$this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values |
331 |
$size = parent::useTemplate($tplIdx, $x, $y, $w, $h); |
332 |
$this->_out('Q'); |
333 |
|
334 |
return $size; |
335 |
} |
336 |
|
337 |
/**
|
338 |
* Copy all imported objects to the resulting document.
|
339 |
*/
|
340 |
protected function _putimportedobjects() |
341 |
{ |
342 |
foreach($this->parsers AS $filename => $p) { |
343 |
$this->currentParser = $p; |
344 |
if (!isset($this->_objStack[$filename]) || !is_array($this->_objStack[$filename])) { |
345 |
continue;
|
346 |
} |
347 |
while(($n = key($this->_objStack[$filename])) !== null) { |
348 |
try {
|
349 |
$nObj = $this->currentParser->resolveObject($this->_objStack[$filename][$n][1]); |
350 |
} catch (Exception $e) { |
351 |
$nObj = array(pdf_parser::TYPE_OBJECT, pdf_parser::TYPE_NULL); |
352 |
} |
353 |
|
354 |
$this->_newobj($this->_objStack[$filename][$n][0]); |
355 |
|
356 |
if ($nObj[0] == pdf_parser::TYPE_STREAM) { |
357 |
$this->_writeValue($nObj); |
358 |
} else {
|
359 |
$this->_writeValue($nObj[1]); |
360 |
} |
361 |
|
362 |
$this->_out("\nendobj"); |
363 |
$this->_objStack[$filename][$n] = null; // free memory |
364 |
unset($this->_objStack[$filename][$n]); |
365 |
reset($this->_objStack[$filename]); |
366 |
} |
367 |
} |
368 |
} |
369 |
|
370 |
/**
|
371 |
* Writes the form XObjects to the PDF document.
|
372 |
*/
|
373 |
protected function _putformxobjects() |
374 |
{ |
375 |
$filter = ($this->compress) ? '/Filter /FlateDecode ' : ''; |
376 |
reset($this->_tpls); |
377 |
foreach($this->_tpls AS $tplIdx => $tpl) { |
378 |
$this->_newobj();
|
379 |
$currentN = $this->n; // TCPDF/Protection: rem current "n" |
380 |
|
381 |
$this->_tpls[$tplIdx]['n'] = $this->n; |
382 |
$this->_out('<<' . $filter . '/Type /XObject'); |
383 |
$this->_out('/Subtype /Form'); |
384 |
$this->_out('/FormType 1'); |
385 |
|
386 |
$this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', |
387 |
(isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x']) * $this->k, |
388 |
(isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y']) * $this->k, |
389 |
(isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x']) * $this->k, |
390 |
(isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h'] - $tpl['y']) * $this->k |
391 |
)); |
392 |
|
393 |
$c = 1; |
394 |
$s = 0; |
395 |
$tx = 0; |
396 |
$ty = 0; |
397 |
|
398 |
if (isset($tpl['box'])) { |
399 |
$tx = -$tpl['box']['llx']; |
400 |
$ty = -$tpl['box']['lly']; |
401 |
|
402 |
if ($tpl['_rotationAngle'] <> 0) { |
403 |
$angle = $tpl['_rotationAngle'] * M_PI/180; |
404 |
$c = cos($angle); |
405 |
$s = sin($angle); |
406 |
|
407 |
switch($tpl['_rotationAngle']) { |
408 |
case -90: |
409 |
$tx = -$tpl['box']['lly']; |
410 |
$ty = $tpl['box']['urx']; |
411 |
break;
|
412 |
case -180: |
413 |
$tx = $tpl['box']['urx']; |
414 |
$ty = $tpl['box']['ury']; |
415 |
break;
|
416 |
case -270: |
417 |
$tx = $tpl['box']['ury']; |
418 |
$ty = -$tpl['box']['llx']; |
419 |
break;
|
420 |
} |
421 |
} |
422 |
} else if ($tpl['x'] != 0 || $tpl['y'] != 0) { |
423 |
$tx = -$tpl['x'] * 2; |
424 |
$ty = $tpl['y'] * 2; |
425 |
} |
426 |
|
427 |
$tx *= $this->k; |
428 |
$ty *= $this->k; |
429 |
|
430 |
if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { |
431 |
$this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', |
432 |
$c, $s, -$s, $c, $tx, $ty |
433 |
)); |
434 |
} |
435 |
|
436 |
$this->_out('/Resources '); |
437 |
|
438 |
if (isset($tpl['resources'])) { |
439 |
$this->currentParser = $tpl['parser']; |
440 |
$this->_writeValue($tpl['resources']); // "n" will be changed |
441 |
} else {
|
442 |
|
443 |
$this->_out('<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); |
444 |
if (isset($this->_res['tpl'][$tplIdx])) { |
445 |
$res = $this->_res['tpl'][$tplIdx]; |
446 |
|
447 |
if (isset($res['fonts']) && count($res['fonts'])) { |
448 |
$this->_out('/Font <<'); |
449 |
foreach ($res['fonts'] as $font) |
450 |
$this->_out('/F' . $font['i'] . ' ' . $font['n'] . ' 0 R'); |
451 |
$this->_out('>>'); |
452 |
} |
453 |
if (isset($res['images']) && count($res['images']) || |
454 |
isset($res['tpls']) && count($res['tpls'])) |
455 |
{ |
456 |
$this->_out('/XObject <<'); |
457 |
if (isset($res['images'])) { |
458 |
foreach ($res['images'] as $image) |
459 |
$this->_out('/I' . $image['i'] . ' ' . $image['n'] . ' 0 R'); |
460 |
} |
461 |
if (isset($res['tpls'])) { |
462 |
foreach ($res['tpls'] as $i => $_tpl) |
463 |
$this->_out($this->tplPrefix . $i . ' ' . $_tpl['n'] . ' 0 R'); |
464 |
} |
465 |
$this->_out('>>'); |
466 |
} |
467 |
$this->_out('>>'); |
468 |
} |
469 |
} |
470 |
|
471 |
if (isset($tpl['groupXObject']) && $tpl['groupXObject']) { |
472 |
$this->_out('/Group <</Type/Group/S/Transparency>>'); |
473 |
} |
474 |
|
475 |
$newN = $this->n; // TCPDF: rem new "n" |
476 |
$this->n = $currentN; // TCPDF: reset to current "n" |
477 |
|
478 |
$buffer = ($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; |
479 |
|
480 |
if (is_subclass_of($this, 'TCPDF')) { |
481 |
$buffer = $this->_getrawstream($buffer); |
482 |
$this->_out('/Length ' . strlen($buffer) . ' >>'); |
483 |
$this->_out("stream\n" . $buffer . "\nendstream"); |
484 |
} else {
|
485 |
$this->_out('/Length ' . strlen($buffer) . ' >>'); |
486 |
$this->_putstream($buffer); |
487 |
} |
488 |
$this->_out('endobj'); |
489 |
$this->n = $newN; // TCPDF: reset to new "n" |
490 |
} |
491 |
|
492 |
$this->_putimportedobjects();
|
493 |
} |
494 |
|
495 |
/**
|
496 |
* Creates and optionally write the object definition to the document.
|
497 |
*
|
498 |
* Rewritten to handle existing own defined objects
|
499 |
*
|
500 |
* @param bool $objId
|
501 |
* @param bool $onlyNewObj
|
502 |
* @return bool|int
|
503 |
*/
|
504 |
public function _newobj($objId = false, $onlyNewObj = false) |
505 |
{ |
506 |
if (!$objId) { |
507 |
$objId = ++$this->n; |
508 |
} |
509 |
|
510 |
//Begin a new object
|
511 |
if (!$onlyNewObj) { |
512 |
$this->offsets[$objId] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); |
513 |
$this->_out($objId . ' 0 obj'); |
514 |
$this->_currentObjId = $objId; // for later use with encryption |
515 |
} |
516 |
|
517 |
return $objId; |
518 |
} |
519 |
|
520 |
/**
|
521 |
* Writes a PDF value to the resulting document.
|
522 |
*
|
523 |
* Needed to rebuild the source document
|
524 |
*
|
525 |
* @param mixed $value A PDF-Value. Structure of values see cases in this method
|
526 |
*/
|
527 |
protected function _writeValue(&$value) |
528 |
{ |
529 |
if (is_subclass_of($this, 'TCPDF')) { |
530 |
parent::_prepareValue($value); |
531 |
} |
532 |
|
533 |
switch ($value[0]) { |
534 |
|
535 |
case pdf_parser::TYPE_TOKEN: |
536 |
$this->_straightOut($value[1] . ' '); |
537 |
break;
|
538 |
case pdf_parser::TYPE_NUMERIC: |
539 |
case pdf_parser::TYPE_REAL: |
540 |
if (is_float($value[1]) && $value[1] != 0) { |
541 |
$this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') . ' '); |
542 |
} else {
|
543 |
$this->_straightOut($value[1] . ' '); |
544 |
} |
545 |
break;
|
546 |
|
547 |
case pdf_parser::TYPE_ARRAY: |
548 |
|
549 |
// An array. Output the proper
|
550 |
// structure and move on.
|
551 |
|
552 |
$this->_straightOut('['); |
553 |
for ($i = 0; $i < count($value[1]); $i++) { |
554 |
$this->_writeValue($value[1][$i]); |
555 |
} |
556 |
|
557 |
$this->_out(']'); |
558 |
break;
|
559 |
|
560 |
case pdf_parser::TYPE_DICTIONARY: |
561 |
|
562 |
// A dictionary.
|
563 |
$this->_straightOut('<<'); |
564 |
|
565 |
reset ($value[1]); |
566 |
|
567 |
while (list($k, $v) = each($value[1])) { |
568 |
$this->_straightOut($k . ' '); |
569 |
$this->_writeValue($v); |
570 |
} |
571 |
|
572 |
$this->_straightOut('>>'); |
573 |
break;
|
574 |
|
575 |
case pdf_parser::TYPE_OBJREF: |
576 |
|
577 |
// An indirect object reference
|
578 |
// Fill the object stack if needed
|
579 |
$cpfn =& $this->currentParser->filename; |
580 |
if (!isset($this->_doneObjStack[$cpfn][$value[1]])) { |
581 |
$this->_newobj(false, true); |
582 |
$this->_objStack[$cpfn][$value[1]] = array($this->n, $value); |
583 |
$this->_doneObjStack[$cpfn][$value[1]] = array($this->n, $value); |
584 |
} |
585 |
$objId = $this->_doneObjStack[$cpfn][$value[1]][0]; |
586 |
|
587 |
$this->_out($objId . ' 0 R'); |
588 |
break;
|
589 |
|
590 |
case pdf_parser::TYPE_STRING: |
591 |
|
592 |
// A string.
|
593 |
$this->_straightOut('(' . $value[1] . ')'); |
594 |
|
595 |
break;
|
596 |
|
597 |
case pdf_parser::TYPE_STREAM: |
598 |
|
599 |
// A stream. First, output the
|
600 |
// stream dictionary, then the
|
601 |
// stream data itself.
|
602 |
$this->_writeValue($value[1]); |
603 |
$this->_out('stream'); |
604 |
$this->_out($value[2][1]); |
605 |
$this->_straightOut("endstream"); |
606 |
break;
|
607 |
|
608 |
case pdf_parser::TYPE_HEX: |
609 |
$this->_straightOut('<' . $value[1] . '>'); |
610 |
break;
|
611 |
|
612 |
case pdf_parser::TYPE_BOOLEAN: |
613 |
$this->_straightOut($value[1] ? 'true ' : 'false '); |
614 |
break;
|
615 |
|
616 |
case pdf_parser::TYPE_NULL: |
617 |
// The null object.
|
618 |
|
619 |
$this->_straightOut('null '); |
620 |
break;
|
621 |
} |
622 |
} |
623 |
|
624 |
|
625 |
/**
|
626 |
* Modified _out() method so not each call will add a newline to the output.
|
627 |
*/
|
628 |
protected function _straightOut($s) |
629 |
{ |
630 |
if (!is_subclass_of($this, 'TCPDF')) { |
631 |
if ($this->state == 2) { |
632 |
$this->pages[$this->page] .= $s; |
633 |
} else {
|
634 |
$this->buffer .= $s; |
635 |
} |
636 |
|
637 |
} else {
|
638 |
if ($this->state == 2) { |
639 |
if ($this->inxobj) { |
640 |
// we are inside an XObject template
|
641 |
$this->xobjects[$this->xobjid]['outdata'] .= $s; |
642 |
} else if ((!$this->InFooter) AND isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { |
643 |
// puts data before page footer
|
644 |
$pagebuff = $this->getPageBuffer($this->page); |
645 |
$page = substr($pagebuff, 0, -$this->footerlen[$this->page]); |
646 |
$footer = substr($pagebuff, -$this->footerlen[$this->page]); |
647 |
$this->setPageBuffer($this->page, $page . $s . $footer); |
648 |
// update footer position
|
649 |
$this->footerpos[$this->page] += strlen($s); |
650 |
} else {
|
651 |
// set page data
|
652 |
$this->setPageBuffer($this->page, $s, true); |
653 |
} |
654 |
} else if ($this->state > 0) { |
655 |
// set general data
|
656 |
$this->setBuffer($s); |
657 |
} |
658 |
} |
659 |
} |
660 |
|
661 |
/**
|
662 |
* Ends the document
|
663 |
*
|
664 |
* Overwritten to close opened parsers
|
665 |
*/
|
666 |
public function _enddoc() |
667 |
{ |
668 |
parent::_enddoc();
|
669 |
$this->_closeParsers();
|
670 |
} |
671 |
|
672 |
/**
|
673 |
* Close all files opened by parsers.
|
674 |
*
|
675 |
* @return boolean
|
676 |
*/
|
677 |
protected function _closeParsers() |
678 |
{ |
679 |
if ($this->state > 2) { |
680 |
$this->cleanUp();
|
681 |
return true; |
682 |
} |
683 |
|
684 |
return false; |
685 |
} |
686 |
|
687 |
/**
|
688 |
* Removes cycled references and closes the file handles of the parser objects.
|
689 |
*/
|
690 |
public function cleanUp() |
691 |
{ |
692 |
while (($parser = array_pop($this->parsers)) !== null) { |
693 |
/**
|
694 |
* @var fpdi_pdf_parser $parser
|
695 |
*/
|
696 |
$parser->closeFile();
|
697 |
} |
698 |
} |
699 |
} |