/** * Object constructor. * * If resource is not a Zend_Pdf_Element object, then stream object with specified value is * generated. * * @param Zend_Pdf_Element|string $resource */ public function __construct($resource) { $this->_objectFactory = Zend_Pdf_ElementFactory::createFactory(1); if ($resource instanceof Zend_Pdf_Element) { $this->_resource = $this->_objectFactory->newObject($resource); } else { $this->_resource = $this->_objectFactory->newStreamObject($resource); } }
/** * Object constructor. * * If resource is not a Zend_Pdf_Element object, then stream object with specified value is * generated. * * @param Zend_Pdf_Element|string $resource */ public function __construct($resource) { if ($resource instanceof Zend_Pdf_Element_Object) { $this->_objectFactory = $resource->getFactory(); $this->_resource = $resource; return; } require_once 'Zend/Pdf/ElementFactory.php'; $this->_objectFactory = Zend_Pdf_ElementFactory::createFactory(1); if ($resource instanceof Zend_Pdf_Element) { $this->_resource = $this->_objectFactory->newObject($resource); } else { $this->_resource = $this->_objectFactory->newStreamObject($resource); } }
/** * * @param Zend_Pdf_Annotation $annotation * @return Zend_Pdf_Page */ public function attachAnnotation(Zend_Pdf_Annotation $annotation) { $annotationDictionary = $annotation->getResource(); if (!$annotationDictionary instanceof Zend_Pdf_Element_Object && !$annotationDictionary instanceof Zend_Pdf_Element_Reference) { $annotationDictionary = $this->_objFactory->newObject($annotationDictionary); } if ($this->_pageDictionary->Annots === null) { $this->_pageDictionary->touch(); $this->_pageDictionary->Annots = new Zend_Pdf_Element_Array(); } else { $this->_pageDictionary->Annots->touch(); } $this->_pageDictionary->Annots->items[] = $annotationDictionary; $annotationDictionary->touch(); $annotationDictionary->P = $this->_pageDictionary; return $this; }
/** * Generate new Zend_Pdf_Element_Object * * @todo Reusage of the freed object. It's not a support of new feature, but only improvement. * * @param Zend_Pdf_Element $objectValue * @return Zend_Pdf_Element_Object */ public function newObject(Zend_Pdf_Element $objectValue) { return $this->_factory->newObject($objectValue); }
/** * Object constructor. * Constructor signatures: * * 1. Load PDF page from a parsed PDF file. * Object factory is created by PDF parser. * --------------------------------------------------------- * new Zend_Pdf_Page(Zend_Pdf_Element_Dictionary $pageDict, * Zend_Pdf_ElementFactory_Interface $factory); * --------------------------------------------------------- * * 2. Clone PDF page. * New page is created in the same context as source page. Object factory is shared. * Thus it will be attached to the document, but need to be placed into Zend_Pdf::$pages array * to be included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(Zend_Pdf_Page $page); * --------------------------------------------------------- * * 3. Create new page with a specified pagesize. * If $factory is null then it will be created and page must be attached to the document to be * included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(string $pagesize, Zend_Pdf_ElementFactory_Interface $factory = null); * --------------------------------------------------------- * * 4. Create new page with a specified pagesize (in default user space units). * If $factory is null then it will be created and page must be attached to the document to be * included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(numeric $width, numeric $height, Zend_Pdf_ElementFactory_Interface $factory = null); * --------------------------------------------------------- * * * @param mixed $param1 * @param mixed $param2 * @param mixed $param3 * @throws Zend_Pdf_Exception */ public function __construct($param1, $param2 = null, $param3 = null) { if ($param1 instanceof Zend_Pdf_Element_Reference && $param1->getType() == Zend_Pdf_Element::TYPE_DICTIONARY && $param2 instanceof Zend_Pdf_ElementFactory_Interface && $param3 === null) { $this->_pageDictionary = $param1; $this->_objFactory = $param2; $this->_attached = true; return; } else { if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) { /** @todo implementation */ throw new Zend_Pdf_Exception('Not implemented yet.'); } else { if (is_string($param1) && ($param2 === null || $param2 instanceof Zend_Pdf_ElementFactory_Interface) && $param3 === null) { $this->_objFactory = $param2 !== null ? $param2 : Zend_Pdf_ElementFactory::createFactory(1); $this->_attached = false; switch (strtolower($param1)) { case 'a4': $param1 = Zend_Pdf_Page::SIZE_A4; break; case 'a4-landscape': $param1 = Zend_Pdf_Page::SIZE_A4_LANDSCAPE; break; case 'letter': $param1 = Zend_Pdf_Page::SIZE_LETTER; break; case 'letter-landscape': $param1 = Zend_Pdf_Page::SIZE_LETTER_LANDSCAPE; break; default: // should be in "x:y" form } $pageDim = explode(':', $param1); if (count($pageDim) == 3) { $pageWidth = $pageDim[0]; $pageHeight = $pageDim[1]; } else { /** * @todo support of user defined pagesize notations, like: * "210x297mm", "595x842", "8.5x11in", "612x792" */ throw new Zend_Pdf_Exception('Wrong pagesize notation.'); } /** * @todo support of pagesize recalculation to "default user space units" */ } else { if (is_numeric($param1) && is_numeric($param2) && ($param3 === null || $param3 instanceof Zend_Pdf_ElementFactory_Interface)) { $this->_objFactory = $param3 !== null ? $param3 : Zend_Pdf_ElementFactory::createFactory(1); $this->_attached = false; $pageWidth = $param1; $pageHeight = $param2; } else { throw new Zend_Pdf_Exception('Unrecognized method signature, wrong number of arguments or wrong argument types.'); } } } } $this->_pageDictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary()); $this->_pageDictionary->Type = new Zend_Pdf_Element_Name('Page'); $this->_pageDictionary->LastModified = new Zend_Pdf_Element_String(Zend_Pdf::pdfDate()); $this->_pageDictionary->Resources = new Zend_Pdf_Element_Dictionary(); $this->_pageDictionary->MediaBox = new Zend_Pdf_Element_Array(); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageWidth); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageHeight); $this->_pageDictionary->Contents = new Zend_Pdf_Element_Array(); }
/** * Dump Outline and its child outlines into PDF structures * * Returns dictionary indirect object or reference * * @internal * @param Zend_Pdf_ElementFactory $factory object factory for newly created indirect objects * @param boolean $updateNavigation Update navigation flag * @param Zend_Pdf_Element $parent Parent outline dictionary reference * @param Zend_Pdf_Element $prev Previous outline dictionary reference * @param SplObjectStorage $processedOutlines List of already processed outlines * @return Zend_Pdf_Element * @throws Zend_Pdf_Exception */ public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory, $updateNavigation, Zend_Pdf_Element $parent, Zend_Pdf_Element $prev = null, SplObjectStorage $processedOutlines = null) { if ($processedOutlines === null) { $processedOutlines = new SplObjectStorage(); } $processedOutlines->attach($this); $outlineDictionary = $factory->newObject(new Zend_Pdf_Element_Dictionary()); $outlineDictionary->Title = new Zend_Pdf_Element_String($this->getTitle()); $target = $this->getTarget(); if ($target === null) { // Do nothing } else { if ($target instanceof Zend_Pdf_Destination) { $outlineDictionary->Dest = $target->getResource(); } else { if ($target instanceof Zend_Pdf_Action) { $outlineDictionary->A = $target->getResource(); } else { require_once 'Zend/Pdf/Exception.php'; throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination, Zend_Pdf_Action object or null'); } } } $color = $this->getColor(); if ($color !== null) { $components = $color->getComponents(); $colorComponentElements = array(new Zend_Pdf_Element_Numeric($components[0]), new Zend_Pdf_Element_Numeric($components[1]), new Zend_Pdf_Element_Numeric($components[2])); $outlineDictionary->C = new Zend_Pdf_Element_Array($colorComponentElements); } if ($this->isItalic() || $this->isBold()) { $outlineDictionary->F = new Zend_Pdf_Element_Numeric(($this->isItalic() ? 1 : 0) | ($this->isBold() ? 2 : 0)); // Bit 2 - Bold } $outlineDictionary->Parent = $parent; $outlineDictionary->Prev = $prev; $lastChild = null; foreach ($this->childOutlines as $childOutline) { if ($processedOutlines->contains($childOutline)) { require_once 'Zend/Pdf/Exception.php'; throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.'); } if ($lastChild === null) { $lastChild = $childOutline->dumpOutline($factory, true, $outlineDictionary, null, $processedOutlines); $outlineDictionary->First = $lastChild; } else { $childOutlineDictionary = $childOutline->dumpOutline($factory, true, $outlineDictionary, $lastChild, $processedOutlines); $lastChild->Next = $childOutlineDictionary; $lastChild = $childOutlineDictionary; } } $outlineDictionary->Last = $lastChild; if (count($this->childOutlines) != 0) { $outlineDictionary->Count = new Zend_Pdf_Element_Numeric(($this->isOpen() ? 1 : -1) * count($this->childOutlines)); } return $outlineDictionary; }
/** * Render the completed PDF to a string. * If $newSegmentOnly is true and it's not a new document, * then only appended part of PDF is returned. * * @param boolean $newSegmentOnly * @param resource $outputStream * @return string * @throws Zend_Pdf_Exception */ public function render($newSegmentOnly = false, $outputStream = null) { if ($this->_isNewDocument) { // Drop full document first time even $newSegmentOnly is set to true $newSegmentOnly = false; $this->_isNewDocument = false; } // Save document properties if necessary if ($this->properties != $this->_originalProperties) { $docInfo = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary()); foreach ($this->properties as $key => $value) { switch ($key) { case 'Trapped': switch ($value) { case true: $docInfo->$key = new Zend_Pdf_Element_Name('True'); break; case false: $docInfo->$key = new Zend_Pdf_Element_Name('False'); break; case null: $docInfo->$key = new Zend_Pdf_Element_Name('Unknown'); break; default: require_once 'Zend/Pdf/Exception.php'; throw new Zend_Pdf_Exception('Wrong Trapped document property vale: \'' . $value . '\'. Only true, false and null values are allowed.'); break; } case 'CreationDate': // break intentionally omitted case 'ModDate': $docInfo->$key = new Zend_Pdf_Element_String((string)$value); break; case 'Title': // break intentionally omitted case 'Author': // break intentionally omitted case 'Subject': // break intentionally omitted case 'Keywords': // break intentionally omitted case 'Creator': // break intentionally omitted case 'Producer': if (extension_loaded('mbstring') === true) { $detected = mb_detect_encoding($value); if ($detected !== 'ASCII') { $value = "\xfe\xff" . mb_convert_encoding($value, 'UTF-16', $detected); } } $docInfo->$key = new Zend_Pdf_Element_String((string)$value); break; default: // Set property using PDF type based on PHP type $docInfo->$key = Zend_Pdf_Element::phpToPdf($value); break; } } $this->_trailer->Info = $docInfo; } $this->_dumpPages(); $this->_dumpNamedDestinations(); $this->_dumpOutlines(); // Check, that PDF file was modified // File is always modified by _dumpPages() now, but future implementations may eliminate this. if (!$this->_objFactory->isModified()) { if ($newSegmentOnly) { // Do nothing, return return ''; } if ($outputStream === null) { return $this->_trailer->getPDFString(); } else { $pdfData = $this->_trailer->getPDFString(); while ( strlen($pdfData) > 0 && ($byteCount = fwrite($outputStream, $pdfData)) != false ) { $pdfData = substr($pdfData, $byteCount); } return ''; } } // offset (from a start of PDF file) of new PDF file segment $offset = $this->_trailer->getPDFLength(); // Last Object number in a list of free objects $lastFreeObject = $this->_trailer->getLastFreeObject(); // Array of cross-reference table subsections $xrefTable = array(); // Object numbers of first objects in each subsection $xrefSectionStartNums = array(); // Last cross-reference table subsection $xrefSection = array(); // Dummy initialization of the first element (specail case - header of linked list of free objects). $xrefSection[] = 0; $xrefSectionStartNums[] = 0; // Object number of last processed PDF object. // Used to manage cross-reference subsections. // Initialized by zero (specail case - header of linked list of free objects). $lastObjNum = 0; if ($outputStream !== null) { if (!$newSegmentOnly) { $pdfData = $this->_trailer->getPDFString(); while ( strlen($pdfData) > 0 && ($byteCount = fwrite($outputStream, $pdfData)) != false ) { $pdfData = substr($pdfData, $byteCount); } } } else { $pdfSegmentBlocks = ($newSegmentOnly) ? array() : array($this->_trailer->getPDFString()); } // Iterate objects to create new reference table foreach ($this->_objFactory->listModifiedObjects() as $updateInfo) { $objNum = $updateInfo->getObjNum(); if ($objNum - $lastObjNum != 1) { // Save cross-reference table subsection and start new one $xrefTable[] = $xrefSection; $xrefSection = array(); $xrefSectionStartNums[] = $objNum; } if ($updateInfo->isFree()) { // Free object cross-reference table entry $xrefSection[] = sprintf("%010d %05d f \n", $lastFreeObject, $updateInfo->getGenNum()); $lastFreeObject = $objNum; } else { // In-use object cross-reference table entry $xrefSection[] = sprintf("%010d %05d n \n", $offset, $updateInfo->getGenNum()); $pdfBlock = $updateInfo->getObjectDump(); $offset += strlen($pdfBlock); if ($outputStream === null) { $pdfSegmentBlocks[] = $pdfBlock; } else { while ( strlen($pdfBlock) > 0 && ($byteCount = fwrite($outputStream, $pdfBlock)) != false ) { $pdfBlock = substr($pdfBlock, $byteCount); } } } $lastObjNum = $objNum; } // Save last cross-reference table subsection $xrefTable[] = $xrefSection; // Modify first entry (specail case - header of linked list of free objects). $xrefTable[0][0] = sprintf("%010d 65535 f \n", $lastFreeObject); $xrefTableStr = "xref\n"; foreach ($xrefTable as $sectId => $xrefSection) { $xrefTableStr .= sprintf("%d %d \n", $xrefSectionStartNums[$sectId], count($xrefSection)); foreach ($xrefSection as $xrefTableEntry) { $xrefTableStr .= $xrefTableEntry; } } $this->_trailer->Size->value = $this->_objFactory->getObjectCount(); $pdfBlock = $xrefTableStr . $this->_trailer->toString() . "startxref\n" . $offset . "\n" . "%%EOF\n"; $this->_objFactory->cleanEnumerationShiftCache(); if ($outputStream === null) { $pdfSegmentBlocks[] = $pdfBlock; return implode('', $pdfSegmentBlocks); } else { while ( strlen($pdfBlock) > 0 && ($byteCount = fwrite($outputStream, $pdfBlock)) != false ) { $pdfBlock = substr($pdfBlock, $byteCount); } return ''; } }
public function setEmbeddedJS($javascript = null) { /* * Names container */ if (null === $javascript || '' === $javascript) { throw new Zend_Pdf_Exception("Javascript must be set."); } $this->setJavaScript($javascript); $js_code = array("S" => new Zend_Pdf_Element_Name('JavaScript'), "JS" => new Zend_Pdf_Element_String($this->getJavascript())); $embed[] = new Zend_Pdf_Element_String('EmbeddedJS'); $embed[] = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary($js_code)); $js_ref = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary(array('Names' => new Zend_Pdf_Element_Array($embed)))); $this->_trailer->Root->Names = new Zend_Pdf_Element_Dictionary(array('JavaScript' => $js_ref)); }
/** * Set the transparancy * * $alpha == 0 - transparent * $alpha == 1 - opaque * * Transparency modes, supported by PDF: * Normal (default), Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, * SoftLight, Difference, Exclusion * * @param float $alpha * @param string $mode * @throws Zend_Pdf_Exception * @return Zend_Pdf_Page */ public function setAlpha($alpha, $mode = 'Normal') { if (!in_array($mode, array('Normal', 'Multiply', 'Screen', 'Overlay', 'Darken', 'Lighten', 'ColorDodge', 'ColorBurn', 'HardLight', 'SoftLight', 'Difference', 'Exclusion'))) { throw new Zend_Pdf_Exception('Unsupported transparency mode.'); } if (!is_numeric($alpha) || $alpha < 0 || $alpha > 1) { throw new Zend_Pdf_Exception('Alpha value must be numeric between 0 (transparent) and 1 (opaque).'); } $this->_addProcSet('Text'); $this->_addProcSet('PDF'); $resources = $this->_pageDictionary->Resources; // Check if Resources dictionary contains ExtGState entry if ($resources->ExtGState === null) { $resources->touch(); $resources->ExtGState = new Zend_Pdf_Element_Dictionary(); } else { $resources->ExtGState->touch(); } $idCounter = 1; do { $gStateName = 'GS' . $idCounter++; } while ($resources->ExtGState->{$gStateName} !== null); $gStateDictionary = new Zend_Pdf_Element_Dictionary(); $gStateDictionary->Type = new Zend_Pdf_Element_Name('ExtGState'); $gStateDictionary->BM = new Zend_Pdf_Element_Name($mode); $gStateDictionary->CA = new Zend_Pdf_Element_Numeric($alpha); $gStateDictionary->ca = new Zend_Pdf_Element_Numeric($alpha); $resources->ExtGState->{$gStateName} = $this->_objFactory->newObject($gStateDictionary); $gStateNameObj = new Zend_Pdf_Element_Name($gStateName); $this->_contents .= $gStateNameObj->toString() . " gs\n"; return $this; }
/** * Object constructor. * Constructor signatures: * * 1. Load PDF page from a parsed PDF file. * Object factory is created by PDF parser. * --------------------------------------------------------- * new Zend_Pdf_Page(Zend_Pdf_Element_Dictionary $pageDict, * Zend_Pdf_ElementFactory_Interface $factory); * --------------------------------------------------------- * * 2. Clone PDF page. * New page is created in the same context as source page. Object factory is shared. * Thus it will be attached to the document, but need to be placed into Zend_Pdf::$pages array * to be included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(Zend_Pdf_Page $page); * --------------------------------------------------------- * * 3. Create new page with a specified pagesize. * If $factory is null then it will be created and page must be attached to the document to be * included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(string $pagesize, Zend_Pdf_ElementFactory_Interface $factory = null); * --------------------------------------------------------- * * 4. Create new page with a specified pagesize (in default user space units). * If $factory is null then it will be created and page must be attached to the document to be * included into output. * --------------------------------------------------------- * new Zend_Pdf_Page(numeric $width, numeric $height, Zend_Pdf_ElementFactory_Interface $factory = null); * --------------------------------------------------------- * * * @param mixed $param1 * @param mixed $param2 * @param mixed $param3 * @throws Zend_Pdf_Exception */ public function __construct($param1, $param2 = null, $param3 = null) { if ($param1 instanceof Zend_Pdf_Element_Reference && $param1->getType() == Zend_Pdf_Element::TYPE_DICTIONARY && $param2 instanceof Zend_Pdf_ElementFactory_Interface && $param3 === null) { $this->_pageDictionary = $param1; $this->_objFactory = $param2; $this->_attached = true; return; } else { if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) { // Clone existing page. // Let already existing content and resources to be shared between pages // We don't give existing content modification functionality, so we don't need "deep copy" $this->_objFactory = $param1->_objFactory; $this->_attached =& $param1->_attached; $this->_pageDictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary()); foreach ($param1->_pageDictionary->getKeys() as $key) { if ($key == 'Contents') { // Clone Contents property $this->_pageDictionary->Contents = new Zend_Pdf_Element_Array(); if ($param1->_pageDictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) { // Prepare array of content streams and add existing stream $this->_pageDictionary->Contents->items[] = $param1->_pageDictionary->Contents; } else { // Clone array of the content streams foreach ($param1->_pageDictionary->Contents->items as $srcContentStream) { $this->_pageDictionary->Contents->items[] = $srcContentStream; } } } else { $this->_pageDictionary->{$key} = $param1->_pageDictionary->{$key}; } } return; } else { if (is_string($param1) && ($param2 === null || $param2 instanceof Zend_Pdf_ElementFactory_Interface) && $param3 === null) { $this->_objFactory = $param2 !== null ? $param2 : Zend_Pdf_ElementFactory::createFactory(1); $this->_attached = false; switch (strtolower($param1)) { case 'a4': $param1 = Zend_Pdf_Page::SIZE_A4; break; case 'a4-landscape': $param1 = Zend_Pdf_Page::SIZE_A4_LANDSCAPE; break; case 'letter': $param1 = Zend_Pdf_Page::SIZE_LETTER; break; case 'letter-landscape': $param1 = Zend_Pdf_Page::SIZE_LETTER_LANDSCAPE; break; default: // should be in "x:y" form } $pageDim = explode(':', $param1); if (count($pageDim) == 3) { $pageWidth = $pageDim[0]; $pageHeight = $pageDim[1]; } else { /** * @todo support of user defined pagesize notations, like: * "210x297mm", "595x842", "8.5x11in", "612x792" */ throw new Zend_Pdf_Exception('Wrong pagesize notation.'); } /** * @todo support of pagesize recalculation to "default user space units" */ } else { if (is_numeric($param1) && is_numeric($param2) && ($param3 === null || $param3 instanceof Zend_Pdf_ElementFactory_Interface)) { $this->_objFactory = $param3 !== null ? $param3 : Zend_Pdf_ElementFactory::createFactory(1); $this->_attached = false; $pageWidth = $param1; $pageHeight = $param2; } else { throw new Zend_Pdf_Exception('Unrecognized method signature, wrong number of arguments or wrong argument types.'); } } } } $this->_pageDictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary()); $this->_pageDictionary->Type = new Zend_Pdf_Element_Name('Page'); $this->_pageDictionary->LastModified = new Zend_Pdf_Element_String(Zend_Pdf::pdfDate()); $this->_pageDictionary->Resources = new Zend_Pdf_Element_Dictionary(); $this->_pageDictionary->MediaBox = new Zend_Pdf_Element_Array(); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageWidth); $this->_pageDictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageHeight); $this->_pageDictionary->Contents = new Zend_Pdf_Element_Array(); }
/** * Load pages recursively * * @param Zend_Pdf_Element_Reference $pages * @param array|null $attributes */ private function _loadPages(Zend_Pdf_Element_Reference $pages, $attributes = array()) { if ($pages->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) { throw new Zend_Pdf_Exception('Wrong argument'); } foreach ($pages->getKeys() as $property) { if (in_array($property, self::$_inheritableAttributes)) { $attributes[$property] = $pages->{$property}; $pages->{$property} = null; } } foreach ($pages->Kids->items as $child) { if ($child->Type->value == 'Pages') { $this->_loadPages($child, $attributes); } else { if ($child->Type->value == 'Page') { foreach (self::$_inheritableAttributes as $property) { if ($child->{$property} === null && array_key_exists($property, $attributes)) { /** * Important note. * If any attribute or dependant object is an indirect object, then it's still * shared between pages. */ if ($attributes[$property] instanceof Zend_Pdf_Element_Object) { $child->{$property} = $attributes[$property]; } else { $child->{$property} = $this->_objFactory->newObject($attributes[$property]); } } } $this->pages[] = new Zend_Pdf_Page($child, $this->_objFactory); } } } }