Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Page.php
Go to the documentation of this file.
1 <?php
23 #require_once 'Zend/Pdf/Element.php';
24 #require_once 'Zend/Pdf/Element/Array.php';
25 #require_once 'Zend/Pdf/Element/String/Binary.php';
26 #require_once 'Zend/Pdf/Element/Boolean.php';
27 #require_once 'Zend/Pdf/Element/Dictionary.php';
28 #require_once 'Zend/Pdf/Element/Name.php';
29 #require_once 'Zend/Pdf/Element/Null.php';
30 #require_once 'Zend/Pdf/Element/Numeric.php';
31 #require_once 'Zend/Pdf/Element/String.php';
32 #require_once 'Zend/Pdf/Resource/Unified.php';
33 
34 #require_once 'Zend/Pdf/Canvas/Abstract.php';
35 
36 
45 {
46  /**** Class Constants ****/
47 
48 
49  /* Page Sizes */
50 
54  const SIZE_A4 = '595:842:';
55 
59  const SIZE_A4_LANDSCAPE = '842:595:';
60 
64  const SIZE_LETTER = '612:792:';
65 
69  const SIZE_LETTER_LANDSCAPE = '792:612:';
70 
71 
72  /* Shape Drawing */
73 
77  const SHAPE_DRAW_STROKE = 0;
78 
82  const SHAPE_DRAW_FILL = 1;
83 
88 
89 
90  /* Shape Filling Methods */
91 
96 
101 
102 
103  /* Line Dash Types */
104 
109 
110 
111 
117  protected $_dictionary;
118 
124  protected $_objFactory = null;
125 
132  protected $_attached;
133 
143  protected $_safeGS;
144 
184  public function __construct($param1, $param2 = null, $param3 = null)
185  {
186  if (($param1 instanceof Zend_Pdf_Element_Reference ||
187  $param1 instanceof Zend_Pdf_Element_Object
188  ) &&
189  $param2 instanceof Zend_Pdf_ElementFactory_Interface &&
190  $param3 === null
191  ) {
192  switch ($param1->getType()) {
194  $this->_dictionary = $param1;
195  $this->_objFactory = $param2;
196  $this->_attached = true;
197  $this->_safeGS = false;
198  return;
199  break;
200 
202  $this->_objFactory = $param2;
203  $pageWidth = $pageHeight = 0;
204  break;
205 
206  default:
207  #require_once 'Zend/Pdf/Exception.php';
208  throw new Zend_Pdf_Exception('Unrecognized object type.');
209  break;
210 
211  }
212  } else if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) {
213  // Duplicate existing page.
214  // Let already existing content and resources to be shared between pages
215  // We don't give existing content modification functionality, so we don't need "deep copy"
216  $this->_objFactory = $param1->_objFactory;
217  $this->_attached = &$param1->_attached;
218  $this->_safeGS = false;
219 
220  $this->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
221 
222  foreach ($param1->_dictionary->getKeys() as $key) {
223  if ($key == 'Contents') {
224  // Clone Contents property
225 
226  $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
227 
228  if ($param1->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
229  // Prepare array of content streams and add existing stream
230  $this->_dictionary->Contents->items[] = $param1->_dictionary->Contents;
231  } else {
232  // Clone array of the content streams
233  foreach ($param1->_dictionary->Contents->items as $srcContentStream) {
234  $this->_dictionary->Contents->items[] = $srcContentStream;
235  }
236  }
237  } else {
238  $this->_dictionary->$key = $param1->_dictionary->$key;
239  }
240  }
241 
242  return;
243  } else if (is_string($param1) &&
244  ($param2 === null || $param2 instanceof Zend_Pdf_ElementFactory_Interface) &&
245  $param3 === null) {
246  if ($param2 !== null) {
247  $this->_objFactory = $param2;
248  } else {
249  #require_once 'Zend/Pdf/ElementFactory.php';
250  $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
251  }
252  $this->_attached = false;
253  $this->_safeGS = true;
255  switch (strtolower($param1)) {
256  case 'a4':
257  $param1 = Zend_Pdf_Page::SIZE_A4;
258  break;
259  case 'a4-landscape':
261  break;
262  case 'letter':
263  $param1 = Zend_Pdf_Page::SIZE_LETTER;
264  break;
265  case 'letter-landscape':
267  break;
268  default:
269  // should be in "x:y" or "x:y:" form
270  }
271 
272  $pageDim = explode(':', $param1);
273  if(count($pageDim) == 2 || count($pageDim) == 3) {
274  $pageWidth = $pageDim[0];
275  $pageHeight = $pageDim[1];
276  } else {
281  #require_once 'Zend/Pdf/Exception.php';
282  throw new Zend_Pdf_Exception('Wrong pagesize notation.');
283  }
288  } else if (is_numeric($param1) && is_numeric($param2) &&
289  ($param3 === null || $param3 instanceof Zend_Pdf_ElementFactory_Interface)) {
290  if ($param3 !== null) {
291  $this->_objFactory = $param3;
292  } else {
293  #require_once 'Zend/Pdf/ElementFactory.php';
294  $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
295  }
296 
297  $this->_attached = false;
298  $this->_safeGS = true;
299  $pageWidth = $param1;
300  $pageHeight = $param2;
301 
302  } else {
303  #require_once 'Zend/Pdf/Exception.php';
304  throw new Zend_Pdf_Exception('Unrecognized method signature, wrong number of arguments or wrong argument types.');
305  }
306 
307  $this->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
308  $this->_dictionary->Type = new Zend_Pdf_Element_Name('Page');
309  #require_once 'Zend/Pdf.php';
310  $this->_dictionary->LastModified = new Zend_Pdf_Element_String(Zend_Pdf::pdfDate());
311  $this->_dictionary->Resources = new Zend_Pdf_Element_Dictionary();
312  $this->_dictionary->MediaBox = new Zend_Pdf_Element_Array();
313  $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
314  $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
315  $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageWidth);
316  $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageHeight);
317  $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
318  }
319 
320 
334  {
335  // Check that Resources dictionary contains appropriate resource set
336  if ($this->_dictionary->Resources->$type === null) {
337  $this->_dictionary->Resources->touch();
338  $this->_dictionary->Resources->$type = new Zend_Pdf_Element_Dictionary();
339  } else {
340  $this->_dictionary->Resources->$type->touch();
341  }
342 
343  // Check, that resource is already attached to resource set.
344  $resObject = $resource->getResource();
345  foreach ($this->_dictionary->Resources->$type->getKeys() as $ResID) {
346  if ($this->_dictionary->Resources->$type->$ResID === $resObject) {
347  return $ResID;
348  }
349  }
350 
351  $idCounter = 1;
352  do {
353  $newResName = $type[0] . $idCounter++;
354  } while ($this->_dictionary->Resources->$type->$newResName !== null);
355 
356  $this->_dictionary->Resources->$type->$newResName = $resObject;
357  $this->_objFactory->attach($resource->getFactory());
358 
359  return $newResName;
360  }
361 
367  protected function _addProcSet($procSetName)
368  {
369  // Check that Resources dictionary contains ProcSet entry
370  if ($this->_dictionary->Resources->ProcSet === null) {
371  $this->_dictionary->Resources->touch();
372  $this->_dictionary->Resources->ProcSet = new Zend_Pdf_Element_Array();
373  } else {
374  $this->_dictionary->Resources->ProcSet->touch();
375  }
376 
377  foreach ($this->_dictionary->Resources->ProcSet->items as $procSetEntry) {
378  if ($procSetEntry->value == $procSetName) {
379  // Procset is already included into a ProcSet array
380  return;
381  }
382  }
383 
384  $this->_dictionary->Resources->ProcSet->items[] = new Zend_Pdf_Element_Name($procSetName);
385  }
386 
416  public function getResources()
417  {
418  $resources = array();
419  $resDictionary = $this->_dictionary->Resources;
420 
421  foreach ($resDictionary->getKeys() as $resType) {
422  $resources[$resType] = array();
423 
424  if ($resType == 'ProcSet') {
425  foreach ($resDictionary->ProcSet->items as $procSetEntry) {
426  $resources[$resType][] = $procSetEntry->value;
427  }
428  } else {
429  $resMap = $resDictionary->$resType;
430 
431  foreach ($resMap->getKeys() as $resId) {
432  $resources[$resType][$resId] =new Zend_Pdf_Resource_Unified($resMap->$resId);
433  }
434  }
435  }
436 
437  return $resources;
438  }
439 
448  public function getContents()
449  {
451  }
452 
458  public function getHeight()
459  {
460  return $this->_dictionary->MediaBox->items[3]->value -
461  $this->_dictionary->MediaBox->items[1]->value;
462  }
463 
469  public function getWidth()
470  {
471  return $this->_dictionary->MediaBox->items[2]->value -
472  $this->_dictionary->MediaBox->items[0]->value;
473  }
474 
479  public function __clone()
480  {
482  $processed = array();
483 
484  // Clone dictionary object.
485  // Do it explicitly to prevent sharing page attributes between different
486  // results of clonePage() operation (other resources are still shared)
487  $dictionary = new Zend_Pdf_Element_Dictionary();
488  foreach ($this->_dictionary->getKeys() as $key) {
489  $dictionary->$key = $this->_dictionary->$key->makeClone($factory->getFactory(),
490  $processed,
492  }
493 
494  $this->_dictionary = $factory->newObject($dictionary);
495  $this->_objFactory = $factory;
496  $this->_attached = false;
497  $this->_style = null;
498  $this->_font = null;
499  }
500 
510  public function clonePage($factory, &$processed)
511  {
512  // Clone dictionary object.
513  // Do it explicitly to prevent sharing page attributes between different
514  // results of clonePage() operation (other resources are still shared)
515  $dictionary = new Zend_Pdf_Element_Dictionary();
516  foreach ($this->_dictionary->getKeys() as $key) {
517  $dictionary->$key = $this->_dictionary->$key->makeClone($factory->getFactory(),
518  $processed,
520  }
521 
522  $clonedPage = new Zend_Pdf_Page($factory->newObject($dictionary), $factory);
523  $clonedPage->_attached = false;
524 
525  return $clonedPage;
526  }
527 
534  public function getPageDictionary()
535  {
536  return $this->_dictionary;
537  }
538 
546  public function flush()
547  {
548  if ($this->_saveCount != 0) {
549  #require_once 'Zend/Pdf/Exception.php';
550  throw new Zend_Pdf_Exception('Saved graphics state is not restored');
551  }
552 
553  if ($this->_contents == '') {
554  return;
555  }
556 
557  if ($this->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
562  $this->_dictionary->touch();
563 
564  $currentPageContents = $this->_dictionary->Contents;
565  $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
566  $this->_dictionary->Contents->items[] = $currentPageContents;
567  } else {
568  $this->_dictionary->Contents->touch();
569  }
570 
571  if ((!$this->_safeGS) && (count($this->_dictionary->Contents->items) != 0)) {
577  $this->_addProcSet('PDF');
578 
579  $newContentsArray = new Zend_Pdf_Element_Array();
580  $newContentsArray->items[] = $this->_objFactory->newStreamObject(" q\n");
581  foreach ($this->_dictionary->Contents->items as $contentStream) {
582  $newContentsArray->items[] = $contentStream;
583  }
584  $newContentsArray->items[] = $this->_objFactory->newStreamObject(" Q\n");
585 
586  $this->_dictionary->touch();
587  $this->_dictionary->Contents = $newContentsArray;
588 
589  $this->_safeGS = true;
590  }
591 
592  $this->_dictionary->Contents->items[] =
593  $this->_objFactory->newStreamObject($this->_contents);
594 
595  $this->_contents = '';
596  }
597 
606  public function render(Zend_Pdf_ElementFactory_Interface $objFactory)
607  {
608  $this->flush();
609 
610  if ($objFactory === $this->_objFactory) {
611  // Page is already attached to the document.
612  return;
613  }
614 
615  if ($this->_attached) {
616  #require_once 'Zend/Pdf/Exception.php';
617  throw new Zend_Pdf_Exception('Page is attached to other documen. Use clone $page to get it context free.');
618  } else {
619  $objFactory->attach($this->_objFactory);
620  }
621  }
622 
633  public function extractResources()
634  {
635  return $this->_dictionary->Resources;
636  }
637 
646  public function extractFonts()
647  {
648  if ($this->_dictionary->Resources->Font === null) {
649  // Page doesn't have any font attached
650  // Return empty array
651  return array();
652  }
653 
654  $fontResources = $this->_dictionary->Resources->Font;
655 
656  $fontResourcesUnique = array();
657  foreach ($fontResources->getKeys() as $fontResourceName) {
658  $fontDictionary = $fontResources->$fontResourceName;
659 
660  if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference ||
661  $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
662  #require_once 'Zend/Pdf/Exception.php';
663  throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
664  }
665 
666  $fontResourcesUnique[spl_object_hash($fontDictionary->getObject())] = $fontDictionary;
667  }
668 
669  $fonts = array();
670  #require_once 'Zend/Pdf/Exception.php';
671  foreach ($fontResourcesUnique as $resourceId => $fontDictionary) {
672  try {
673  #require_once 'Zend/Pdf/Resource/Font/Extracted.php';
674  // Try to extract font
675  $extractedFont = new Zend_Pdf_Resource_Font_Extracted($fontDictionary);
676 
677  $fonts[$resourceId] = $extractedFont;
678  } catch (Zend_Pdf_Exception $e) {
679  if ($e->getMessage() != 'Unsupported font type.') {
680  throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
681  }
682  }
683  }
684 
685  return $fonts;
686  }
687 
696  public function extractFont($fontName)
697  {
698  if ($this->_dictionary->Resources->Font === null) {
699  // Page doesn't have any font attached
700  return null;
701  }
702 
703  $fontResources = $this->_dictionary->Resources->Font;
704 
705  $fontResourcesUnique = array();
706 
707  #require_once 'Zend/Pdf/Exception.php';
708  foreach ($fontResources->getKeys() as $fontResourceName) {
709  $fontDictionary = $fontResources->$fontResourceName;
710 
711  if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference ||
712  $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
713  #require_once 'Zend/Pdf/Exception.php';
714  throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
715  }
716 
717  $resourceId = spl_object_hash($fontDictionary->getObject());
718  if (isset($fontResourcesUnique[$resourceId])) {
719  continue;
720  } else {
721  // Mark resource as processed
722  $fontResourcesUnique[$resourceId] = 1;
723  }
724 
725  if ($fontDictionary->BaseFont->value != $fontName) {
726  continue;
727  }
728 
729  try {
730  // Try to extract font
731  #require_once 'Zend/Pdf/Resource/Font/Extracted.php';
732  return new Zend_Pdf_Resource_Font_Extracted($fontDictionary);
733  } catch (Zend_Pdf_Exception $e) {
734  if ($e->getMessage() != 'Unsupported font type.') {
735  throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
736  }
737 
738  // Continue searhing font with specified name
739  }
740  }
741 
742  return null;
743  }
744 
750  public function attachAnnotation(Zend_Pdf_Annotation $annotation)
751  {
752  $annotationDictionary = $annotation->getResource();
753  if (!$annotationDictionary instanceof Zend_Pdf_Element_Object &&
754  !$annotationDictionary instanceof Zend_Pdf_Element_Reference) {
755  $annotationDictionary = $this->_objFactory->newObject($annotationDictionary);
756  }
757 
758  if ($this->_dictionary->Annots === null) {
759  $this->_dictionary->touch();
760  $this->_dictionary->Annots = new Zend_Pdf_Element_Array();
761  } else {
762  $this->_dictionary->Annots->touch();
763  }
764 
765  $this->_dictionary->Annots->items[] = $annotationDictionary;
766 
767  $annotationDictionary->touch();
768  $annotationDictionary->P = $this->_dictionary;
769 
770  return $this;
771  }
772 }
773 
const FILL_METHOD_NON_ZERO_WINDING
Definition: Page.php:95
const LINE_DASHING_SOLID
Definition: Page.php:108
const SIZE_A4_LANDSCAPE
Definition: Page.php:59
static pdfDate($timestamp=null)
Definition: Pdf.php:1625
const TYPE_ARRAY
Definition: Element.php:36
const FILL_METHOD_EVEN_ODD
Definition: Page.php:100
getContents()
Definition: Page.php:448
render(Zend_Pdf_ElementFactory_Interface $objFactory)
Definition: Page.php:606
$resource
Definition: bulk.php:12
const TYPE_DICTIONARY
Definition: Element.php:37
const SIZE_LETTER_LANDSCAPE
Definition: Page.php:69
getResources()
Definition: Page.php:416
$type
Definition: item.phtml:13
const SIZE_LETTER
Definition: Page.php:64
extractFonts()
Definition: Page.php:646
clonePage($factory, &$processed)
Definition: Page.php:510
extractResources()
Definition: Page.php:633
_attachResource($type, Zend_Pdf_Resource $resource)
Definition: Page.php:333
const SHAPE_DRAW_STROKE
Definition: Page.php:77
attach(Zend_Pdf_ElementFactory_Interface $factory)
const TYPE_NULL
Definition: Element.php:39
__construct($param1, $param2=null, $param3=null)
Definition: Page.php:184
const SHAPE_DRAW_FILL
Definition: Page.php:82
_addProcSet($procSetName)
Definition: Page.php:367
getPageDictionary()
Definition: Page.php:534
const SHAPE_DRAW_FILL_AND_STROKE
Definition: Page.php:87
static createFactory($objCount)
attachAnnotation(Zend_Pdf_Annotation $annotation)
Definition: Page.php:750
extractFont($fontName)
Definition: Page.php:696
const CLONE_MODE_SKIP_PAGES
Definition: Element.php:67
const SIZE_A4
Definition: Page.php:54