Fpdi.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. /**
  3. * This file is part of FPDI
  4. *
  5. * @package Fpdi
  6. * @copyright Copyright (c) 2020 Setasign GmbH & Co. KG (https://www.setasign.com)
  7. * @license http://opensource.org/licenses/mit-license The MIT License
  8. */
  9. namespace Fpdi;
  10. use Fpdi\PdfParser\CrossReference\CrossReferenceException;
  11. use Fpdi\PdfParser\PdfParserException;
  12. use Fpdi\PdfParser\Type\PdfIndirectObject;
  13. use Fpdi\PdfParser\Type\PdfNull;
  14. /**
  15. * Class Fpdi
  16. *
  17. * This class let you import pages of existing PDF documents into a reusable structure for FPDF.
  18. */
  19. class Fpdi extends FpdfTpl
  20. {
  21. use FpdiTrait;
  22. /**
  23. * FPDI version
  24. *
  25. * @string
  26. */
  27. const VERSION = '2.3.6';
  28. protected function _enddoc()
  29. {
  30. parent::_enddoc();
  31. $this->cleanUp();
  32. }
  33. /**
  34. * Draws an imported page or a template onto the page or another template.
  35. *
  36. * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the
  37. * aspect ratio.
  38. *
  39. * @param mixed $tpl The template id
  40. * @param float|int|array $x The abscissa of upper-left corner. Alternatively you could use an assoc array
  41. * with the keys "x", "y", "width", "height", "adjustPageSize".
  42. * @param float|int $y The ordinate of upper-left corner.
  43. * @param float|int|null $width The width.
  44. * @param float|int|null $height The height.
  45. * @param bool $adjustPageSize
  46. * @return array The size
  47. * @see Fpdi::getTemplateSize()
  48. */
  49. public function useTemplate($tpl, $x = 0, $y = 0, $width = null, $height = null, $adjustPageSize = false)
  50. {
  51. if (isset($this->importedPages[$tpl])) {
  52. $size = $this->useImportedPage($tpl, $x, $y, $width, $height, $adjustPageSize);
  53. if ($this->currentTemplateId !== null) {
  54. $this->templates[$this->currentTemplateId]['resources']['templates']['importedPages'][$tpl] = $tpl;
  55. }
  56. return $size;
  57. }
  58. return parent::useTemplate($tpl, $x, $y, $width, $height, $adjustPageSize);
  59. }
  60. /**
  61. * Get the size of an imported page or template.
  62. *
  63. * Give only one of the size parameters (width, height) to calculate the other one automatically in view to the
  64. * aspect ratio.
  65. *
  66. * @param mixed $tpl The template id
  67. * @param float|int|null $width The width.
  68. * @param float|int|null $height The height.
  69. * @return array|bool An array with following keys: width, height, 0 (=width), 1 (=height), orientation (L or P)
  70. */
  71. public function getTemplateSize($tpl, $width = null, $height = null)
  72. {
  73. $size = parent::getTemplateSize($tpl, $width, $height);
  74. if ($size === false) {
  75. return $this->getImportedPageSize($tpl, $width, $height);
  76. }
  77. return $size;
  78. }
  79. /**
  80. * @inheritdoc
  81. * @throws CrossReferenceException
  82. * @throws PdfParserException
  83. */
  84. protected function _putimages()
  85. {
  86. $this->currentReaderId = null;
  87. parent::_putimages();
  88. foreach ($this->importedPages as $key => $pageData) {
  89. $this->_newobj();
  90. $this->importedPages[$key]['objectNumber'] = $this->n;
  91. $this->currentReaderId = $pageData['readerId'];
  92. $this->writePdfType($pageData['stream']);
  93. $this->_put('endobj');
  94. }
  95. foreach (\array_keys($this->readers) as $readerId) {
  96. $parser = $this->getPdfReader($readerId)->getParser();
  97. $this->currentReaderId = $readerId;
  98. while (($objectNumber = \array_pop($this->objectsToCopy[$readerId])) !== null) {
  99. try {
  100. $object = $parser->getIndirectObject($objectNumber);
  101. } catch (CrossReferenceException $e) {
  102. if ($e->getCode() === CrossReferenceException::OBJECT_NOT_FOUND) {
  103. $object = PdfIndirectObject::create($objectNumber, 0, new PdfNull());
  104. } else {
  105. throw $e;
  106. }
  107. }
  108. $this->writePdfType($object);
  109. }
  110. }
  111. $this->currentReaderId = null;
  112. }
  113. /**
  114. * @inheritdoc
  115. */
  116. protected function _putxobjectdict()
  117. {
  118. foreach ($this->importedPages as $key => $pageData) {
  119. $this->_put('/' . $pageData['id'] . ' ' . $pageData['objectNumber'] . ' 0 R');
  120. }
  121. parent::_putxobjectdict();
  122. }
  123. /**
  124. * @inheritdoc
  125. */
  126. protected function _put($s, $newLine = true)
  127. {
  128. if ($newLine) {
  129. $this->buffer .= $s . "\n";
  130. } else {
  131. $this->buffer .= $s;
  132. }
  133. }
  134. }