text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: ElementFactory.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_ElementFactory_Interface */
require_once 'Zend/Pdf/ElementFactory/Interface.php';

/**
 * PDF element factory.
 * Responsibility is to log PDF changes
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_ElementFactory implements Zend_Pdf_ElementFactory_Interface
{
    /**
     * List of the modified objects.
     * Also contains new and removed objects
     *
     * Array: ojbectNumber => Zend_Pdf_Element_Object
     *
     * @var array
     */
    private $_modifiedObjects = array();

    /**
     * List of the removed objects
     *
     * Array: ojbectNumber => Zend_Pdf_Element_Object
     *
     * @var SplObjectStorage
     */
    private $_removedObjects;

    /**
     * List of registered objects.
     * Used for resources clean up when factory is destroyed.
     *
     * Array of Zend_Pdf_Element objects
     *
     * @var array
     */
    private $_registeredObjects = array();

    /**
     * PDF object counter.
     * Actually it's an object number for new PDF object
     *
     * @var integer
     */
    private $_objectCount;

    /**
     * List of the attached object factories.
     * Array of Zend_Pdf_ElementFactory_Interface objects
     *
     * @var array
     */
    private $_attachedFactories = array();

    /**
     * Factory internal id
     *
     * @var integer
     */
    private $_factoryId;

    /**
     * Identity, used for factory id generation
     *
     * @var integer
     */
    private static $_identity = 0;

    /**
     * Internal cache to save calculated shifts
     *
     * @var array
     */
    private $_shiftCalculationCache = array();

    /**
     * Object constructor
     *
     * @param integer $objCount
     */
    public function __construct($objCount)
    {
        $this->_objectCount    = (int)$objCount;
        $this->_factoryId      = self::$_identity++;
        $this->_removedObjects = new SplObjectStorage();
    }

    /**
     * Get factory
     *
     * @return Zend_Pdf_ElementFactory_Interface
     */
    public function getFactory()
    {
        return $this;
    }

    /**
     * Factory generator
     *
     * @param integer $objCount
     * @return Zend_Pdf_ElementFactory_Interface
     */
    static public function createFactory($objCount)
    {
        require_once 'Zend/Pdf/ElementFactory/Proxy.php';
        return new Zend_Pdf_ElementFactory_Proxy(new Zend_Pdf_ElementFactory($objCount));
    }

    /**
     * Close factory and clean-up resources
     *
     * @internal
     */
    public function close()
    {
        $this->_modifiedObjects   = null;
        $this->_removedObjects    = null;
        $this->_attachedFactories = null;

        foreach ($this->_registeredObjects as $obj) {
            $obj->cleanUp();
        }
        $this->_registeredObjects = null;
    }

    /**
     * Get source factory object
     *
     * @return Zend_Pdf_ElementFactory
     */
    public function resolve()
    {
        return $this;
    }

    /**
     * Get factory ID
     *
     * @return integer
     */
    public function getId()
    {
        return $this->_factoryId;
    }

    /**
     * Set object counter
     *
     * @param integer $objCount
     */
    public function setObjectCount($objCount)
    {
        $this->_objectCount = (int)$objCount;
    }

    /**
     * Get object counter
     *
     * @return integer
     */
    public function getObjectCount()
    {
        $count = $this->_objectCount;

        foreach ($this->_attachedFactories as $attached) {
            $count += $attached->getObjectCount() - 1; // -1 as "0" object is a special case and shared between factories
        }

        return $count;
    }

    /**
     * Attach factory to the current;
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     */
    public function attach(Zend_Pdf_ElementFactory_Interface $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;
    }

    /**
     * Calculate object enumeration shift.
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     */
    public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory)
    {
        if ($factory === $this) {
            return 0;
        }

        if (isset($this->_shiftCalculationCache[$factory->_factoryId])) {
            return $this->_shiftCalculationCache[$factory->_factoryId];
        }

        $shift = $this->_objectCount - 1;

        foreach ($this->_attachedFactories as $subFactory) {
            $subFactoryShift = $subFactory->calculateShift($factory);

            if ($subFactoryShift != -1) {
                // context found
                $this->_shiftCalculationCache[$factory->_factoryId] = $shift + $subFactoryShift;
                return $shift + $subFactoryShift;
            } else {
                $shift += $subFactory->getObjectCount()-1;
            }
        }

        $this->_shiftCalculationCache[$factory->_factoryId] = -1;
        return -1;
    }

    /**
     * Clean enumeration shift cache.
     * Has to be used after PDF render operation to let followed updates be correct.
     */
    public function cleanEnumerationShiftCache()
    {
        $this->_shiftCalculationCache = array();

        foreach ($this->_attachedFactories as $attached) {
            $attached->cleanEnumerationShiftCache();
        }
    }

    /**
     * Retrive object enumeration shift.
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     * @throws Zend_Pdf_Exception
     */
    public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory)
    {
        if (($shift = $this->calculateShift($factory)) == -1) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Wrong object context');
        }

        return $shift;
    }

    /**
     * Mark object as modified in context of current factory.
     *
     * @param Zend_Pdf_Element_Object $obj
     * @throws Zend_Pdf_Exception
     */
    public function markAsModified(Zend_Pdf_Element_Object $obj)
    {
        if ($obj->getFactory() !== $this) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Object is not generated by this factory');
        }

        $this->_modifiedObjects[$obj->getObjNum()] = $obj;
    }

    /**
     * Remove object in context of current factory.
     *
     * @param Zend_Pdf_Element_Object $obj
     * @throws Zend_Pdf_Exception
     */
    public function remove(Zend_Pdf_Element_Object $obj)
    {
        if (!$obj->compareFactory($this)) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Object is not generated by this factory');
        }

        $this->_modifiedObjects[$obj->getObjNum()] = $obj;
        $this->_removedObjects->attach($obj);
    }

    /**
     * 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)
    {
        require_once 'Zend/Pdf/Element/Object.php';
        $obj = new Zend_Pdf_Element_Object($objectValue, $this->_objectCount++, 0, $this);
        $this->_modifiedObjects[$obj->getObjNum()] = $obj;
        return $obj;
    }

    /**
     * Generate new Zend_Pdf_Element_Object_Stream
     *
     * @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
     *
     * @param mixed $objectValue
     * @return Zend_Pdf_Element_Object_Stream
     */
    public function newStreamObject($streamValue)
    {
        require_once 'Zend/Pdf/Element/Object/Stream.php';
        $obj = new Zend_Pdf_Element_Object_Stream($streamValue, $this->_objectCount++, 0, $this);
        $this->_modifiedObjects[$obj->getObjNum()] = $obj;
        return $obj;
    }

    /**
     * Enumerate modified objects.
     * Returns array of Zend_Pdf_UpdateInfoContainer
     *
     * @param Zend_Pdf_ElementFactory_Interface $rootFactory
     * @return array
     */
    public function listModifiedObjects($rootFactory = null)
    {
        if ($rootFactory == null) {
            $rootFactory = $this;
            $shift = 0;
        } else {
            $shift = $rootFactory->getEnumerationShift($this);
        }

        ksort($this->_modifiedObjects);

        $result = array();
        require_once 'Zend/Pdf/UpdateInfoContainer.php';
        foreach ($this->_modifiedObjects as $objNum => $obj) {
            if ($this->_removedObjects->contains($obj)) {
                            $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
                                                                           $obj->getGenNum()+1,
                                                                           true);
            } else {
                $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
                                                                           $obj->getGenNum(),
                                                                           false,
                                                                           $obj->dump($rootFactory));
            }
        }

        foreach ($this->_attachedFactories as $factory) {
            $result += $factory->listModifiedObjects($rootFactory);
        }

        return $result;
    }

    /**
     * Register object in the factory
     *
     * It's used to clear "parent object" referencies when factory is closed and clean up resources
     *
     * @param string $refString
     * @param Zend_Pdf_Element_Object $obj
     */
    public function registerObject(Zend_Pdf_Element_Object $obj, $refString)
    {
        $this->_registeredObjects[$refString] = $obj;
    }

    /**
     * Fetch object specified by reference
     *
     * @param string $refString
     * @return Zend_Pdf_Element_Object|null
     */
    public function fetchObject($refString)
    {
        if (!isset($this->_registeredObjects[$refString])) {
            return null;
        }
        return $this->_registeredObjects[$refString];
    }

    /**
     * Check if PDF file was modified
     *
     * @return boolean
     */
    public function isModified()
    {
        if (count($this->_modifiedObjects) != 0) {
            return true;
        }

        foreach ($this->_attachedFactories as $subFactory) {
            if ($subFactory->isModified()) {
                return true;
            }
        }

        return false;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage FileParser
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: FileParserDataSource.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Abstract helper class for {@link Zend_Pdf_FileParser} that provides the
 * data source for parsing.
 *
 * Concrete subclasses allow for parsing of in-memory, filesystem, and other
 * sources through a common API. These subclasses also take care of error
 * handling and other mundane tasks.
 *
 * Subclasses must implement at minimum {@link __construct()},
 * {@link __destruct()}, {@link readBytes()}, and {@link readAllBytes()}.
 * Subclasses should also override {@link moveToOffset()} and
 * {@link __toString()} as appropriate.
 *
 * @package    Zend_Pdf
 * @subpackage FileParser
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Pdf_FileParserDataSource
{
  /**** Instance Variables ****/

    /**
     * Total size in bytes of the data source.
     * @var integer
     */
    protected $_size = 0;

    /**
     * Byte offset of the current read position within the data source.
     * @var integer
     */
    protected $_offset = 0;

  /**** Public Interface ****/

  /* Abstract Methods */

    /**
     * Object constructor. Opens the data source for parsing.
     *
     * Must set $this->_size to the total size in bytes of the data source.
     *
     * Upon return the data source can be interrogated using the primitive
     * methods described here.
     *
     * If the data source cannot be opened for any reason (such as insufficient
     * permissions, missing file, etc.), will throw an appropriate exception.
     *
     * @throws Zend_Pdf_Exception
     */
    abstract public function __construct();

    /**
     * Object destructor. Closes the data source.
     *
     * May also perform cleanup tasks such as deleting temporary files.
     */
    abstract public function __destruct();

    /**
     * Returns the specified number of raw bytes from the data source at the
     * byte offset of the current read position.
     *
     * Must advance the read position by the number of bytes read by updating
     * $this->_offset.
     *
     * Throws an exception if there is insufficient data to completely fulfill
     * the request or if an error occurs.
     *
     * @param integer $byteCount Number of bytes to read.
     * @return string
     * @throws Zend_Pdf_Exception
     */
    abstract public function readBytes($byteCount);

    /**
     * Returns the entire contents of the data source as a string.
     *
     * This method may be called at any time and so must preserve the byte
     * offset of the read position, both through $this->_offset and whatever
     * other additional pointers (such as the seek position of a file pointer)
     * that might be used.
     *
     * @return string
     */
    abstract public function readAllBytes();

  /* Object Magic Methods */

    /**
     * Returns a description of the object for debugging purposes.
     *
     * Subclasses should override this method to provide a more specific
     * description of the actual object being represented.
     *
     * @return string
     */
    public function __toString()
    {
        return get_class($this);
    }

  /* Accessors */

    /**
     * Returns the byte offset of the current read position within the data
     * source.
     *
     * @return integer
     */
    public function getOffset()
    {
        return $this->_offset;
    }

    /**
     * Returns the total size in bytes of the data source.
     *
     * @return integer
     */
    public function getSize()
    {
        return $this->_size;
    }

  /* Primitive Methods */

    /**
     * Moves the current read position to the specified byte offset.
     *
     * Throws an exception you attempt to move before the beginning or beyond
     * the end of the data source.
     *
     * If a subclass needs to perform additional tasks (such as performing a
     * fseek() on a filesystem source), it should do so after calling this
     * parent method.
     *
     * @param integer $offset Destination byte offset.
     * @throws Zend_Pdf_Exception
     */
    public function moveToOffset($offset)
    {
        if ($this->_offset == $offset) {
            return;    // Not moving; do nothing.
        }
        if ($offset < 0) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Attempt to move before start of data source',
                                         Zend_Pdf_Exception::MOVE_BEFORE_START_OF_FILE);
        }
        if ($offset >= $this->_size) {    // Offsets are zero-based.
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Attempt to move beyond end of data source',
                                         Zend_Pdf_Exception::MOVE_BEYOND_END_OF_FILE);
        }
        $this->_offset = $offset;
    }

    /**
     * Shifts the current read position within the data source by the specified
     * number of bytes.
     *
     * You may move forward (positive numbers) or backward (negative numbers).
     * Throws an exception you attempt to move before the beginning or beyond
     * the end of the data source.
     *
     * @param integer $byteCount Number of bytes to skip.
     * @throws Zend_Pdf_Exception
     */
    public function skipBytes($byteCount)
    {
        $this->moveToOffset($this->_offset + $byteCount);
    }
}

repo_name: michael-romer/zf-boilerplate

repo_language: PHP

mime_type: text/html


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Page.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Internally used classes */
require_once 'Zend/Pdf/Element.php';
require_once 'Zend/Pdf/Element/Array.php';
require_once 'Zend/Pdf/Element/String/Binary.php';
require_once 'Zend/Pdf/Element/Boolean.php';
require_once 'Zend/Pdf/Element/Dictionary.php';
require_once 'Zend/Pdf/Element/Name.php';
require_once 'Zend/Pdf/Element/Null.php';
require_once 'Zend/Pdf/Element/Numeric.php';
require_once 'Zend/Pdf/Element/String.php';
require_once 'Zend/Pdf/Resource/Unified.php';

require_once 'Zend/Pdf/Canvas/Abstract.php';

/**
 * PDF Page
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_Page extends Zend_Pdf_Canvas_Abstract
{
  /**** Class Constants ****/

  /* Page Sizes */

    /**
     * Size representing an A4 page in portrait (tall) orientation.
     */
    const SIZE_A4                = '595:842:';

    /**
     * Size representing an A4 page in landscape (wide) orientation.
     */
    const SIZE_A4_LANDSCAPE      = '842:595:';

    /**
     * Size representing a US Letter page in portrait (tall) orientation.
     */
    const SIZE_LETTER            = '612:792:';

    /**
     * Size representing a US Letter page in landscape (wide) orientation.
     */
    const SIZE_LETTER_LANDSCAPE  = '792:612:';

  /* Shape Drawing */

    /**
     * Stroke the path only. Do not fill.
     */
    const SHAPE_DRAW_STROKE      = 0;

    /**
     * Fill the path only. Do not stroke.
     */
    const SHAPE_DRAW_FILL        = 1;

    /**
     * Fill and stroke the path.
     */
    const SHAPE_DRAW_FILL_AND_STROKE = 2;

  /* Shape Filling Methods */

    /**
     * Fill the path using the non-zero winding rule.
     */
    const FILL_METHOD_NON_ZERO_WINDING = 0;

    /**
     * Fill the path using the even-odd rule.
     */
    const FILL_METHOD_EVEN_ODD        = 1;

  /* Line Dash Types */

    /**
     * Solid line dash.
     */
    const LINE_DASHING_SOLID = 0;

    /**
     * Page dictionary (refers to an inderect Zend_Pdf_Element_Dictionary object).
     *
     * @var Zend_Pdf_Element_Reference|Zend_Pdf_Element_Object
     */
    protected $_dictionary;

    /**
     * PDF objects factory.
     *
     * @var Zend_Pdf_ElementFactory_Interface
     */
    protected $_objFactory = null;

    /**
     * Flag which signals, that page is created separately from any PDF document or
     * attached to anyone.
     *
     * @var boolean
     */
    protected $_attached;

    /**
     * Safe Graphics State semafore
     *
     * If it's false, than we can't be sure Graphics State is restored withing
     * context of previous contents stream (ex. drawing coordinate system may be rotated).
     * We should encompass existing content with save/restore GS operators
     *
     * @var boolean
     */
    protected $_safeGS;

    /**
     * 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. Make a copy of the 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 instanceof Zend_Pdf_Element_Object
            ) &&
            $param2 instanceof Zend_Pdf_ElementFactory_Interface &&
            $param3 === null
           ) {
            switch ($param1->getType()) {
                case Zend_Pdf_Element::TYPE_DICTIONARY:
                    $this->_dictionary = $param1;
                    $this->_objFactory = $param2;
                    $this->_attached   = true;
                    $this->_safeGS     = false;
                    return;
                    break;

                case Zend_Pdf_Element::TYPE_NULL:
                    $this->_objFactory = $param2;
                    $pageWidth = $pageHeight = 0;
                    break;

                default:
                    require_once 'Zend/Pdf/Exception.php';
                    throw new Zend_Pdf_Exception('Unrecognized object type.');
                    break;

            }
        } else if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) {
            // Duplicate 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->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());

            foreach ($param1->_dictionary->getKeys() as $key) {
                if ($key == 'Contents') {
                    // Clone Contents property

                    $this->_dictionary->Contents = new Zend_Pdf_Element_Array();

                    if ($param1->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
                        // Prepare array of content streams and add existing stream
                        $this->_dictionary->Contents->items[] = $param1->_dictionary->Contents;
                    } else {
                        // Clone array of the content streams
                        foreach ($param1->_dictionary->Contents->items as $srcContentStream) {
                            $this->_dictionary->Contents->items[] = $srcContentStream;
                        }
                    }
                } else {
                    $this->_dictionary->$key = $param1->_dictionary->$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->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
        $this->_dictionary->Type         = new Zend_Pdf_Element_Name('Page');
        require_once 'Zend/Pdf.php';
        $this->_dictionary->LastModified = new Zend_Pdf_Element_String(Zend_Pdf::pdfDate());
        $this->_dictionary->Resources    = new Zend_Pdf_Element_Dictionary();
        $this->_dictionary->MediaBox     = new Zend_Pdf_Element_Array();
        $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
        $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
        $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageWidth);
        $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageHeight);
        $this->_dictionary->Contents     = new Zend_Pdf_Element_Array();
    }

    /**
     * Attach resource to the canvas
     *
     * Method returns a name of the resource which can be used
     * as a resource reference within drawing instructions stream
     * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
     * 'XObject', 'Font', 'Properties'
     *
     * @param string $type
     * @param Zend_Pdf_Resource $resource
     * @return string
     */
    protected function _attachResource($type, Zend_Pdf_Resource $resource)
    {
        // Check that Resources dictionary contains appropriate resource set
        if ($this->_dictionary->Resources->$type === null) {
            $this->_dictionary->Resources->touch();
            $this->_dictionary->Resources->$type = new Zend_Pdf_Element_Dictionary();
        } else {
            $this->_dictionary->Resources->$type->touch();
        }

        // Check, that resource is already attached to resource set.
        $resObject = $resource->getResource();
        foreach ($this->_dictionary->Resources->$type->getKeys() as $ResID) {
            if ($this->_dictionary->Resources->$type->$ResID === $resObject) {
                return $ResID;
            }
        }

        $idCounter = 1;
        do {
            $newResName = $type[0] . $idCounter++;
        } while ($this->_dictionary->Resources->$type->$newResName !== null);

        $this->_dictionary->Resources->$type->$newResName = $resObject;
        $this->_objFactory->attach($resource->getFactory());

        return $newResName;
    }

    /**
     * Add procedureSet to the Page description
     *
     * @param string $procSetName
     */
    protected function _addProcSet($procSetName)
    {
        // Check that Resources dictionary contains ProcSet entry
        if ($this->_dictionary->Resources->ProcSet === null) {
            $this->_dictionary->Resources->touch();
            $this->_dictionary->Resources->ProcSet = new Zend_Pdf_Element_Array();
        } else {
            $this->_dictionary->Resources->ProcSet->touch();
        }

        foreach ($this->_dictionary->Resources->ProcSet->items as $procSetEntry) {
            if ($procSetEntry->value == $procSetName) {
                // Procset is already included into a ProcSet array
                return;
            }
        }

        $this->_dictionary->Resources->ProcSet->items[] = new Zend_Pdf_Element_Name($procSetName);
    }

    /**
     * Returns dictionaries of used resources.
     *
     * Used for canvas implementations interoperability
     *
     * Structure of the returned array:
     * array(
     *   <resTypeName> => array(
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      ...
     *                    ),
     *   <resTypeName> => array(
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      <resName> => <Zend_Pdf_Resource object>,
     *                      ...
     *                    ),
     *   ...
     *   'ProcSet' => array()
     * )
     *
     * where ProcSet array is a list of used procedure sets names (strings).
     * Allowed procedure set names: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'
     *
     * @internal
     * @return array
     */
    public function getResources()
    {
        $resources = array();
        $resDictionary = $this->_dictionary->Resources;

        foreach ($resDictionary->getKeys() as $resType) {
            $resources[$resType] = array();

            if ($resType == 'ProcSet') {
                foreach ($resDictionary->ProcSet->items as $procSetEntry) {
                    $resources[$resType][] = $procSetEntry->value;
                }
            } else {
                $resMap = $resDictionary->$resType;

                foreach ($resMap->getKeys() as $resId) {
                    $resources[$resType][$resId] =new Zend_Pdf_Resource_Unified($resMap->$resId);
                }
            }
        }

        return $resources;
    }

    /**
     * Get drawing instructions stream
     *
     * It has to be returned as a PDF stream object to make it reusable.
     *
     * @internal
     * @returns Zend_Pdf_Resource_ContentStream
     */
    public function getContents()
    {
        /** @todo implementation */
    }

    /**
     * Return the height of this page in points.
     *
     * @return float
     */
    public function getHeight()
    {
        return $this->_dictionary->MediaBox->items[3]->value -
               $this->_dictionary->MediaBox->items[1]->value;
    }

    /**
     * Return the width of this page in points.
     *
     * @return float
     */
    public function getWidth()
    {
        return $this->_dictionary->MediaBox->items[2]->value -
               $this->_dictionary->MediaBox->items[0]->value;
    }

    /**
     * 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;
    }

    /**
     * Clone page, extract it and dependent objects from the current document,
     * so it can be used within other docs.
     *
     * @internal
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @param array $processed
     * @return Zend_Pdf_Page
     */
    public function clonePage($factory, &$processed)
    {
        // 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);
        }

        $clonedPage = new Zend_Pdf_Page($factory->newObject($dictionary), $factory);
        $clonedPage->_attached = false;

        return $clonedPage;
    }

    /**
     * Retrive PDF file reference to the page
     *
     * @internal
     * @return Zend_Pdf_Element_Dictionary
     */
    public function getPageDictionary()
    {
        return $this->_dictionary;
    }

    /**
     * Dump current drawing instructions into the content stream.
     *
     * @todo Don't forget to close all current graphics operations (like path drawing)
     *
     * @throws Zend_Pdf_Exception
     */
    public function flush()
    {
        if ($this->_saveCount != 0) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Saved graphics state is not restored');
        }

        if ($this->_contents == '') {
            return;
        }

        if ($this->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
            /**
             * It's a stream object.
             * Prepare Contents page attribute for update.
             */
            $this->_dictionary->touch();

            $currentPageContents = $this->_dictionary->Contents;
            $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
            $this->_dictionary->Contents->items[] = $currentPageContents;
        } else {
            $this->_dictionary->Contents->touch();
        }

        if ((!$this->_safeGS)  &&  (count($this->_dictionary->Contents->items) != 0)) {
            /**
             * Page already has some content which is not treated as safe.
             *
             * Add save/restore GS operators
             */
            $this->_addProcSet('PDF');

            $newContentsArray = new Zend_Pdf_Element_Array();
            $newContentsArray->items[] = $this->_objFactory->newStreamObject(" q\n");
            foreach ($this->_dictionary->Contents->items as $contentStream) {
                $newContentsArray->items[] = $contentStream;
            }
            $newContentsArray->items[] = $this->_objFactory->newStreamObject(" Q\n");

            $this->_dictionary->touch();
            $this->_dictionary->Contents = $newContentsArray;

            $this->_safeGS = true;
        }

        $this->_dictionary->Contents->items[] =
                $this->_objFactory->newStreamObject($this->_contents);

        $this->_contents = '';
    }

    /**
     * Prepare page to be rendered into PDF.
     *
     * @todo Don't forget to close all current graphics operations (like path drawing)
     *
     * @param Zend_Pdf_ElementFactory_Interface $objFactory
     * @throws Zend_Pdf_Exception
     */
    public function render(Zend_Pdf_ElementFactory_Interface $objFactory)
    {
        $this->flush();

        if ($objFactory === $this->_objFactory) {
            // Page is already attached to the document.
            return;
        }

        if ($this->_attached) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Page is attached to other documen. Use clone $page to get it context free.');
        } else {
            $objFactory->attach($this->_objFactory);
        }
    }

    /**
     * Extract resources attached to the page
     *
     * This method is not intended to be used in userland, but helps to optimize some document wide operations
     *
     * returns array of Zend_Pdf_Element_Dictionary objects
     *
     * @internal
     * @return array
     */
    public function extractResources()
    {
        return $this->_dictionary->Resources;
    }

    /**
     * Extract fonts attached to the page
     *
     * returns array of Zend_Pdf_Resource_Font_Extracted objects
     *
     * @return array
     * @throws Zend_Pdf_Exception
     */
    public function extractFonts()
    {
        if ($this->_dictionary->Resources->Font === null) {
            // Page doesn't have any font attached
            // Return empty array
            return array();
        }

        $fontResources = $this->_dictionary->Resources->Font;

        $fontResourcesUnique = array();
        foreach ($fontResources->getKeys() as $fontResourceName) {
            $fontDictionary = $fontResources->$fontResourceName;

            if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference  ||
                   $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
            }

            $fontResourcesUnique[spl_object_hash($fontDictionary->getObject())] = $fontDictionary;
        }

        $fonts = array();
        require_once 'Zend/Pdf/Exception.php';
        foreach ($fontResourcesUnique as $resourceId => $fontDictionary) {
            try {
                require_once 'Zend/Pdf/Resource/Font/Extracted.php';
                // Try to extract font
                $extractedFont = new Zend_Pdf_Resource_Font_Extracted($fontDictionary);

                $fonts[$resourceId] = $extractedFont;
            } catch (Zend_Pdf_Exception $e) {
                if ($e->getMessage() != 'Unsupported font type.') {
                    throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
                }
            }
        }

        return $fonts;
    }

    /**
     * Extract font attached to the page by specific font name
     *
     * $fontName should be specified in UTF-8 encoding
     *
     * @return Zend_Pdf_Resource_Font_Extracted|null
     * @throws Zend_Pdf_Exception
     */
    public function extractFont($fontName)
    {
        if ($this->_dictionary->Resources->Font === null) {
            // Page doesn't have any font attached
            return null;
        }

        $fontResources = $this->_dictionary->Resources->Font;

        $fontResourcesUnique = array();

        require_once 'Zend/Pdf/Exception.php';
        foreach ($fontResources->getKeys() as $fontResourceName) {
            $fontDictionary = $fontResources->$fontResourceName;

            if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference  ||
                   $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
            }

            $resourceId = spl_object_hash($fontDictionary->getObject());
            if (isset($fontResourcesUnique[$resourceId])) {
                continue;
            } else {
                // Mark resource as processed
                $fontResourcesUnique[$resourceId] = 1;
            }

            if ($fontDictionary->BaseFont->value != $fontName) {
                continue;
            }

            try {
                // Try to extract font
                require_once 'Zend/Pdf/Resource/Font/Extracted.php';
                return new Zend_Pdf_Resource_Font_Extracted($fontDictionary);
            } catch (Zend_Pdf_Exception $e) {
                if ($e->getMessage() != 'Unsupported font type.') {
                    throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
                }

                // Continue searhing font with specified name
            }
        }

        return null;
    }

    /**
     *
     * @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->_dictionary->Annots === null) {
            $this->_dictionary->touch();
            $this->_dictionary->Annots = new Zend_Pdf_Element_Array();
        } else {
            $this->_dictionary->Annots->touch();
        }

        $this->_dictionary->Annots->items[] = $annotationDictionary;

        $annotationDictionary->touch();
        $annotationDictionary->P = $this->_dictionary;

        return $this;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Core
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Exception.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Exception */
require_once 'Zend/Exception.php';

/**
 * Exception class for Zend_Pdf.
 *
 * If you expect a certain type of exception to be caught and handled by the
 * caller, create a constant for it here and include it in the object being
 * thrown. Example:
 *
 *   throw new Zend_Pdf_Exception('foo() is not yet implemented',
 *                                Zend_Pdf_Exception::NOT_IMPLEMENTED);
 *
 * This allows the caller to determine the specific type of exception that was
 * thrown without resorting to parsing the descriptive text.
 *
 * IMPORTANT: Do not rely on numeric values of the constants! They are grouped
 * sequentially below for organizational purposes only. The numbers may come to
 * mean something in the future, but they are subject to renumbering at any
 * time. ALWAYS use the symbolic constant names, which are guaranteed never to
 * change, in logical checks! You have been warned.
 *
 * @package    Zend_Pdf
 * @subpackage Core
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_Exception extends Zend_Exception
{
  /**** Class Constants ****/

  /* Generic Exceptions */

    /**
     * The feature or option is planned but has not yet been implemented. It
     * should be available in a future revision of the framework.
     */
    const NOT_IMPLEMENTED = 0x0001;

    /**
     * The feature or option has been deprecated and will be removed in a future
     * revision of the framework. The descriptive text accompanying this
     * exception should explain how to use the replacement features or options.
     */
    const DEPRECATED = 0x0002;

    /**
     * Not enough paramaters were supplied to the method.
     */
    const TOO_FEW_PARAMETERS = 0x0003;

    /**
     * A parameter was of the wrong data type.
     */
    const BAD_PARAMETER_TYPE = 0x0004;

    /**
     * A parameter contained an unusable value.
     */
    const BAD_PARAMETER_VALUE = 0x0005;

    /**
     * A parameter value was not within the expected range.
     */
    const PARAMETER_VALUE_OUT_OF_RANGE = 0x0006;

    /**
     * The method that has multiple signatures could not understand the
     * number and/or types of parameters.
     */
    const BAD_METHOD_SIGNATURE = 0x0007;

    /**
     * An array or string index was out of range.
     */
    const INDEX_OUT_OF_RANGE = 0x0008;

  /* Filesystem I/O */

    /**
     * The file path was unusable or invalid.
     */
    const BAD_FILE_PATH = 0x0101;

    /**
     * The file is not readable by the current user.
     */
    const NOT_READABLE = 0x0102;

    /**
     * The file is not writeable by the current user.
     */
    const NOT_WRITEABLE = 0x0103;

    /**
     * The file resource has been closed unexpectedly.
     */
    const FILE_NOT_OPEN = 0x0104;

    /**
     * An error was encountered while attempting to open the file.
     */
    const CANT_OPEN_FILE = 0x0105;

    /**
     * An error was encountered while attempting to obtain the current file
     * position.
     */
    const CANT_GET_FILE_POSITION = 0x0106;

    /**
     * An error was encountered while attempting to set a new file position.
     */
    const CANT_SET_FILE_POSITION = 0x0107;

    /**
     * An attempt was made to move the current file position before the start
     * of the file.
     */
    const MOVE_BEFORE_START_OF_FILE = 0x0108;

    /**
     * An attempt was made to move the current file position beyond the end of
     * the file.
     */
    const MOVE_BEYOND_END_OF_FILE = 0x0109;

    /**
     * An error was encountered while attempting to obtain the file size.
     */
    const CANT_GET_FILE_SIZE = 0x010a;

    /**
     * An error was encountered while attempting to read data from the file.
     */
    const ERROR_DURING_READ = 0x010b;

    /**
     * An error was encountered while attempting to write data to the file.
     */
    const ERROR_DURING_WRITE = 0x010c;

    /**
     * An incompatible page size was specified for a buffered read operation.
     */
    const INVALID_PAGE_SIZE = 0x010d;

    /**
     * There is insufficient data to fulfill the read request.
     */
    const INSUFFICIENT_DATA = 0x010e;

  /* Zend_Pdf_FileParser */

    /**
     * The file parser data source object was invalid or improperly initialized.
     */
    const BAD_DATA_SOURCE = 0x0201;

    /**
     * An unknown byte order was specified.
     */
    const INVALID_BYTE_ORDER = 0x0202;

    /**
     * An invalid integer size was specified.
     */
    const INVALID_INTEGER_SIZE = 0x0203;

    /**
     * An invalid fixed-point number size was specified.
     */
    const BAD_FIXED_POINT_SIZE = 0x0204;

    /**
     * The string cannot be read.
     */
    const CANT_READ_STRING = 0x0205;

    /**
     * This file type must be parsed in a specific order and a parsing method
     * was called out-of-turn.
     */
    const PARSED_OUT_OF_ORDER = 0x0206;

  /* Zend_Pdf_FileParser_Font and Subclasses */

    /**
     * The font file type is incorrect.
     */
    const WRONG_FONT_TYPE = 0x0301;

    /**
     * The number of tables contained in the font is outside the expected range.
     */
    const BAD_TABLE_COUNT = 0x0302;

    /**
     * A required table was not present in the font.
     */
    const REQUIRED_TABLE_NOT_FOUND = 0x0303;

    /**
     * The parser does not understand this version of this table in the font.
     */
    const DONT_UNDERSTAND_TABLE_VERSION = 0x0303;

    /**
     * The magic number in the font file is incorrect.
     */
    const BAD_MAGIC_NUMBER = 0x0304;

    /**
     * Could not locate a usable character map for this font.
     */
    const CANT_FIND_GOOD_CMAP = 0x0305;

  /* Zend_Pdf_Cmap and Subclasses */

    /**
     * The character map type is currently unsupported.
     */
    const CMAP_TYPE_UNSUPPORTED = 0x0401;

    /**
     * The type of the character map is not understood.
     */
    const CMAP_UNKNOWN_TYPE = 0x0402;

    /**
     * The character map table data is too small.
     */
    const CMAP_TABLE_DATA_TOO_SMALL = 0x0403;

    /**
     * The character map table data is for a different type of table.
     */
    const CMAP_WRONG_TABLE_TYPE = 0x0404;

    /**
     * The character map table data contains in incorrect length.
     */
    const CMAP_WRONG_TABLE_LENGTH = 0x0405;

    /**
     * This character map table is language-dependent. Character maps must be
     * language-independent.
     */
    const CMAP_NOT_LANGUAGE_INDEPENDENT = 0x0406;

    /**
     * The final byte offset when reading the character map table data does not
     * match the reported length of the table.
     */
    const CMAP_FINAL_OFFSET_NOT_LENGTH = 0x0407;

    /**
     * The character map subtable entry count does not match the expected value.
     */
    const CMAP_WRONG_ENTRY_COUNT = 0x0408;

  /* Zend_Pdf_Resource_Font and Subclasses */

    /**
     * The specified glyph number is out of range for this font.
     */
    const GLYPH_OUT_OF_RANGE = 0x0501;

    /**
     * This font program has copyright bits set which prevent it from being
     * embedded in the PDF file. You must specify the no-embed option to use
     * this font.
     */
    const FONT_CANT_BE_EMBEDDED = 0x0502;

  /* Zend_Pdf_Font */

    /**
     * The font name did not match any previously instantiated font and is not
     * one of the standard 14 PDF fonts.
     */
    const BAD_FONT_NAME = 0x0601;

    /**
     * The factory method could not determine the type of the font file.
     */
    const CANT_DETERMINE_FONT_TYPE = 0x0602;

  /* Text Layout System */

    /**
     * The specified attribute value for the text object cannot be used.
     */
    const BAD_ATTRIBUTE_VALUE = 0x0701;

  /* Zend_Pdf_Image and Subclasses */

    const CANT_DETERMINE_IMAGE_TYPE = 0x0801;
    const WRONG_IMAGE_TYPE = 0x0802;
    const UNSUPPORTED_IMAGE_ENCODING_OPTIONS = 0x0803;
    const IMAGE_FILE_CORRUPT = 0x0804;

}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: UpdateInfoContainer.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Container which collects updated object info.
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_UpdateInfoContainer
{
    /**
     * Object number
     *
     * @var integer
     */
    private $_objNum;

    /**
     * Generation number
     *
     * @var integer
     */
    private $_genNum;

    /**
     * Flag, which signals, that object is free
     *
     * @var boolean
     */
    private $_isFree;

    /**
     * String representation of the object
     *
     * @var Zend_Memory_Container|null
     */
    private $_dump = null;

    /**
     * Object constructor
     *
     * @param integer $objCount
     */
    public function __construct($objNum, $genNum, $isFree, $dump = null)
    {
        $this->_objNum = $objNum;
        $this->_genNum = $genNum;
        $this->_isFree = $isFree;

        if ($dump !== null) {
            if (strlen($dump) > 1024) {
                require_once 'Zend/Pdf.php';
                $this->_dump = Zend_Pdf::getMemoryManager()->create($dump);
            } else {
                $this->_dump = $dump;
            }
        }
    }

    /**
     * Get object number
     *
     * @return integer
     */
    public function getObjNum()
    {
        return $this->_objNum;
    }

    /**
     * Get generation number
     *
     * @return integer
     */
    public function getGenNum()
    {
        return $this->_genNum;
    }

    /**
     * Check, that object is free
     *
     * @return boolean
     */
    public function isFree()
    {
        return $this->_isFree;
    }

    /**
     * Get string representation of the object
     *
     * @return string
     */
    public function getObjectDump()
    {
        if ($this->_dump === null) {
            return '';
        }

        if (is_string($this->_dump)) {
            return $this->_dump;
        }

        return $this->_dump->getRef();
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Style.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Style object.
 * Style object doesn't directly correspond to any PDF file object.
 * It's utility class, used as a container for style information.
 * It's used by Zend_Pdf_Page class in draw operations.
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_Style
{
    /**
     * Fill color.
     * Used to fill geometric shapes or text.
     *
     * @var Zend_Pdf_Color|null
     */
    private $_fillColor = null;

    /**
     * Line color.
     * Current color, used for lines and font outlines.
     *
     * @var Zend_Pdf_Color|null
     */

    private $_color;

    /**
     * Line width.
     *
     * @var Zend_Pdf_Element_Numeric
     */
    private $_lineWidth;

    /**
     * Array which describes line dashing pattern.
     * It's array of numeric:
     * array($on_length, $off_length, $on_length, $off_length, ...)
     *
     * @var array
     */
    private $_lineDashingPattern;

    /**
     * Line dashing phase
     *
     * @var float
     */
    private $_lineDashingPhase;

    /**
     * Current font
     *
     * @var Zend_Pdf_Resource_Font
     */
    private $_font;

    /**
     * Font size
     *
     * @var float
     */
    private $_fontSize;

    /**
     * Create style.
     *
     * @param Zend_Pdf_Style $anotherStyle
     */
    public function __construct($anotherStyle = null)
    {
        if ($anotherStyle !== null) {
            $this->_fillColor          = $anotherStyle->_fillColor;
            $this->_color              = $anotherStyle->_color;
            $this->_lineWidth          = $anotherStyle->_lineWidth;
            $this->_lineDashingPattern = $anotherStyle->_lineDashingPattern;
            $this->_lineDashingPhase   = $anotherStyle->_lineDashingPhase;
            $this->_font               = $anotherStyle->_font;
            $this->_fontSize           = $anotherStyle->_fontSize;
        }
    }

    /**
     * Set fill color.
     *
     * @param Zend_Pdf_Color $color
     */
    public function setFillColor(Zend_Pdf_Color $color)
    {
        $this->_fillColor = $color;
    }

    /**
     * Set line color.
     *
     * @param Zend_Pdf_Color $color
     */
    public function setLineColor(Zend_Pdf_Color $color)
    {
        $this->_color = $color;
    }

    /**
     * Set line width.
     *
     * @param float $width
     */
    public function setLineWidth($width)
    {
        require_once 'Zend/Pdf/Element/Numeric.php';
        $this->_lineWidth = new Zend_Pdf_Element_Numeric($width);
    }

    /**
     * Set line dashing pattern
     *
     * @param array $pattern
     * @param float $phase
     */
    public function setLineDashingPattern($pattern, $phase = 0)
    {
        require_once 'Zend/Pdf/Page.php';
        if ($pattern === Zend_Pdf_Page::LINE_DASHING_SOLID) {
            $pattern = array();
            $phase   = 0;
        }

        require_once 'Zend/Pdf/Element/Numeric.php';
        $this->_lineDashingPattern = $pattern;
        $this->_lineDashingPhase   = new Zend_Pdf_Element_Numeric($phase);
    }

    /**
     * Set current font.
     *
     * @param Zend_Pdf_Resource_Font $font
     * @param float $fontSize
     */
    public function setFont(Zend_Pdf_Resource_Font $font, $fontSize)
    {
        $this->_font = $font;
        $this->_fontSize = $fontSize;
    }

    /**
     * Modify current font size
     *
     * @param float $fontSize
     */
    public function setFontSize($fontSize)
    {
        $this->_fontSize = $fontSize;
    }

    /**
     * Get fill color.
     *
     * @return Zend_Pdf_Color|null
     */
    public function getFillColor()
    {
        return $this->_fillColor;
    }

    /**
     * Get line color.
     *
     * @return Zend_Pdf_Color|null
     */
    public function getLineColor()
    {
        return $this->_color;
    }

    /**
     * Get line width.
     *
     * @return float
     */
    public function getLineWidth()
    {
        return $this->_lineWidth->value;
    }

    /**
     * Get line dashing pattern
     *
     * @return array
     */
    public function getLineDashingPattern()
    {
        return $this->_lineDashingPattern;
    }

    /**
     * Get current font.
     *
     * @return Zend_Pdf_Resource_Font $font
     */
    public function getFont()
    {
        return $this->_font;
    }

    /**
     * Get current font size
     *
     * @return float $fontSize
     */
    public function getFontSize()
    {
        return $this->_fontSize;
    }

    /**
     * Get line dashing phase
     *
     * @return float
     */
    public function getLineDashingPhase()
    {
        return $this->_lineDashingPhase->value;
    }

    /**
     * Dump style to a string, which can be directly inserted into content stream
     *
     * @return string
     */
    public function instructions()
    {
        $instructions = '';

        if ($this->_fillColor !== null) {
            $instructions .= $this->_fillColor->instructions(false);
        }

        if ($this->_color !== null) {
            $instructions .= $this->_color->instructions(true);
        }

        if ($this->_lineWidth !== null) {
            $instructions .= $this->_lineWidth->toString() . " w\n";
        }

        if ($this->_lineDashingPattern !== null) {
            require_once 'Zend/Pdf/Element/Array.php';
            $dashPattern = new Zend_Pdf_Element_Array();

            require_once 'Zend/Pdf/Element/Numeric.php';
            foreach ($this->_lineDashingPattern as $dashItem) {
                $dashElement = new Zend_Pdf_Element_Numeric($dashItem);
                $dashPattern->items[] = $dashElement;
            }

            $instructions .= $dashPattern->toString() . ' '
                           . $this->_lineDashingPhase->toString() . " d\n";
        }

        return $instructions;
    }

}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Images
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Image.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Abstract factory class which vends {@link Zend_Pdf_Resource_Image} objects.
 *
 * This class is also the home for image-related constants because the name of
 * the true base class ({@link Zend_Pdf_Resource_Image}) is not intuitive for the
 * end user.
 *
 * @package    Zend_Pdf
 * @subpackage Images
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Pdf_Image
{
  /**** Class Constants ****/

  /* Image Types */

    const TYPE_UNKNOWN = 0;
    const TYPE_JPEG = 1;
    const TYPE_PNG = 2;
    const TYPE_TIFF = 3;

  /* TIFF Constants */

    const TIFF_FIELD_TYPE_BYTE=1;
    const TIFF_FIELD_TYPE_ASCII=2;
    const TIFF_FIELD_TYPE_SHORT=3;
    const TIFF_FIELD_TYPE_LONG=4;
    const TIFF_FIELD_TYPE_RATIONAL=5;

    const TIFF_TAG_IMAGE_WIDTH=256;
    const TIFF_TAG_IMAGE_LENGTH=257; //Height
    const TIFF_TAG_BITS_PER_SAMPLE=258;
    const TIFF_TAG_COMPRESSION=259;
    const TIFF_TAG_PHOTOMETRIC_INTERPRETATION=262;
    const TIFF_TAG_STRIP_OFFSETS=273;
    const TIFF_TAG_SAMPLES_PER_PIXEL=277;
    const TIFF_TAG_STRIP_BYTE_COUNTS=279;

    const TIFF_COMPRESSION_UNCOMPRESSED = 1;
    const TIFF_COMPRESSION_CCITT1D = 2;
    const TIFF_COMPRESSION_GROUP_3_FAX = 3;
    const TIFF_COMPRESSION_GROUP_4_FAX  = 4;
    const TIFF_COMPRESSION_LZW = 5;
    const TIFF_COMPRESSION_JPEG = 6;
    const TIFF_COMPRESSION_FLATE = 8;
    const TIFF_COMPRESSION_FLATE_OBSOLETE_CODE = 32946;
    const TIFF_COMPRESSION_PACKBITS = 32773;

    const TIFF_PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO=0;
    const TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO=1;
    const TIFF_PHOTOMETRIC_INTERPRETATION_RGB=2;
    const TIFF_PHOTOMETRIC_INTERPRETATION_RGB_INDEXED=3;
    const TIFF_PHOTOMETRIC_INTERPRETATION_CMYK=5;
    const TIFF_PHOTOMETRIC_INTERPRETATION_YCBCR=6;
    const TIFF_PHOTOMETRIC_INTERPRETATION_CIELAB=8;

  /* PNG Constants */

    const PNG_COMPRESSION_DEFAULT_STRATEGY = 0;
    const PNG_COMPRESSION_FILTERED = 1;
    const PNG_COMPRESSION_HUFFMAN_ONLY = 2;
    const PNG_COMPRESSION_RLE = 3;

    const PNG_FILTER_NONE = 0;
    const PNG_FILTER_SUB = 1;
    const PNG_FILTER_UP = 2;
    const PNG_FILTER_AVERAGE = 3;
    const PNG_FILTER_PAETH = 4;

    const PNG_INTERLACING_DISABLED = 0;
    const PNG_INTERLACING_ENABLED = 1;

    const PNG_CHANNEL_GRAY = 0;
    const PNG_CHANNEL_RGB = 2;
    const PNG_CHANNEL_INDEXED = 3;
    const PNG_CHANNEL_GRAY_ALPHA = 4;
    const PNG_CHANNEL_RGB_ALPHA = 6;

  /**** Public Interface ****/

  /* Factory Methods */

    /**
     * Returns a {@link Zend_Pdf_Resource_Image} object by file path.
     *
     * @param string $filePath Full path to the image file.
     * @return Zend_Pdf_Resource_Image
     * @throws Zend_Pdf_Exception
     */
    public static function imageWithPath($filePath)
    {
        /**
         * use old implementation
         * @todo switch to new implementation
         */
        require_once 'Zend/Pdf/Resource/ImageFactory.php';
        return Zend_Pdf_Resource_ImageFactory::factory($filePath);

        /* Create a file parser data source object for this file. File path and
         * access permission checks are handled here.
         */
        require_once 'Zend/Pdf/FileParserDataSource/File.php';
        $dataSource = new Zend_Pdf_FileParserDataSource_File($filePath);

        /* Attempt to determine the type of image. We can't always trust file
         * extensions, but try that first since it's fastest.
         */
        $fileExtension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));

        /* If it turns out that the file is named improperly and we guess the
         * wrong type, we'll get null instead of an image object.
         */
        switch ($fileExtension) {
            case 'tif':
                //Fall through to next case;
            case 'tiff':
                $image = Zend_Pdf_Image::_extractTiffImage($dataSource);
                break;
            case 'png':
                $image = Zend_Pdf_Image::_extractPngImage($dataSource);
                break;
            case 'jpg':
                //Fall through to next case;
            case 'jpe':
                //Fall through to next case;
            case 'jpeg':
                $image = Zend_Pdf_Image::_extractJpegImage($dataSource);
                break;
            default:
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception("Cannot create image resource. File extension not known or unsupported type.");
                break;
        }

        /* Done with the data source object.
         */
        $dataSource = null;

        if ($image !== null) {
            return $image;

        } else {
            /* The type of image could not be determined. Give up.
             */
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception("Cannot determine image type: $filePath",
                                         Zend_Pdf_Exception::CANT_DETERMINE_IMAGE_TYPE);
         }
    }

    /**** Internal Methods ****/

    /* Image Extraction Methods */

    /**
     * Attempts to extract a JPEG Image from the data source.
     *
     * @param Zend_Pdf_FileParserDataSource $dataSource
     * @return Zend_Pdf_Resource_Image_Jpeg May also return null if
     *   the data source does not appear to contain valid image data.
     * @throws Zend_Pdf_Exception
     */
    protected static function _extractJpegImage($dataSource)
    {
        require_once 'Zend/Pdf/Exception.php';
        throw new Zend_Pdf_Exception('Jpeg image fileparser is not implemented. Old styly implementation has to be used.');

        require_once 'Zend/Pdf/FileParser/Image/Jpeg.php';
        $imageParser = new Zend_Pdf_FileParser_Image_Jpeg($dataSource);
        require_once 'Zend/Pdf/Resource/Image/Jpeg.php';
        $image = new Zend_Pdf_Resource_Image_Jpeg($imageParser);
        unset($imageParser);

        return $image;
    }

    /**
     * Attempts to extract a PNG Image from the data source.
     *
     * @param Zend_Pdf_FileParserDataSource $dataSource
     * @return Zend_Pdf_Resource_Image_Png May also return null if
     *   the data source does not appear to contain valid image data.
     */
    protected static function _extractPngImage($dataSource)
    {
        require_once 'Zend/Pdf/FileParser/Image/Png.php';
        $imageParser = new Zend_Pdf_FileParser_Image_Png($dataSource);
        require_once 'Zend/Pdf/Resource/Image/Png.php';
        $image = new Zend_Pdf_Resource_Image_Png($imageParser);
        unset($imageParser);

        return $image;
    }

    /**
     * Attempts to extract a TIFF Image from the data source.
     *
     * @param Zend_Pdf_FileParserDataSource $dataSource
     * @return Zend_Pdf_Resource_Image_Tiff May also return null if
     *   the data source does not appear to contain valid image data.
     * @throws Zend_Pdf_Exception
     */
    protected static function _extractTiffImage($dataSource)
    {
        require_once 'Zend/Pdf/Exception.php';
        throw new Zend_Pdf_Exception('Tiff image fileparser is not implemented. Old styly implementation has to be used.');

        require_once 'Zend/Pdf/FileParser/Image/Tiff.php';
        $imageParser = new Zend_Pdf_FileParser_Image_Tiff($dataSource);
        require_once 'Zend/Pdf/Resource/Image/Tiff.php';
        $image = new Zend_Pdf_Resource_Image_Tiff($imageParser);
        unset($imageParser);

        return $image;
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Actions
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: NameTree.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Internally used classes */
require_once 'Zend/Pdf/Element.php';

/**
 * PDF name tree representation class
 *
 * @todo implement lazy resource loading so resources will be really loaded at access time
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_NameTree implements ArrayAccess, Iterator, Countable
{
    /**
     * Elements
     * Array of name => object tree entries
     *
     * @var array
     */
    protected $_items = array();

    /**
     * Object constructor
     *
     * @param Zend_Pdf_Element $rootDictionary root of name dictionary
     */
    public function __construct(Zend_Pdf_Element $rootDictionary)
    {
        if ($rootDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Name tree root must be a dictionary.');
        }

        $intermediateNodes = array();
        $leafNodes         = array();
        if ($rootDictionary->Kids !== null) {
            $intermediateNodes[] = $rootDictionary;
        } else {
            $leafNodes[] = $rootDictionary;
        }

        while (count($intermediateNodes) != 0) {
            $newIntermediateNodes = array();
            foreach ($intermediateNodes as $node) {
                foreach ($node->Kids->items as $childNode) {
                    if ($childNode->Kids !== null) {
                        $newIntermediateNodes[] = $childNode;
                    } else {
                        $leafNodes[] = $childNode;
                    }
                }
            }
            $intermediateNodes = $newIntermediateNodes;
        }

        foreach ($leafNodes as $leafNode) {
            $destinationsCount = count($leafNode->Names->items)/2;
            for ($count = 0; $count < $destinationsCount; $count++) {
                $this->_items[$leafNode->Names->items[$count*2]->value] = $leafNode->Names->items[$count*2 + 1];
            }
        }
    }

    public function current()
    {
        return current($this->_items);
    }

    public function next()
    {
        return next($this->_items);
    }

    public function key()
    {
        return key($this->_items);
    }

    public function valid() {
        return current($this->_items)!==false;
    }

    public function rewind()
    {
        reset($this->_items);
    }

    public function offsetExists($offset)
    {
        return array_key_exists($offset, $this->_items);
    }

    public function offsetGet($offset)
    {
        return $this->_items[$offset];
    }

    public function offsetSet($offset, $value)
    {
        if ($offset === null) {
            $this->_items[]        = $value;
        } else {
            $this->_items[$offset] = $value;
        }
    }

    public function offsetUnset($offset)
    {
        unset($this->_items[$offset]);
    }

    public function clear()
    {
        $this->_items = array();
    }

    public function count()
    {
        return count($this->_items);
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Annotation
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Annotation.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Internally used classes */
require_once 'Zend/Pdf/Element.php';

/**
 * Abstract PDF annotation representation class
 *
 * An annotation associates an object such as a note, sound, or movie with a location
 * on a page of a PDF document, or provides a way to interact with the user by
 * means of the mouse and keyboard.
 *
 * @package    Zend_Pdf
 * @subpackage Annotation
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Pdf_Annotation
{
    /**
     * Annotation dictionary
     *
     * @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
     */
    protected $_annotationDictionary;

    /**
     * Get annotation dictionary
     *
     * @internal
     * @return Zend_Pdf_Element
     */
    public function getResource()
    {
        return $this->_annotationDictionary;
    }

    /**
     * Set bottom edge of the annotation rectangle.
     *
     * @param float $bottom
     * @return Zend_Pdf_Annotation
     */
    public function setBottom($bottom) {
        $this->_annotationDictionary->Rect->items[1]->touch();
        $this->_annotationDictionary->Rect->items[1]->value = $bottom;

        return $this;
    }

    /**
     * Get bottom edge of the annotation rectangle.
     *
     * @return float
     */
    public function getBottom() {
        return $this->_annotationDictionary->Rect->items[1]->value;
    }

    /**
     * Set top edge of the annotation rectangle.
     *
     * @param float $top
     * @return Zend_Pdf_Annotation
     */
    public function setTop($top) {
        $this->_annotationDictionary->Rect->items[3]->touch();
        $this->_annotationDictionary->Rect->items[3]->value = $top;

        return $this;
    }

    /**
     * Get top edge of the annotation rectangle.
     *
     * @return float
     */
    public function getTop() {
        return $this->_annotationDictionary->Rect->items[3]->value;
    }

    /**
     * Set right edge of the annotation rectangle.
     *
     * @param float $right
     * @return Zend_Pdf_Annotation
     */
    public function setRight($right) {
        $this->_annotationDictionary->Rect->items[2]->touch();
        $this->_annotationDictionary->Rect->items[2]->value = $right;

        return $this;
    }

    /**
     * Get right edge of the annotation rectangle.
     *
     * @return float
     */
    public function getRight() {
        return $this->_annotationDictionary->Rect->items[2]->value;
    }

    /**
     * Set left edge of the annotation rectangle.
     *
     * @param float $left
     * @return Zend_Pdf_Annotation
     */
    public function setLeft($left) {
        $this->_annotationDictionary->Rect->items[0]->touch();
        $this->_annotationDictionary->Rect->items[0]->value = $left;

        return $this;
    }

    /**
     * Get left edge of the annotation rectangle.
     *
     * @return float
     */
    public function getLeft() {
        return $this->_annotationDictionary->Rect->items[0]->value;
    }

    /**
     * Return text to be displayed for the annotation or, if this type of annotation
     * does not display text, an alternate description of the annotation’s contents
     * in human-readable form.
     *
     * @return string
     */
    public function getText() {
        if ($this->_annotationDictionary->Contents === null) {
            return '';
        }

        return $this->_annotationDictionary->Contents->value;
    }

    /**
     * Set text to be displayed for the annotation or, if this type of annotation
     * does not display text, an alternate description of the annotation’s contents
     * in human-readable form.
     *
     * @param string $text
     * @return Zend_Pdf_Annotation
     */
    public function setText($text) {
        require_once 'Zend/Pdf/Element/String.php';

        if ($this->_annotationDictionary->Contents === null) {
            $this->_annotationDictionary->touch();
            $this->_annotationDictionary->Contents = new Zend_Pdf_Element_String($text);
        } else {
            $this->_annotationDictionary->Contents->touch();
            $this->_annotationDictionary->Contents->value = new Zend_Pdf_Element_String($text);
        }

        return $this;
    }

    /**
     * Annotation object constructor
     *
     * @throws Zend_Pdf_Exception
     */
    public function __construct(Zend_Pdf_Element $annotationDictionary)
    {
        if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
        }

        $this->_annotationDictionary = $annotationDictionary;

        if ($this->_annotationDictionary->Type !== null  &&
            $this->_annotationDictionary->Type->value != 'Annot') {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Wrong resource type. \'Annot\' expected.');
        }

        if ($this->_annotationDictionary->Rect === null) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('\'Rect\' dictionary entry is required.');
        }

        if (count($this->_annotationDictionary->Rect->items) != 4 ||
            $this->_annotationDictionary->Rect->items[0]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
            $this->_annotationDictionary->Rect->items[1]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
            $this->_annotationDictionary->Rect->items[2]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
            $this->_annotationDictionary->Rect->items[3]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('\'Rect\' dictionary entry must be an array of four numeric elements.');
        }
    }

    /**
     * Load Annotation object from a specified resource
     *
     * @internal
     * @param Zend_Pdf_Element $resource
     * @return Zend_Pdf_Annotation
     */
    public static function load(Zend_Pdf_Element $resource)
    {
        /** @todo implementation */
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Actions
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Outline.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Abstract PDF outline representation class
 *
 * @todo Implement an ability to associate an outline item with a structure element (PDF 1.3 feature)
 *
 * @package    Zend_Pdf
 * @subpackage Outlines
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
abstract class Zend_Pdf_Outline implements RecursiveIterator, Countable
{
    /**
     * True if outline is open.
     *
     * @var boolean
     */
    protected $_open = false;

    /**
     * Array of child outlines (array of Zend_Pdf_Outline objects)
     *
     * @var array
     */
    public $childOutlines = array();

    /**
     * Get outline title.
     *
     * @return string
     */
    abstract public function getTitle();

    /**
     * Set outline title
     *
     * @param string $title
     * @return Zend_Pdf_Outline
     */
    abstract public function setTitle($title);

    /**
     * Returns true if outline item is open by default
     *
     * @return boolean
     */
    public function isOpen()
    {
        return $this->_open;
    }

    /**
     * Sets 'isOpen' outline flag
     *
     * @param boolean $isOpen
     * @return Zend_Pdf_Outline
     */
    public function setIsOpen($isOpen)
    {
        $this->_open = $isOpen;
        return $this;
    }

    /**
     * Returns true if outline item is displayed in italic
     *
     * @return boolean
     */
    abstract public function isItalic();

    /**
     * Sets 'isItalic' outline flag
     *
     * @param boolean $isItalic
     * @return Zend_Pdf_Outline
     */
    abstract public function setIsItalic($isItalic);

    /**
     * Returns true if outline item is displayed in bold
     *
     * @return boolean
     */
    abstract public function isBold();

    /**
     * Sets 'isBold' outline flag
     *
     * @param boolean $isBold
     * @return Zend_Pdf_Outline
     */
    abstract public function setIsBold($isBold);

    /**
     * Get outline text color.
     *
     * @return Zend_Pdf_Color_Rgb
     */
    abstract public function getColor();

    /**
     * Set outline text color.
     * (null means default color which is black)
     *
     * @param Zend_Pdf_Color_Rgb $color
     * @return Zend_Pdf_Outline
     */
    abstract public function setColor(Zend_Pdf_Color_Rgb $color);

    /**
     * Get outline target.
     *
     * @return Zend_Pdf_Target
     */
    abstract public function getTarget();

    /**
     * Set outline target.
     * Null means no target
     *
     * @param Zend_Pdf_Target|string $target
     * @return Zend_Pdf_Outline
     */
    abstract public function setTarget($target = null);

    /**
     * Get outline options
     *
     * @return array
     */
    public function getOptions()
    {
        return array('title'  => $this->_title,
                     'open'   => $this->_open,
                     'color'  => $this->_color,
                     'italic' => $this->_italic,
                     'bold'   => $this->_bold,
                     'target' => $this->_target);
    }

    /**
     * Set outline options
     *
     * @param array $options
     * @return Zend_Pdf_Action
     * @throws Zend_Pdf_Exception
     */
    public function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            switch ($key) {
                case 'title':
                    $this->setTitle($value);
                    break;

                case 'open':
                    $this->setIsOpen($value);
                    break;

                case 'color':
                    $this->setColor($value);
                    break;
                case 'italic':
                    $this->setIsItalic($value);
                    break;

                case 'bold':
                    $this->setIsBold($value);
                    break;

                case 'target':
                    $this->setTarget($value);
                    break;

                default:
                    require_once 'Zend/Pdf/Exception.php';
                    throw new Zend_Pdf_Exception("Unknown option name - '$key'.");
                    break;
            }
        }

        return $this;
    }

    /**
     * Create new Outline object
     *
     * It provides two forms of input parameters:
     *
     * 1. Zend_Pdf_Outline::create(string $title[, Zend_Pdf_Target $target])
     * 2. Zend_Pdf_Outline::create(array $options)
     *
     * Second form allows to provide outline options as an array.
     * The followed options are supported:
     *   'title'  - string, outline title, required
     *   'open'   - boolean, true if outline entry is open (default value is false)
     *   'color'  - Zend_Pdf_Color_Rgb object, true if outline entry is open (default value is null - black)
     *   'italic' - boolean, true if outline entry is displayed in italic (default value is false)
     *   'bold'   - boolean, true if outline entry is displayed in bold (default value is false)
     *   'target' - Zend_Pdf_Target object or string, outline item destination
     *
     * @return Zend_Pdf_Outline
     * @throws Zend_Pdf_Exception
     */
    public static function create($param1, $param2 = null)
    {
        require_once 'Zend/Pdf/Outline/Created.php';
        if (is_string($param1)) {
            if ($param2 !== null  &&  !($param2 instanceof Zend_Pdf_Target  ||  is_string($param2))) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Outline create method takes $title (string) and $target (Zend_Pdf_Target or string) or an array as an input');
            }

            return new Zend_Pdf_Outline_Created(array('title'  => $param1,
                                                      'target' => $param2));
        } else {
            if (!is_array($param1)  ||  $param2 !== null) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Outline create method takes $title (string) and $destination (Zend_Pdf_Destination) or an array as an input');
            }

            return new Zend_Pdf_Outline_Created($param1);
        }
    }

    /**
     * Returns number of the total number of open items at all levels of the outline.
     *
     * @internal
     * @return integer
     */
    public function openOutlinesCount()
    {
        $count = 1; // Include this outline

        if ($this->isOpen()) {
            foreach ($this->childOutlines as $child) {
                $count += $child->openOutlinesCount();
            }
        }

        return $count;
    }

    /**
     * Dump Outline and its child outlines into PDF structures
     *
     * Returns dictionary indirect object or reference
     *
     * @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
     */
    abstract public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory,
                                                                           $updateNavigation,
                                                          Zend_Pdf_Element $parent,
                                                          Zend_Pdf_Element $prev = null,
                                                          SplObjectStorage $processedOutlines = null);

    ////////////////////////////////////////////////////////////////////////
    //  RecursiveIterator interface methods
    //////////////

    /**
     * Returns the child outline.
     *
     * @return Zend_Pdf_Outline
     */
    public function current()
    {
        return current($this->childOutlines);
    }

    /**
     * Returns current iterator key
     *
     * @return integer
     */
    public function key()
    {
        return key($this->childOutlines);
    }

    /**
     * Go to next child
     */
    public function next()
    {
        return next($this->childOutlines);
    }

    /**
     * Rewind children
     */
    public function rewind()
    {
        return reset($this->childOutlines);
    }

    /**
     * Check if current position is valid
     *
     * @return boolean
     */
    public function valid()
    {
        return current($this->childOutlines) !== false;
    }

    /**
     * Returns the child outline.
     *
     * @return Zend_Pdf_Outline|null
     */
    public function getChildren()
    {
        return current($this->childOutlines);
    }

    /**
     * Implements RecursiveIterator interface.
     *
     * @return bool  whether container has any pages
     */
    public function hasChildren()
    {
        return count($this->childOutlines) > 0;
    }

    ////////////////////////////////////////////////////////////////////////
    //  Countable interface methods
    //////////////

    /**
     * count()
     *
     * @return int
     */
    public function count()
    {
        return count($this->childOutlines);
    }
}


text:
<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Pdf
 * @subpackage Actions
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: RecursivelyIteratableObjectsContainer.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * Iteratable objects container
 *
 * @package    Zend_Pdf
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Pdf_RecursivelyIteratableObjectsContainer implements RecursiveIterator, Countable
{
    protected $_objects = array();

    public function __construct(array $objects) { $this->_objects = $objects; }

    public function current()      { return current($this->_objects);            }
    public function key()          { return key($this->_objects);                }
    public function next()         { return next($this->_objects);               }
    public function rewind()       { return reset($this->_objects);              }
    public function valid()        { return current($this->_objects) !== false;  }
    public function getChildren()  { return current($this->_objects);            }
    public function hasChildren()  { return count($this->_objects) > 0;          }

    public function count() { return count($this->_objects); }
}