/** * Object constructor * * @param \Zend\Pdf\InternalType\DictionaryObject $dict * @param \Zend\Pdf\InternalType\IndirectObjectReference\Context $context * @param \Zend\Pdf\Trailer\AbstractTrailer $prev */ public function __construct(InternalType\DictionaryObject $dict, InternalType\IndirectObjectReference\Context $context, AbstractTrailer $prev = null) { parent::__construct($dict); $this->_context = $context; $this->_prev = $prev; }
/** * Object constructor * * @param \Zend\Pdf\InternalType\DictionaryObject $dict */ public function __construct(InternalType\DictionaryObject $dict) { parent::__construct($dict); }
/** * Render the completed PDF to a string. * If $newSegmentOnly is true, 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) { // Save document properties if necessary if ($this->properties != $this->_originalProperties) { $docInfo = $this->_objFactory->newObject(new InternalType\DictionaryObject()); foreach ($this->properties as $key => $value) { switch ($key) { case 'Trapped': switch ($value) { case true: $docInfo->{$key} = new InternalType\NameObject('True'); break; case false: $docInfo->{$key} = new InternalType\NameObject('False'); break; case null: $docInfo->{$key} = new InternalType\NameObject('Unknown'); break; default: throw new Exception\LogicException('Wrong Trapped document property vale: \'' . $value . '\'. Only true, false and null values are allowed.'); break; } case 'CreationDate': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'ModDate': $docInfo->{$key} = new InternalType\StringObject((string) $value); break; case 'Title': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'Author': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'Subject': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'Keywords': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'Creator': // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted // break intentionally omitted case 'Producer': if (extension_loaded('mbstring') === true) { $detected = mb_detect_encoding($value); if ($detected !== 'ASCII') { $value = chr(254) . chr(255) . mb_convert_encoding($value, 'UTF-16', $detected); } } $docInfo->{$key} = new InternalType\StringObject((string) $value); break; default: // Set property using PDF type based on PHP type $docInfo->{$key} = InternalType\AbstractTypeObject::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 ''; } }