Example #1
0
 /**
  * Dump object to a string to save within PDF file
  *
  * $factory parameter defines operation context.
  *
  * @param Zend_Pdf_ElementFactory $factory
  * @return string
  */
 public function dump(Zend_Pdf_ElementFactory $factory)
 {
     $shift = $factory->getEnumerationShift($this->_factory);
     // Update stream length
     $this->dictionary->Length->value = $this->length();
     return $this->_objNum + $shift . " " . $this->_genNum . " obj \n" . $this->dictionary->toString($factory) . "\n" . $this->_value->toString($factory) . "\n" . "endobj\n";
 }
Example #2
0
 /**
  * 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->_processedFacories = array();
     $this->_objectFactory = new Zend_Pdf_ElementFactory(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)
 {
     $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);
     }
 }
Example #4
0
 /**
  * Dereference.
  * Take inderect object, take $value member of this object (must be Zend_Pdf_Element),
  * take reference to the $value member of this object and assign it to
  * $value member of current PDF Reference object
  * $obj can be null
  *
  * @throws Zend_Pdf_Exception
  */
 private function _dereference()
 {
     $obj = $this->_context->getParser()->getObject($this->_context->getRefTable()->getOffset($this->_objNum . ' ' . $this->_genNum . ' R'), $this->_context);
     if ($obj === null) {
         $this->_ref = new Zend_Pdf_Element_Null();
         return;
     }
     if ($obj->toString() != $this->_objNum . ' ' . $this->_genNum . ' R') {
         throw new Zend_Pdf_Exception('Incorrect reference to the object');
     }
     $this->_ref = $obj;
     $this->setParentObject($obj);
     $this->_factory->registerObject($this);
 }
Example #5
0
 /**
  * Dereference.
  * Take inderect object, take $value member of this object (must be Zend_Pdf_Element),
  * take reference to the $value member of this object and assign it to
  * $value member of current PDF Reference object
  * $obj can be null
  *
  * @throws Zend_Pdf_Exception
  */
 private function _dereference()
 {
     if (($obj = $this->_factory->fetchObject($this->_objNum . ' ' . $this->_genNum)) === null) {
         $obj = $this->_context->getParser()->getObject($this->_context->getRefTable()->getOffset($this->_objNum . ' ' . $this->_genNum . ' R'), $this->_context);
     }
     if ($obj === null) {
         $this->_ref = new Zend_Pdf_Element_Null();
         return;
     }
     if ($obj->toString() != $this->_objNum . ' ' . $this->_genNum . ' R') {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception('Incorrect reference to the object');
     }
     $this->_ref = $obj;
 }
Example #6
0
 /**
  * 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);
     }
 }
Example #7
0
 /**
  * Object constructor.
  *
  * @param Zend_Pdf_Element_Object $extGStateObject
  * @throws Zend_Pdf_Exception
  */
 public function __construct(Zend_Pdf_Element_Object $extGStateObject = null)
 {
     if ($extGStateObject == null) {
         // Create new Graphics State object
         require_once 'Zend/Pdf/ElementFactory.php';
         $factory = Zend_Pdf_ElementFactory::createFactory(1);
         $gsDictionary = new Zend_Pdf_Element_Dictionary();
         $gsDictionary->Type = new Zend_Pdf_Element_Name('ExtGState');
         $extGStateObject = $factory->newObject($gsDictionary);
     }
     if ($extGStateObject->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception('Graphics state PDF object must be a dictionary');
     }
     parent::__construct($gsDictionary);
 }
 /**
  * Render the completed PDF to a string.
  * If $newSegmentOnly is true, then only appended part of PDF is returned.
  *
  * @param boolean $newSegmentOnly
  * @return string
  */
 public function render($newSegmentOnly = false)
 {
     $this->_dumpPages();
     // 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) {
             return '';
         } else {
             return $this->_trailer->getPDFString();
         }
     }
     // offset (from a start of PDF file) of new PDF file segment
     $segmentOffset = $this->_trailer->getPDFLength();
     // new PDF file segment itself
     $pdfSegment = '';
     // 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;
     // 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", $segmentOffset + strlen($pdfSegment), $updateInfo->getGenNum());
             $pdfSegment .= $updateInfo->getObjectDump();
         }
         $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;
         }
     }
     $xrefStartOffset = $segmentOffset + strlen($pdfSegment);
     $this->_trailer->Size->value = $this->_objFactory->getObjectCount();
     $pdfSegment .= $xrefTableStr . $this->_trailer->toString() . "startxref\n" . $xrefStartOffset . "\n" . "%%EOF\n";
     if ($newSegmentOnly) {
         return $pdfSegment;
     } else {
         return $this->_trailer->getPDFString() . $pdfSegment;
     }
 }
Example #9
0
    /**
     * Creates or loads PDF document.
     *
     * If $source is null, then it creates a new document.
     *
     * If $source is a string and $load is false, then it loads document
     * from a binary string.
     *
     * If $source is a string and $load is true, then it loads document
     * from a file.

     * $revision used to roll back document to specified version
     * (0 - current version, 1 - previous version, 2 - ...)
     *
     * @param string  $source - PDF file to load
     * @param integer $revision
     * @throws Zend_Pdf_Exception
     * @return Zend_Pdf
     */
    public function __construct($source = null, $revision = null, $load = false)
    {
        require_once 'Zend/Pdf/ElementFactory.php';
        $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);

        if ($source !== null) {
            require_once 'Zend/Pdf/Parser.php';
            $this->_parser           = new Zend_Pdf_Parser($source, $this->_objFactory, $load);
            $this->_pdfHeaderVersion = $this->_parser->getPDFVersion();
            $this->_trailer          = $this->_parser->getTrailer();
            if ($this->_trailer->Encrypt !== null) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Encrypted document modification is not supported');
            }
            if ($revision !== null) {
                $this->rollback($revision);
            } else {
                $this->_loadPages($this->_trailer->Root->Pages);
            }

            $this->_loadNamedDestinations($this->_trailer->Root, $this->_parser->getPDFVersion());
            $this->_loadOutlines($this->_trailer->Root);

            if ($this->_trailer->Info !== null) {
                $this->properties = $this->_trailer->Info->toPhp();

                if (isset($this->properties['Trapped'])) {
                    switch ($this->properties['Trapped']) {
                        case 'True':
                            $this->properties['Trapped'] = true;
                            break;

                        case 'False':
                            $this->properties['Trapped'] = false;
                            break;

                        case 'Unknown':
                            $this->properties['Trapped'] = null;
                            break;

                        default:
                            // Wrong property value
                            // Do nothing
                            break;
                    }
                }

                $this->_originalProperties = $this->properties;
            }

            $this->_isNewDocument = false;
        } else {
            $this->_pdfHeaderVersion = Zend_Pdf::PDF_VERSION;

            $trailerDictionary = new Zend_Pdf_Element_Dictionary();

            /**
             * Document id
             */
            $docId = md5(uniqid(rand(), true));   // 32 byte (128 bit) identifier
            $docIdLow  = substr($docId,  0, 16);  // first 16 bytes
            $docIdHigh = substr($docId, 16, 16);  // second 16 bytes

            $trailerDictionary->ID = new Zend_Pdf_Element_Array();
            $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdLow);
            $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdHigh);

            $trailerDictionary->Size = new Zend_Pdf_Element_Numeric(0);

            require_once 'Zend/Pdf/Trailer/Generator.php';
            $this->_trailer = new Zend_Pdf_Trailer_Generator($trailerDictionary);

            /**
             * Document catalog indirect object.
             */
            $docCatalog = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
            $docCatalog->Type    = new Zend_Pdf_Element_Name('Catalog');
            $docCatalog->Version = new Zend_Pdf_Element_Name(Zend_Pdf::PDF_VERSION);
            $this->_trailer->Root = $docCatalog;

            /**
             * Pages container
             */
            $docPages = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
            $docPages->Type  = new Zend_Pdf_Element_Name('Pages');
            $docPages->Kids  = new Zend_Pdf_Element_Array();
            $docPages->Count = new Zend_Pdf_Element_Numeric(0);
            $docCatalog->Pages = $docPages;
        }
    }
Example #10
0
 /**
  * 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();
 }
Example #11
0
 /**
  * Clone page, extract it and dependent objects from the current document,
  * so it can be used within other docs.
  */
 public function __clone()
 {
     $factory = Zend_Pdf_ElementFactory::createFactory(1);
     $processed = array();
     // Clone dictionary object.
     // Do it explicitly to prevent sharing page attributes between different
     // results of clonePage() operation (other resources are still shared)
     $dictionary = new Zend_Pdf_Element_Dictionary();
     foreach ($this->_dictionary->getKeys() as $key) {
         $dictionary->{$key} = $this->_dictionary->{$key}->makeClone($factory->getFactory(), $processed, Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
     }
     $this->_dictionary = $factory->newObject($dictionary);
     $this->_objFactory = $factory;
     $this->_attached = false;
     $this->_style = null;
     $this->_font = null;
 }
Example #12
0
 /**
  * Object constructor.
  */
 public function __construct()
 {
     $this->_factory = Zend_Pdf_ElementFactory::createFactory(1);
     $this->_processed = array();
 }
Example #13
0
 /**
  * Prepare page to be rendered into PDF.
  *
  * @todo Don't forget to close all current graphics operations (like path drawing)
  *
  * @param Zend_Pdf_ElementFactory $objFactory
  * @throws Zend_Pdf_Exception
  */
 public function render(Zend_Pdf_ElementFactory $objFactory)
 {
     $this->flush();
     if ($objFactory === $this->_objFactory) {
         // Page is already attached to the document.
         return;
     }
     if ($this->_attached) {
         throw new Zend_Pdf_Exception('Page is attached to one documen, but rendered in context of another.');
         /**
          * @todo Page cloning must be implemented here instead of exception.
          *       PDF objects (ex. fonts) can be shared between pages.
          *       Thus all referenced objects, which can be modified, must be cloned recursively,
          *       to avoid producing wrong object references in a context of source PDF.
          */
         //...
     } else {
         $objFactory->attach($this->_objFactory);
     }
 }
Example #14
0
 /**
  * Creates or loads PDF document.
  *
  * If $source is null, then it creates a new document.
  *
  * If $source is a string and $load is false, then it loads document
  * from a binary string.
  *
  * If $source is a string and $load is true, then it loads document
  * from a file.
  * $revision used to roll back document to specified version
  * (0 - currtent version, 1 - previous version, 2 - ...)
  *
  * @param string  $source - PDF file to load
  * @param integer $revision
  * @throws Zend_Pdf_Exception
  * @return Zend_Pdf
  */
 public function __construct($source = null, $revision = null, $load = false)
 {
     $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
     if ($source !== null) {
         $this->_parser = new Zend_Pdf_Parser($source, $this->_objFactory, $load);
         $this->_trailer = $this->_parser->getTrailer();
         if ($revision !== null) {
             $this->rollback($revision);
         } else {
             $this->_loadPages($this->_trailer->Root->Pages);
         }
         if ($this->_trailer->Info !== null) {
             foreach ($this->_trailer->Info->getKeys() as $key) {
                 $this->properties[$key] = $this->_trailer->Info->{$key}->value;
             }
             if (isset($this->properties['Trapped'])) {
                 switch ($this->properties['Trapped']) {
                     case 'True':
                         $this->properties['Trapped'] = true;
                         break;
                     case 'False':
                         $this->properties['Trapped'] = false;
                         break;
                     case 'Unknown':
                         $this->properties['Trapped'] = null;
                         break;
                     default:
                         // Wrong property value
                         // Do nothing
                         break;
                 }
             }
             $this->_originalProperties = $this->properties;
         }
     } else {
         $trailerDictionary = new Zend_Pdf_Element_Dictionary();
         /**
          * Document id
          */
         $docId = md5(uniqid(rand(), true));
         // 32 byte (128 bit) identifier
         $docIdLow = substr($docId, 0, 16);
         // first 16 bytes
         $docIdHigh = substr($docId, 16, 16);
         // second 16 bytes
         $trailerDictionary->ID = new Zend_Pdf_Element_Array();
         $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdLow);
         $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdHigh);
         $trailerDictionary->Size = new Zend_Pdf_Element_Numeric(0);
         $this->_trailer = new Zend_Pdf_Trailer_Generator($trailerDictionary);
         /**
          * Document catalog indirect object.
          */
         $docCatalog = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
         $docCatalog->Type = new Zend_Pdf_Element_Name('Catalog');
         $docCatalog->Version = new Zend_Pdf_Element_Name(Zend_Pdf::PDF_VERSION);
         $this->_trailer->Root = $docCatalog;
         /**
          * Pages container
          */
         $docPages = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
         $docPages->Type = new Zend_Pdf_Element_Name('Pages');
         $docPages->Kids = new Zend_Pdf_Element_Array();
         $docPages->Count = new Zend_Pdf_Element_Numeric(0);
         $docCatalog->Pages = $docPages;
     }
 }
Example #15
0
 /**
  * Creates or loads PDF document.
  *
  * If $source is null, then it creates a new document.
  *
  * If $source is a string and $load is false, then it loads document
  * from a binary string.
  *
  * If $source is a string and $load is true, then it loads document
  * from a file.
  * $revision used to roll back document to specified version
  * (0 - currtent version, 1 - previous version, 2 - ...)
  *
  * @param string  $source - PDF file to load
  * @param integer $revision
  * @throws Zend_Pdf_Exception
  * @return Zend_Pdf
  */
 public function __construct($source = null, $revision = null, $load = false)
 {
     $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
     if ($source !== null) {
         $this->_parser = new Zend_Pdf_Parser($source, $this->_objFactory, $load);
         $this->_trailer = $this->_parser->getTrailer();
         if ($revision !== null) {
             $this->rollback($revision);
         } else {
             $this->_loadPages($this->_trailer->Root->Pages);
         }
     } else {
         $trailerDictionary = new Zend_Pdf_Element_Dictionary();
         /**
          * Document id
          */
         $docId = md5(uniqid(rand(), true));
         // 32 byte (128 bit) identifier
         $docIdLow = substr($docId, 0, 16);
         // first 16 bytes
         $docIdHigh = substr($docId, 16, 16);
         // second 16 bytes
         $trailerDictionary->ID = new Zend_Pdf_Element_Array();
         $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdLow);
         $trailerDictionary->ID->items[] = new Zend_Pdf_Element_String_Binary($docIdHigh);
         $trailerDictionary->Size = new Zend_Pdf_Element_Numeric(0);
         $this->_trailer = new Zend_Pdf_Trailer_Generator($trailerDictionary);
         /**
          * Document catalog indirect object.
          */
         $docCatalog = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
         $docCatalog->Type = new Zend_Pdf_Element_Name('Catalog');
         $docCatalog->Version = new Zend_Pdf_Element_Name(Zend_Pdf::PDF_VERSION);
         $this->_trailer->Root = $docCatalog;
         /**
          * Pages container
          */
         $docPages = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
         $docPages->Type = new Zend_Pdf_Element_Name('Pages');
         $docPages->Kids = new Zend_Pdf_Element_Array();
         $docPages->Count = new Zend_Pdf_Element_Numeric(0);
         $docCatalog->Pages = $docPages;
     }
 }
Example #16
0
 /**
  * Object constructor
  *
  * Note: PHP duplicates string, which is sent by value, only of it's updated.
  * Thus we don't need to care about overhead
  *
  * @param mixed $source
  * @param Zend_Pdf_ElementFactory $factory
  * @param boolean $load
  * @throws Zend_Exception
  */
 public function __construct($source, Zend_Pdf_ElementFactory $factory, $load)
 {
     if ($load) {
         if (($pdfFile = @fopen($source, 'rb')) === false) {
             throw new Zend_Pdf_Exception("Can not open '{$source}' file for reading.");
         }
         $byteCount = filesize($source);
         $data = '';
         while ($byteCount > 0 && ($nextBlock = fread($pdfFile, $byteCount)) != false) {
             $data .= $nextBlock;
             $byteCount -= strlen($nextBlock);
         }
         fclose($pdfFile);
         $this->_stringParser = new Zend_Pdf_StringParser($data, $factory);
     } else {
         $this->_stringParser = new Zend_Pdf_StringParser($source, $factory);
     }
     $pdfVersionComment = $this->_stringParser->readComment();
     if (substr($pdfVersionComment, 0, 5) != '%PDF-') {
         throw new Zend_Pdf_Exception('File is not a PDF.');
     }
     $pdfVersion = (double) substr($pdfVersionComment, 5);
     if ($pdfVersion < 0.9 || $pdfVersion >= 1.61) {
         /**
          * @todo
          * To support PDF versions 1.5 (Acrobat 6) and PDF version 1.7 (Acrobat 7)
          * Stream compression filter must be implemented (for compressed object streams).
          * Cross reference streams must be implemented
          */
         throw new Zend_Pdf_Exception(sprintf('Unsupported PDF version. Zend_Pdf supports PDF 1.0-1.4. Current version - \'%f\'', $pdfVersion));
     }
     $this->_stringParser->offset = strrpos($this->_stringParser->data, '%%EOF');
     if ($this->_stringParser->offset === false || strlen($this->_stringParser->data) - $this->_stringParser->offset > 7) {
         throw new Zend_Pdf_Exception('Pdf file syntax error. End-of-fle marker expected at the end of file.');
     }
     $this->_stringParser->offset--;
     /**
      * Go to end of cross-reference table offset
      */
     while (Zend_Pdf_StringParser::isWhiteSpace(ord($this->_stringParser->data[$this->_stringParser->offset])) && $this->_stringParser->offset > 0) {
         $this->_stringParser->offset--;
     }
     /**
      * Go to the start of cross-reference table offset
      */
     while (!Zend_Pdf_StringParser::isWhiteSpace(ord($this->_stringParser->data[$this->_stringParser->offset])) && $this->_stringParser->offset > 0) {
         $this->_stringParser->offset--;
     }
     /**
      * Go to the end of 'startxref' keyword
      */
     while (Zend_Pdf_StringParser::isWhiteSpace(ord($this->_stringParser->data[$this->_stringParser->offset])) && $this->_stringParser->offset > 0) {
         $this->_stringParser->offset--;
     }
     /**
      * Go to the white space (eol marker) before 'startxref' keyword
      */
     $this->_stringParser->offset -= 9;
     $nextLexeme = $this->_stringParser->readLexeme();
     if ($nextLexeme != 'startxref') {
         throw new Zend_Pdf_Exception(sprintf('Pdf file syntax error. \'startxref\' keyword expected. Offset - 0x%X.', $this->_stringParser->offset - strlen($nextLexeme)));
     }
     $startXref = $this->_stringParser->readLexeme();
     if (!ctype_digit($startXref)) {
         throw new Zend_Pdf_Exception(sprintf('Pdf file syntax error. Cross-reference table offset must contain only digits. Offset - 0x%X.', $this->_stringParser->offset - strlen($nextLexeme)));
     }
     $this->_trailer = $this->_loadXRefTable($startXref);
     $factory->setObjectCount($this->_trailer->Size->value);
 }
Example #17
0
 /**
  * Dump object to a string to save within PDF file
  *
  * $factory parameter defines operation context.
  *
  * @param Zend_Pdf_ElementFactory $factory
  * @return string
  */
 public function dump(Zend_Pdf_ElementFactory $factory)
 {
     $shift = $factory->getEnumerationShift($this->_factory);
     if ($this->_streamDecoded) {
         $this->_initialDictionaryData = $this->_extractDictionaryData();
         $this->_encodeStream();
     } else {
         if ($this->_initialDictionaryData != null) {
             $newDictionary = $this->_extractDictionaryData();
             if ($this->_initialDictionaryData !== $newDictionary) {
                 $this->_decodeStream();
                 $this->_initialDictionaryData = $newDictionary;
                 $this->_encodeStream();
             }
         }
     }
     // Update stream length
     $this->dictionary->Length->value = $this->_value->length();
     return $this->_objNum + $shift . " " . $this->_genNum . " obj \n" . $this->dictionary->toString($factory) . "\n" . $this->_value->toString($factory) . "\n" . "endobj\n";
 }
Example #18
0
 /**
  * Object constructor
  *
  * @param string $imageFileName
  * @throws Zend_Pdf_Exception
  * @todo Add compression conversions to support compression strategys other than PNG_COMPRESSION_DEFAULT_STRATEGY.
  * @todo Add pre-compression filtering.
  * @todo Add interlaced image handling.
  * @todo Add support for 16-bit images. Requires PDF version bump to 1.5 at least.
  * @todo Add processing for all PNG chunks defined in the spec. gAMA etc.
  * @todo Fix tRNS chunk support for Indexed Images to a SMask.
  */
 public function __construct($imageFileName)
 {
     if (($imageFile = @fopen($imageFileName, 'rb')) === false) {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception("Can not open '{$imageFileName}' file for reading.");
     }
     parent::__construct();
     //Check if the file is a PNG
     fseek($imageFile, 1, SEEK_CUR);
     //First signature byte (%)
     if ('PNG' != fread($imageFile, 3)) {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception('Image is not a PNG');
     }
     fseek($imageFile, 12, SEEK_CUR);
     //Signature bytes (Includes the IHDR chunk) IHDR processed linerarly because it doesnt contain a variable chunk length
     $wtmp = unpack('Ni', fread($imageFile, 4));
     //Unpack a 4-Byte Long
     $width = $wtmp['i'];
     $htmp = unpack('Ni', fread($imageFile, 4));
     $height = $htmp['i'];
     $bits = ord(fread($imageFile, 1));
     //Higher than 8 bit depths are only supported in later versions of PDF.
     $color = ord(fread($imageFile, 1));
     $compression = ord(fread($imageFile, 1));
     $prefilter = ord(fread($imageFile, 1));
     if (($interlacing = ord(fread($imageFile, 1))) != Zend_Pdf_Resource_Image_Png::PNG_INTERLACING_DISABLED) {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception("Only non-interlaced images are currently supported.");
     }
     $this->_width = $width;
     $this->_height = $height;
     $this->_imageProperties = array();
     $this->_imageProperties['bitDepth'] = $bits;
     $this->_imageProperties['pngColorType'] = $color;
     $this->_imageProperties['pngFilterType'] = $prefilter;
     $this->_imageProperties['pngCompressionType'] = $compression;
     $this->_imageProperties['pngInterlacingType'] = $interlacing;
     fseek($imageFile, 4, SEEK_CUR);
     //4 Byte Ending Sequence
     $imageData = '';
     /*
      * The following loop processes PNG chunks. 4 Byte Longs are packed first give the chunk length
      * followed by the chunk signature, a four byte code. IDAT and IEND are manditory in any PNG.
      */
     while (!feof($imageFile)) {
         $chunkLengthBytes = fread($imageFile, 4);
         if ($chunkLengthBytes === false) {
             require_once 'Zend/Pdf/Exception.php';
             throw new Zend_Pdf_Exception('Error ocuured while image file reading.');
         }
         $chunkLengthtmp = unpack('Ni', $chunkLengthBytes);
         $chunkLength = $chunkLengthtmp['i'];
         $chunkType = fread($imageFile, 4);
         switch ($chunkType) {
             case 'IDAT':
                 //Image Data
                 /*
                  * Reads the actual image data from the PNG file. Since we know at this point that the compression
                  * strategy is the default strategy, we also know that this data is Zip compressed. We will either copy
                  * the data directly to the PDF and provide the correct FlateDecode predictor, or decompress the data
                  * decode the filters and output the data as a raw pixel map.
                  */
                 $imageData .= fread($imageFile, $chunkLength);
                 fseek($imageFile, 4, SEEK_CUR);
                 break;
             case 'PLTE':
                 //Palette
                 $paletteData = fread($imageFile, $chunkLength);
                 fseek($imageFile, 4, SEEK_CUR);
                 break;
             case 'tRNS':
                 //Basic (non-alpha channel) transparency.
                 $trnsData = fread($imageFile, $chunkLength);
                 switch ($color) {
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY:
                         $baseColor = ord(substr($trnsData, 1, 1));
                         $transparencyData = array(new Zend_Pdf_Element_Numeric($baseColor), new Zend_Pdf_Element_Numeric($baseColor));
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB:
                         $red = ord(substr($trnsData, 1, 1));
                         $green = ord(substr($trnsData, 3, 1));
                         $blue = ord(substr($trnsData, 5, 1));
                         $transparencyData = array(new Zend_Pdf_Element_Numeric($red), new Zend_Pdf_Element_Numeric($red), new Zend_Pdf_Element_Numeric($green), new Zend_Pdf_Element_Numeric($green), new Zend_Pdf_Element_Numeric($blue), new Zend_Pdf_Element_Numeric($blue));
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_INDEXED:
                         //Find the first transparent color in the index, we will mask that. (This is a bit of a hack. This should be a SMask and mask all entries values).
                         if (($trnsIdx = strpos($trnsData, "")) !== false) {
                             $transparencyData = array(new Zend_Pdf_Element_Numeric($trnsIdx), new Zend_Pdf_Element_Numeric($trnsIdx));
                         }
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY_ALPHA:
                         // Fall through to the next case
                     // Fall through to the next case
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA:
                         require_once 'Zend/Pdf/Exception.php';
                         throw new Zend_Pdf_Exception("tRNS chunk illegal for Alpha Channel Images");
                         break;
                 }
                 fseek($imageFile, 4, SEEK_CUR);
                 //4 Byte Ending Sequence
                 break;
             case 'IEND':
                 break 2;
                 //End the loop too
             //End the loop too
             default:
                 fseek($imageFile, $chunkLength + 4, SEEK_CUR);
                 //Skip the section
                 break;
         }
     }
     fclose($imageFile);
     $compressed = true;
     $imageDataTmp = '';
     $smaskData = '';
     switch ($color) {
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB:
             $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY:
             $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_INDEXED:
             if (empty($paletteData)) {
                 require_once 'Zend/Pdf/Exception.php';
                 throw new Zend_Pdf_Exception("PNG Corruption: No palette data read for indexed type PNG.");
             }
             $colorSpace = new Zend_Pdf_Element_Array();
             $colorSpace->items[] = new Zend_Pdf_Element_Name('Indexed');
             $colorSpace->items[] = new Zend_Pdf_Element_Name('DeviceRGB');
             $colorSpace->items[] = new Zend_Pdf_Element_Numeric(strlen($paletteData) / 3 - 1);
             $paletteObject = $this->_objectFactory->newObject(new Zend_Pdf_Element_String_Binary($paletteData));
             $colorSpace->items[] = $paletteObject;
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY_ALPHA:
             /*
              * To decode PNG's with alpha data we must create two images from one. One image will contain the Gray data
              * the other will contain the Gray transparency overlay data. The former will become the object data and the latter
              * will become the Shadow Mask (SMask).
              */
             if ($bits > 8) {
                 require_once 'Zend/Pdf/Exception.php';
                 throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
             }
             $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
             require_once 'Zend/Pdf/ElementFactory.php';
             $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
             $decodingStream = $decodingObjFactory->newStreamObject($imageData);
             $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
             $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
             $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
             $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
             $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(2);
             //GreyAlpha
             $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
             $decodingStream->skipFilters();
             $pngDataRawDecoded = $decodingStream->value;
             //Iterate every pixel and copy out gray data and alpha channel (this will be slow)
             for ($pixel = 0, $pixelcount = $width * $height; $pixel < $pixelcount; $pixel++) {
                 $imageDataTmp .= $pngDataRawDecoded[$pixel * 2];
                 $smaskData .= $pngDataRawDecoded[$pixel * 2 + 1];
             }
             $compressed = false;
             $imageData = $imageDataTmp;
             //Overwrite image data with the gray channel without alpha
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA:
             /*
              * To decode PNG's with alpha data we must create two images from one. One image will contain the RGB data
              * the other will contain the Gray transparency overlay data. The former will become the object data and the latter
              * will become the Shadow Mask (SMask).
              */
             if ($bits > 8) {
                 require_once 'Zend/Pdf/Exception.php';
                 throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
             }
             $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
             require_once 'Zend/Pdf/ElementFactory.php';
             $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
             $decodingStream = $decodingObjFactory->newStreamObject($imageData);
             $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
             $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
             $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
             $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
             $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(4);
             //RGBA
             $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
             $decodingStream->skipFilters();
             $pngDataRawDecoded = $decodingStream->value;
             //Iterate every pixel and copy out rgb data and alpha channel (this will be slow)
             for ($pixel = 0, $pixelcount = $width * $height; $pixel < $pixelcount; $pixel++) {
                 $imageDataTmp .= $pngDataRawDecoded[$pixel * 4 + 0] . $pngDataRawDecoded[$pixel * 4 + 1] . $pngDataRawDecoded[$pixel * 4 + 2];
                 $smaskData .= $pngDataRawDecoded[$pixel * 4 + 3];
             }
             $compressed = false;
             $imageData = $imageDataTmp;
             //Overwrite image data with the RGB channel without alpha
             break;
         default:
             require_once 'Zend/Pdf/Exception.php';
             throw new Zend_Pdf_Exception("PNG Corruption: Invalid color space.");
     }
     if (empty($imageData)) {
         require_once 'Zend/Pdf/Exception.php';
         throw new Zend_Pdf_Exception("Corrupt PNG Image. Mandatory IDAT chunk not found.");
     }
     $imageDictionary = $this->_resource->dictionary;
     if (!empty($smaskData)) {
         /*
          * Includes the Alpha transparency data as a Gray Image, then assigns the image as the Shadow Mask for the main image data.
          */
         $smaskStream = $this->_objectFactory->newStreamObject($smaskData);
         $smaskStream->dictionary->Type = new Zend_Pdf_Element_Name('XObject');
         $smaskStream->dictionary->Subtype = new Zend_Pdf_Element_Name('Image');
         $smaskStream->dictionary->Width = new Zend_Pdf_Element_Numeric($width);
         $smaskStream->dictionary->Height = new Zend_Pdf_Element_Numeric($height);
         $smaskStream->dictionary->ColorSpace = new Zend_Pdf_Element_Name('DeviceGray');
         $smaskStream->dictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
         $imageDictionary->SMask = $smaskStream;
         // Encode stream with FlateDecode filter
         $smaskStreamDecodeParms = array();
         $smaskStreamDecodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15);
         $smaskStreamDecodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
         $smaskStreamDecodeParms['Colors'] = new Zend_Pdf_Element_Numeric(1);
         $smaskStreamDecodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric(8);
         $smaskStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($smaskStreamDecodeParms);
         $smaskStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
     }
     if (!empty($transparencyData)) {
         //This is experimental and not properly tested.
         $imageDictionary->Mask = new Zend_Pdf_Element_Array($transparencyData);
     }
     $imageDictionary->Width = new Zend_Pdf_Element_Numeric($width);
     $imageDictionary->Height = new Zend_Pdf_Element_Numeric($height);
     $imageDictionary->ColorSpace = $colorSpace;
     $imageDictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
     $imageDictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
     $decodeParms = array();
     $decodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15);
     // Optimal prediction
     $decodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
     $decodeParms['Colors'] = new Zend_Pdf_Element_Numeric($color == Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB || $color == Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA ? 3 : 1);
     $decodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric($bits);
     $imageDictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($decodeParms);
     //Include only the image IDAT section data.
     $this->_resource->value = $imageData;
     //Skip double compression
     if ($compressed) {
         $this->_resource->skipFilters();
     }
 }
Example #19
0
 /**
  * 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;
         $this->_safeGS = false;
         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->_safeGS = false;
             $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) {
                 if ($param2 !== null) {
                     $this->_objFactory = $param2;
                 } else {
                     //require_once 'Zend/Pdf/ElementFactory.php';
                     $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
                 }
                 $this->_attached = false;
                 $this->_safeGS = true;
                 /** New page created. That's users App responsibility to track GS changes */
                 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" or "x:y:" form
                 }
                 $pageDim = explode(':', $param1);
                 if (count($pageDim) == 2 || count($pageDim) == 3) {
                     $pageWidth = $pageDim[0];
                     $pageHeight = $pageDim[1];
                 } else {
                     /**
                      * @todo support of user defined pagesize notations, like:
                      *       "210x297mm", "595x842", "8.5x11in", "612x792"
                      */
                     //require_once 'Zend/Pdf/Exception.php';
                     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)) {
                     if ($param3 !== null) {
                         $this->_objFactory = $param3;
                     } else {
                         //require_once 'Zend/Pdf/ElementFactory.php';
                         $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
                     }
                     $this->_attached = false;
                     $this->_safeGS = true;
                     /** New page created. That's users App responsibility to track GS changes */
                     $pageWidth = $param1;
                     $pageHeight = $param2;
                 } else {
                     //require_once 'Zend/Pdf/Exception.php';
                     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');
     //require_once 'Zend/Pdf.php';
     $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();
 }
 /**
  * Attach factory to the current;
  *
  * @param Zend_Pdf_ElementFactory $factory
  */
 public function attach(Zend_Pdf_ElementFactory $factory)
 {
     if ($factory == $this || isset($this->_attachedFactories[$factory->getId()])) {
         /**
          * Don't attach factory twice.
          * We do not check recusively because of nature of attach operation
          * (Pages are always attached to the Documents, Fonts are always attached
          * to the pages even if pages already use Document level object factory and so on)
          */
         return;
     }
     $this->_attachedFactories[$factory->getId()] = $factory;
 }
Example #21
0
 /**
  * Mark object as modified, to include it into new PDF file segment
  */
 public function touch()
 {
     $this->_factory->markAsModified($this);
 }
Example #22
0
 public function __construct($imageFileName)
 {
     if (($imageFile = @fopen($imageFileName, 'rb')) === false) {
         throw new Zend_Pdf_Exception("Can not open '{$imageFileName}' file for reading.");
     }
     parent::__construct();
     fseek($imageFile, 1, SEEK_CUR);
     if ('PNG' != fread($imageFile, 3)) {
         throw new Zend_Pdf_Exception('Image is not a PNG');
     }
     fseek($imageFile, 12, SEEK_CUR);
     $wtmp = unpack('Ni', fread($imageFile, 4));
     $width = $wtmp['i'];
     $htmp = unpack('Ni', fread($imageFile, 4));
     $height = $htmp['i'];
     $bits = ord(fread($imageFile, 1));
     $color = ord(fread($imageFile, 1));
     $compression = ord(fread($imageFile, 1));
     $prefilter = ord(fread($imageFile, 1));
     if (($interlacing = ord(fread($imageFile, 1))) != Zend_Pdf_Resource_Image_Png::PNG_INTERLACING_DISABLED) {
         throw new Zend_Pdf_Exception("Only non-interlaced images are currently supported.");
     }
     $this->_width = $width;
     $this->_height = $height;
     $this->_imageProperties = array();
     $this->_imageProperties['bitDepth'] = $bits;
     $this->_imageProperties['pngColorType'] = $color;
     $this->_imageProperties['pngFilterType'] = $prefilter;
     $this->_imageProperties['pngCompressionType'] = $compression;
     $this->_imageProperties['pngInterlacingType'] = $interlacing;
     fseek($imageFile, 4, SEEK_CUR);
     $imageData = '';
     while (!feof($imageFile)) {
         $chunkLengthBytes = fread($imageFile, 4);
         if ($chunkLengthBytes === false) {
             throw new Zend_Pdf_Exception('Error ocuured while image file reading.');
         }
         $chunkLengthtmp = unpack('Ni', $chunkLengthBytes);
         $chunkLength = $chunkLengthtmp['i'];
         $chunkType = fread($imageFile, 4);
         switch ($chunkType) {
             case 'IDAT':
                 $imageData .= fread($imageFile, $chunkLength);
                 fseek($imageFile, 4, SEEK_CUR);
                 break;
             case 'PLTE':
                 $paletteData = fread($imageFile, $chunkLength);
                 fseek($imageFile, 4, SEEK_CUR);
                 break;
             case 'tRNS':
                 $trnsData = fread($imageFile, $chunkLength);
                 switch ($color) {
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY:
                         $baseColor = ord(substr($trnsData, 1, 1));
                         $transparencyData = array(new Zend_Pdf_Element_Numeric($baseColor), new Zend_Pdf_Element_Numeric($baseColor));
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB:
                         $red = ord(substr($trnsData, 1, 1));
                         $green = ord(substr($trnsData, 3, 1));
                         $blue = ord(substr($trnsData, 5, 1));
                         $transparencyData = array(new Zend_Pdf_Element_Numeric($red), new Zend_Pdf_Element_Numeric($red), new Zend_Pdf_Element_Numeric($green), new Zend_Pdf_Element_Numeric($green), new Zend_Pdf_Element_Numeric($blue), new Zend_Pdf_Element_Numeric($blue));
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_INDEXED:
                         if (($trnsIdx = strpos($trnsData, "")) !== false) {
                             $transparencyData = array(new Zend_Pdf_Element_Numeric($trnsIdx), new Zend_Pdf_Element_Numeric($trnsIdx));
                         }
                         break;
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY_ALPHA:
                     case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA:
                         throw new Zend_Pdf_Exception("tRNS chunk illegal for Alpha Channel Images");
                         break;
                 }
                 fseek($imageFile, 4, SEEK_CUR);
                 break;
             case 'IEND':
                 break 2;
             default:
                 fseek($imageFile, $chunkLength + 4, SEEK_CUR);
                 break;
         }
     }
     fclose($imageFile);
     $compressed = true;
     $imageDataTmp = '';
     $smaskData = '';
     switch ($color) {
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB:
             $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY:
             $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_INDEXED:
             if (empty($paletteData)) {
                 throw new Zend_Pdf_Exception("PNG Corruption: No palette data read for indexed type PNG.");
             }
             $colorSpace = new Zend_Pdf_Element_Array();
             $colorSpace->items[] = new Zend_Pdf_Element_Name('Indexed');
             $colorSpace->items[] = new Zend_Pdf_Element_Name('DeviceRGB');
             $colorSpace->items[] = new Zend_Pdf_Element_Numeric(strlen($paletteData) / 3 - 1);
             $paletteObject = $this->_objectFactory->newObject(new Zend_Pdf_Element_String_Binary($paletteData));
             $colorSpace->items[] = $paletteObject;
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_GRAY_ALPHA:
             if ($bits > 8) {
                 throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
             }
             $colorSpace = new Zend_Pdf_Element_Name('DeviceGray');
             $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
             $decodingStream = $decodingObjFactory->newStreamObject($imageData);
             $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
             $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
             $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
             $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
             $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(2);
             $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
             $decodingStream->skipFilters();
             $pngDataRawDecoded = $decodingStream->value;
             for ($pixel = 0, $pixelcount = $width * $height; $pixel < $pixelcount; $pixel++) {
                 $imageDataTmp .= $pngDataRawDecoded[$pixel * 2];
                 $smaskData .= $pngDataRawDecoded[$pixel * 2 + 1];
             }
             $compressed = false;
             $imageData = $imageDataTmp;
             break;
         case Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA:
             if ($bits > 8) {
                 throw new Zend_Pdf_Exception("Alpha PNGs with bit depth > 8 are not yet supported");
             }
             $colorSpace = new Zend_Pdf_Element_Name('DeviceRGB');
             $decodingObjFactory = Zend_Pdf_ElementFactory::createFactory(1);
             $decodingStream = $decodingObjFactory->newStreamObject($imageData);
             $decodingStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
             $decodingStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary();
             $decodingStream->dictionary->DecodeParms->Predictor = new Zend_Pdf_Element_Numeric(15);
             $decodingStream->dictionary->DecodeParms->Columns = new Zend_Pdf_Element_Numeric($width);
             $decodingStream->dictionary->DecodeParms->Colors = new Zend_Pdf_Element_Numeric(4);
             $decodingStream->dictionary->DecodeParms->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
             $decodingStream->skipFilters();
             $pngDataRawDecoded = $decodingStream->value;
             for ($pixel = 0, $pixelcount = $width * $height; $pixel < $pixelcount; $pixel++) {
                 $imageDataTmp .= $pngDataRawDecoded[$pixel * 4 + 0] . $pngDataRawDecoded[$pixel * 4 + 1] . $pngDataRawDecoded[$pixel * 4 + 2];
                 $smaskData .= $pngDataRawDecoded[$pixel * 4 + 3];
             }
             $compressed = false;
             $imageData = $imageDataTmp;
             break;
         default:
             throw new Zend_Pdf_Exception("PNG Corruption: Invalid color space.");
     }
     if (empty($imageData)) {
         throw new Zend_Pdf_Exception("Corrupt PNG Image. Mandatory IDAT chunk not found.");
     }
     $imageDictionary = $this->_resource->dictionary;
     if (!empty($smaskData)) {
         $smaskStream = $this->_objectFactory->newStreamObject($smaskData);
         $smaskStream->dictionary->Type = new Zend_Pdf_Element_Name('XObject');
         $smaskStream->dictionary->Subtype = new Zend_Pdf_Element_Name('Image');
         $smaskStream->dictionary->Width = new Zend_Pdf_Element_Numeric($width);
         $smaskStream->dictionary->Height = new Zend_Pdf_Element_Numeric($height);
         $smaskStream->dictionary->ColorSpace = new Zend_Pdf_Element_Name('DeviceGray');
         $smaskStream->dictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
         $imageDictionary->SMask = $smaskStream;
         $smaskStreamDecodeParms = array();
         $smaskStreamDecodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15);
         $smaskStreamDecodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
         $smaskStreamDecodeParms['Colors'] = new Zend_Pdf_Element_Numeric(1);
         $smaskStreamDecodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric(8);
         $smaskStream->dictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($smaskStreamDecodeParms);
         $smaskStream->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
     }
     if (!empty($transparencyData)) {
         $imageDictionary->Mask = new Zend_Pdf_Element_Array($transparencyData);
     }
     $imageDictionary->Width = new Zend_Pdf_Element_Numeric($width);
     $imageDictionary->Height = new Zend_Pdf_Element_Numeric($height);
     $imageDictionary->ColorSpace = $colorSpace;
     $imageDictionary->BitsPerComponent = new Zend_Pdf_Element_Numeric($bits);
     $imageDictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
     $decodeParms = array();
     $decodeParms['Predictor'] = new Zend_Pdf_Element_Numeric(15);
     $decodeParms['Columns'] = new Zend_Pdf_Element_Numeric($width);
     $decodeParms['Colors'] = new Zend_Pdf_Element_Numeric($color == Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB || $color == Zend_Pdf_Resource_Image_Png::PNG_CHANNEL_RGB_ALPHA ? 3 : 1);
     $decodeParms['BitsPerComponent'] = new Zend_Pdf_Element_Numeric($bits);
     $imageDictionary->DecodeParms = new Zend_Pdf_Element_Dictionary($decodeParms);
     $this->_resource->value = $imageData;
     if ($compressed) {
         $this->_resource->skipFilters();
     }
 }