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 Fonts
 * @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: ByteEncoding.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Cmap */
require_once 'Zend/Pdf/Cmap.php';

/**
 * Implements the "byte encoding" character map (type 0).
 *
 * This is the (legacy) Apple standard encoding mechanism and provides coverage
 * for characters in the Mac Roman character set only. Consequently, this cmap
 * type should be used only as a last resort.
 *
 * The mapping from Mac Roman to Unicode can be found at
 * {@link http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT}.
 *
 * @package    Zend_Pdf
 * @subpackage Fonts
 * @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_Cmap_ByteEncoding extends Zend_Pdf_Cmap
{
  /**** Instance Variables ****/

    /**
     * Glyph index array. Stores the actual glyph numbers. The array keys are
     * the translated Unicode code points.
     * @var array
     */
    protected $_glyphIndexArray = array();

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

  /* Concrete Class Implementation */

    /**
     * Returns an array of glyph numbers corresponding to the Unicode characters.
     *
     * If a particular character doesn't exist in this font, the special 'missing
     * character glyph' will be substituted.
     *
     * See also {@link glyphNumberForCharacter()}.
     *
     * @param array $characterCodes Array of Unicode character codes (code points).
     * @return array Array of glyph numbers.
     */
    public function glyphNumbersForCharacters($characterCodes)
    {
        $glyphNumbers = array();
        foreach ($characterCodes as $key => $characterCode) {

           if (! isset($this->_glyphIndexArray[$characterCode])) {
                $glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
                continue;
            }

            $glyphNumbers[$key] = $this->_glyphIndexArray[$characterCode];

        }
        return $glyphNumbers;
    }

    /**
     * Returns the glyph number corresponding to the Unicode character.
     *
     * If a particular character doesn't exist in this font, the special 'missing
     * character glyph' will be substituted.
     *
     * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
     * operations.
     *
     * @param integer $characterCode Unicode character code (code point).
     * @return integer Glyph number.
     */
    public function glyphNumberForCharacter($characterCode)
    {
        if (! isset($this->_glyphIndexArray[$characterCode])) {
            return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
        }
        return $this->_glyphIndexArray[$characterCode];
    }

    /**
     * Returns an array containing the Unicode characters that have entries in
     * this character map.
     *
     * @return array Unicode character codes.
     */
    public function getCoveredCharacters()
    {
        return array_keys($this->_glyphIndexArray);
    }

    /**
     * Returns an array containing the glyphs numbers that have entries in this character map.
     * Keys are Unicode character codes (integers)
     *
     * This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
     * call, but this method do it in more effective way (prepare complete list instead of searching
     * glyph for each character code).
     *
     * @internal
     * @return array Array representing <Unicode character code> => <glyph number> pairs.
     */
    public function getCoveredCharactersGlyphs()
    {
        return $this->_glyphIndexArray;
    }

  /* Object Lifecycle */

    /**
     * Object constructor
     *
     * Parses the raw binary table data. Throws an exception if the table is
     * malformed.
     *
     * @param string $cmapData Raw binary cmap table data.
     * @throws Zend_Pdf_Exception
     */
    public function __construct($cmapData)
    {
        /* Sanity check: This table must be exactly 262 bytes long.
         */
        $actualLength = strlen($cmapData);
        if ($actualLength != 262) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Insufficient table data',
                                         Zend_Pdf_Exception::CMAP_TABLE_DATA_TOO_SMALL);
        }

        /* Sanity check: Make sure this is right data for this table type.
         */
        $type = $this->_extractUInt2($cmapData, 0);
        if ($type != Zend_Pdf_Cmap::TYPE_BYTE_ENCODING) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Wrong cmap table type',
                                         Zend_Pdf_Exception::CMAP_WRONG_TABLE_TYPE);
        }

        $length = $this->_extractUInt2($cmapData, 2);
        if ($length != $actualLength) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception("Table length ($length) does not match actual length ($actualLength)",
                                         Zend_Pdf_Exception::CMAP_WRONG_TABLE_LENGTH);
        }

        /* Mapping tables should be language-independent. The font may not work
         * as expected if they are not. Unfortunately, many font files in the
         * wild incorrectly record a language ID in this field, so we can't
         * call this a failure.
         */
        $language = $this->_extractUInt2($cmapData, 4);
        if ($language != 0) {
            // Record a warning here somehow?
        }

        /* The mapping between the Mac Roman and Unicode characters is static.
         * For simplicity, just put all 256 glyph indices into one array keyed
         * off the corresponding Unicode character.
         */
        $i = 6;
        $this->_glyphIndexArray[0x00]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x01]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x03]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x04]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x05]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x06]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x07]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x08]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x09]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x10]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x11]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x12]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x13]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x14]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x15]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x16]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x17]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x18]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x19]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x1f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x20]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x21]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x22]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x23]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x24]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x25]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x26]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x27]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x28]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x29]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x30]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x31]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x32]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x33]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x34]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x35]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x36]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x37]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x38]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x39]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x3f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x40]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x41]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x42]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x43]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x44]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x45]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x46]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x47]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x48]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x49]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x4f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x50]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x51]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x52]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x53]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x54]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x55]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x56]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x57]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x58]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x59]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x5f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x60]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x61]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x62]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x63]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x64]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x65]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x66]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x67]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x68]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x69]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x6f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x70]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x71]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x72]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x73]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x74]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x75]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x76]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x77]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x78]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x79]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7a]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7b]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7c]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7d]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7e]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x7f]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc4]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc7]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc9]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd6]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xdc]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe0]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe2]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe4]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe3]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe7]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe9]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xea]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xeb]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xed]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xec]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xee]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xef]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf3]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf2]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf4]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf6]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xfa]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf9]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xfb]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xfc]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2020] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb0]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa2]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa3]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa7]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2022] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb6]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xdf]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xae]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa9]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2122] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb4]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2260] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc6]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x221e] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2264] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2265] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2202] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2211] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x220f] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x03c0] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x222b] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xaa]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xba]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x03a9] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xe6]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xbf]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xac]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x221a] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0192] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2248] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2206] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xab]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xbb]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2026] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xa0]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc0]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc3]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd5]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0152] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0153] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2013] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2014] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x201c] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x201d] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2018] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2019] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf7]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x25ca] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xff]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0178] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2044] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x20ac] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2039] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x203a] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xfb01] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xfb02] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2021] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb7]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x201a] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x201e] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x2030] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc2]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xca]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc1]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xcb]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xc8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xcd]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xce]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xcf]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xcc]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd3]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd4]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xf8ff] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd2]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xda]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xdb]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xd9]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x0131] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02c6] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02dc] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xaf]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02d8] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02d9] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02da] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0xb8]   = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02dd] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02db] = ord($cmapData[$i++]);
        $this->_glyphIndexArray[0x02c7] = ord($cmapData[$i]);
    }

}


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 Fonts
 * @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: TrimmedTable.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Cmap */
require_once 'Zend/Pdf/Cmap.php';

/**
 * Implements the "trimmed table mapping" character map (type 6).
 *
 * This table type is preferred over the {@link Zend_Pdf_Cmap_SegmentToDelta}
 * table when the Unicode characters covered by the font fall into a single
 * contiguous range.
 *
 * @package    Zend_Pdf
 * @subpackage Fonts
 * @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_Cmap_TrimmedTable extends Zend_Pdf_Cmap
{
  /**** Instance Variables ****/

    /**
     * The starting character code covered by this table.
     * @var integer
     */
    protected $_startCode = 0;

    /**
     * The ending character code covered by this table.
     * @var integer
     */
    protected $_endCode = 0;

    /**
     * Glyph index array. Stores the actual glyph numbers.
     * @var array
     */
    protected $_glyphIndexArray = array();

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

  /* Concrete Class Implementation */

    /**
     * Returns an array of glyph numbers corresponding to the Unicode characters.
     *
     * If a particular character doesn't exist in this font, the special 'missing
     * character glyph' will be substituted.
     *
     * See also {@link glyphNumberForCharacter()}.
     *
     * @param array $characterCodes Array of Unicode character codes (code points).
     * @return array Array of glyph numbers.
     */
    public function glyphNumbersForCharacters($characterCodes)
    {
        $glyphNumbers = array();
        foreach ($characterCodes as $key => $characterCode) {

            if (($characterCode < $this->_startCode) || ($characterCode > $this->_endCode)) {
                $glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
                continue;
            }

            $glyphIndex = $characterCode - $this->_startCode;
            $glyphNumbers[$key] = $this->_glyphIndexArray[$glyphIndex];

        }
        return $glyphNumbers;
    }

    /**
     * Returns the glyph number corresponding to the Unicode character.
     *
     * If a particular character doesn't exist in this font, the special 'missing
     * character glyph' will be substituted.
     *
     * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
     * operations.
     *
     * @param integer $characterCode Unicode character code (code point).
     * @return integer Glyph number.
     */
    public function glyphNumberForCharacter($characterCode)
    {
        if (($characterCode < $this->_startCode) || ($characterCode > $this->_endCode)) {
            return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
        }
        $glyphIndex = $characterCode - $this->_startCode;
        return $this->_glyphIndexArray[$glyphIndex];
    }

    /**
     * Returns an array containing the Unicode characters that have entries in
     * this character map.
     *
     * @return array Unicode character codes.
     */
    public function getCoveredCharacters()
    {
        $characterCodes = array();
        for ($code = $this->_startCode; $code <= $this->_endCode; $code++) {
            $characterCodes[] = $code;
        }
        return $characterCodes;
    }

    /**
     * Returns an array containing the glyphs numbers that have entries in this character map.
     * Keys are Unicode character codes (integers)
     *
     * This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
     * call, but this method do it in more effective way (prepare complete list instead of searching
     * glyph for each character code).
     *
     * @internal
     * @return array Array representing <Unicode character code> => <glyph number> pairs.
     */
    public function getCoveredCharactersGlyphs()
    {
        $glyphNumbers = array();
        for ($code = $this->_startCode; $code <= $this->_endCode; $code++) {
            $glyphNumbers[$code] = $this->_glyphIndexArray[$code - $this->_startCode];
        }

        return $glyphNumbers;
    }

  /* Object Lifecycle */

    /**
     * Object constructor
     *
     * Parses the raw binary table data. Throws an exception if the table is
     * malformed.
     *
     * @param string $cmapData Raw binary cmap table data.
     * @throws Zend_Pdf_Exception
     */
    public function __construct($cmapData)
    {
        /* Sanity check: The table should be at least 9 bytes in size.
         */
        $actualLength = strlen($cmapData);
        if ($actualLength < 9) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Insufficient table data',
                                         Zend_Pdf_Exception::CMAP_TABLE_DATA_TOO_SMALL);
        }

        /* Sanity check: Make sure this is right data for this table type.
         */
        $type = $this->_extractUInt2($cmapData, 0);
        if ($type != Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Wrong cmap table type',
                                         Zend_Pdf_Exception::CMAP_WRONG_TABLE_TYPE);
        }

        $length = $this->_extractUInt2($cmapData, 2);
        if ($length != $actualLength) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception("Table length ($length) does not match actual length ($actualLength)",
                                         Zend_Pdf_Exception::CMAP_WRONG_TABLE_LENGTH);
        }

        /* Mapping tables should be language-independent. The font may not work
         * as expected if they are not. Unfortunately, many font files in the
         * wild incorrectly record a language ID in this field, so we can't
         * call this a failure.
         */
        $language = $this->_extractUInt2($cmapData, 4);
        if ($language != 0) {
            // Record a warning here somehow?
        }

        $this->_startCode = $this->_extractUInt2($cmapData, 6);

        $entryCount = $this->_extractUInt2($cmapData, 8);
        $expectedCount = ($length - 10) >> 1;
        if ($entryCount != $expectedCount) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception("Entry count is wrong; expected: $expectedCount; actual: $entryCount",
                                         Zend_Pdf_Exception::CMAP_WRONG_ENTRY_COUNT);
        }

        $this->_endCode = $this->_startCode + $entryCount - 1;

        $offset = 10;
        for ($i = 0; $i < $entryCount; $i++, $offset += 2) {
            $this->_glyphIndexArray[] = $this->_extractUInt2($cmapData, $offset);
        }

        /* Sanity check: After reading all of the data, we should be at the end
         * of the table.
         */
        if ($offset != $length) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception("Ending offset ($offset) does not match length ($length)",
                                         Zend_Pdf_Exception::CMAP_FINAL_OFFSET_NOT_LENGTH);
        }
    }

}

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
 * @subpackage Fonts
 * @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: Static.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Cmap_ByteEncoding */
require_once 'Zend/Pdf/Cmap/ByteEncoding.php';

/**
 * Custom cmap type used for the Adobe Standard 14 PDF fonts.
 *
 * Just like {@link Zend_Pdf_Cmap_ByteEncoding} except that the constructor
 * takes a predefined array of glyph numbers and can cover any Unicode character.
 *
 * @package    Zend_Pdf
 * @subpackage Fonts
 * @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_Cmap_ByteEncoding_Static extends Zend_Pdf_Cmap_ByteEncoding
{
  /**** Public Interface ****/

  /* Object Lifecycle */

    /**
     * Object constructor
     *
     * @param array $cmapData Array whose keys are Unicode character codes and
     *   values are glyph numbers.
     * @throws Zend_Pdf_Exception
     */
    public function __construct($cmapData)
    {
        if (! is_array($cmapData)) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Constructor parameter must be an array',
                                         Zend_Pdf_Exception::BAD_PARAMETER_TYPE);
        }
        $this->_glyphIndexArray = $cmapData;
    }

}


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: Loaded.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/Numeric.php';
require_once 'Zend/Pdf/Element/String.php';

/** Zend_Pdf_Outline */
require_once 'Zend/Pdf/Outline.php';

/**
 * Traceable PDF outline representation class
 *
 * Instances of this class trace object update uperations. That allows to avoid outlines PDF tree update
 * which should be performed at each document update otherwise.
 *
 * @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
 */
class Zend_Pdf_Outline_Loaded extends Zend_Pdf_Outline
{
    /**
     * Outline dictionary object
     *
     * @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
     */
    protected $_outlineDictionary;

    /**
     * original array of child outlines
     *
     * @var array
     */
    protected $_originalChildOutlines = array();

    /**
     * Get outline title.
     *
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public function getTitle()
    {
        if ($this->_outlineDictionary->Title === null) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Outline dictionary Title entry is required.');
        }
        return $this->_outlineDictionary->Title->value;
    }

    /**
     * Set outline title
     *
     * @param string $title
     * @return Zend_Pdf_Outline
     */
    public function setTitle($title)
    {
        $this->_outlineDictionary->Title->touch();
        $this->_outlineDictionary->Title = new Zend_Pdf_Element_String($title);
        return $this;
    }

    /**
     * Sets 'isOpen' outline flag
     *
     * @param boolean $isOpen
     * @return Zend_Pdf_Outline
     */
    public function setIsOpen($isOpen)
    {
        parent::setIsOpen($isOpen);

        if ($this->_outlineDictionary->Count === null) {
            // Do Nothing.
            return this;
        }

        $childrenCount = $this->_outlineDictionary->Count->value;
        $isOpenCurrentState = ($childrenCount > 0);
        if ($isOpen != $isOpenCurrentState) {
            $this->_outlineDictionary->Count->touch();
            $this->_outlineDictionary->Count->value = ($isOpen? 1 : -1)*abs($childrenCount);
        }

        return $this;
    }

    /**
     * Returns true if outline item is displayed in italic
     *
     * @return boolean
     */
    public function isItalic()
    {
        if ($this->_outlineDictionary->F === null) {
            return false;
        }
        return $this->_outlineDictionary->F->value & 1;
    }

    /**
     * Sets 'isItalic' outline flag
     *
     * @param boolean $isItalic
     * @return Zend_Pdf_Outline
     */
    public function setIsItalic($isItalic)
    {
        if ($this->_outlineDictionary->F === null) {
            $this->_outlineDictionary->touch();
            $this->_outlineDictionary->F = new Zend_Pdf_Element_Numeric($isItalic? 1 : 0);
        } else {
            $this->_outlineDictionary->F->touch();
            if ($isItalic) {
                $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | 1;
            } else {
                $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | ~1;
            }
        }
        return $this;
    }

    /**
     * Returns true if outline item is displayed in bold
     *
     * @return boolean
     */
    public function isBold()
    {
        if ($this->_outlineDictionary->F === null) {
            return false;
        }
        return $this->_outlineDictionary->F->value & 2;
    }

    /**
     * Sets 'isBold' outline flag
     *
     * @param boolean $isBold
     * @return Zend_Pdf_Outline
     */
    public function setIsBold($isBold)
    {
        if ($this->_outlineDictionary->F === null) {
            $this->_outlineDictionary->touch();
            $this->_outlineDictionary->F = new Zend_Pdf_Element_Numeric($isBold? 2 : 0);
        } else {
            $this->_outlineDictionary->F->touch();
            if ($isBold) {
                $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | 2;
            } else {
                $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | ~2;
            }
        }
        return $this;
    }

    /**
     * Get outline text color.
     *
     * @return Zend_Pdf_Color_Rgb
     */
    public function getColor()
    {
        if ($this->_outlineDictionary->C === null) {
            return null;
        }

        $components = $this->_outlineDictionary->C->items;

        require_once 'Zend/Pdf/Color/Rgb.php';
        return new Zend_Pdf_Color_Rgb($components[0], $components[1], $components[2]);
    }

    /**
     * Set outline text color.
     * (null means default color which is black)
     *
     * @param Zend_Pdf_Color_Rgb $color
     * @return Zend_Pdf_Outline
     */
    public function setColor(Zend_Pdf_Color_Rgb $color)
    {
        $this->_outlineDictionary->touch();

        if ($color === null) {
            $this->_outlineDictionary->C = null;
        } else {
            $components = $color->getComponents();
            $colorComponentElements = array(new Zend_Pdf_Element_Numeric($components[0]),
                                            new Zend_Pdf_Element_Numeric($components[1]),
                                            new Zend_Pdf_Element_Numeric($components[2]));
            $this->_outlineDictionary->C = new Zend_Pdf_Element_Array($colorComponentElements);
        }

        return $this;
    }

    /**
     * Get outline target.
     *
     * @return Zend_Pdf_Target
     * @throws Zend_Pdf_Exception
     */
    public function getTarget()
    {
        if ($this->_outlineDictionary->Dest !== null) {
            if ($this->_outlineDictionary->A !== null) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Outline dictionary may contain Dest or A entry, but not both.');
            }

            require_once 'Zend/Pdf/Destination.php';
            return Zend_Pdf_Destination::load($this->_outlineDictionary->Dest);
        } else if ($this->_outlineDictionary->A !== null) {
            require_once 'Zend/Pdf/Action.php';
            return Zend_Pdf_Action::load($this->_outlineDictionary->A);
        }

        return null;
    }

    /**
     * Set outline target.
     * Null means no target
     *
     * @param Zend_Pdf_Target|string $target
     * @return Zend_Pdf_Outline
     * @throws Zend_Pdf_Exception
     */
    public function setTarget($target = null)
    {
        $this->_outlineDictionary->touch();

        if (is_string($target)) {
            require_once 'Zend/Pdf/Destination/Named.php';
            $target = Zend_Pdf_Destination_Named::create($target);
        }

        if ($target === null) {
            $this->_outlineDictionary->Dest = null;
            $this->_outlineDictionary->A    = null;
        } else if ($target instanceof Zend_Pdf_Destination) {
            $this->_outlineDictionary->Dest = $target->getResource();
            $this->_outlineDictionary->A    = null;
        } else if ($target instanceof Zend_Pdf_Action) {
            $this->_outlineDictionary->Dest = null;
            $this->_outlineDictionary->A    = $target->getResource();
        } else {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination or Zend_Pdf_Action object or string');
        }

        return $this;
    }

    /**
     * Set outline options
     *
     * @param array $options
     * @return Zend_Pdf_Actions_Traceable
     * @throws Zend_Pdf_Exception
     */
    public function setOptions(array $options)
    {
        parent::setOptions($options);

        return $this;
    }

    /**
     * Create PDF outline object using specified dictionary
     *
     * @internal
     * @param Zend_Pdf_Element $dictionary (It's actually Dictionary or Dictionary Object or Reference to a Dictionary Object)
     * @param Zend_Pdf_Action  $parentAction
     * @param SplObjectStorage $processedOutlines  List of already processed Outline dictionaries,
     *                                             used to avoid cyclic references
     * @return Zend_Pdf_Action
     * @throws Zend_Pdf_Exception
     */
    public function __construct(Zend_Pdf_Element $dictionary, SplObjectStorage $processedDictionaries = null)
    {
        if ($dictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('$dictionary mast be an indirect dictionary object.');
        }

        if ($processedDictionaries === null) {
            $processedDictionaries = new SplObjectStorage();
        }
        $processedDictionaries->attach($dictionary);

        $this->_outlineDictionary = $dictionary;

        if ($dictionary->Count !== null) {
            if ($dictionary->Count->getType() != Zend_Pdf_Element::TYPE_NUMERIC) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Outline dictionary Count entry must be a numeric element.');
            }

            $childOutlinesCount = $dictionary->Count->value;
            if ($childOutlinesCount > 0) {
                $this->_open = true;
            }
            $childOutlinesCount = abs($childOutlinesCount);

            $childDictionary = $dictionary->First;

            $children = new SplObjectStorage();
            while ($childDictionary !== null) {
                // Check children structure for cyclic references
                if ($children->contains($childDictionary)) {
                    require_once 'Zend/Pdf/Exception.php';
                    throw new Zend_Pdf_Exception('Outline childs load error.');
                }

                if (!$processedDictionaries->contains($childDictionary)) {
                    $this->childOutlines[] = new Zend_Pdf_Outline_Loaded($childDictionary, $processedDictionaries);
                }

                $childDictionary = $childDictionary->Next;
            }

            $this->_originalChildOutlines = $this->childOutlines;
        }
    }

    /**
     * Dump Outline and its child outlines into PDF structures
     *
     * Returns dictionary indirect object or reference
     *
     * @internal
     * @param Zend_Pdf_ElementFactory    $factory object factory for newly created indirect objects
     * @param boolean $updateNavigation  Update navigation flag
     * @param Zend_Pdf_Element $parent   Parent outline dictionary reference
     * @param Zend_Pdf_Element $prev     Previous outline dictionary reference
     * @param SplObjectStorage $processedOutlines  List of already processed outlines
     * @return Zend_Pdf_Element
     * @throws Zend_Pdf_Exception
     */
    public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory,
                                                                  $updateNavigation,
                                                 Zend_Pdf_Element $parent,
                                                 Zend_Pdf_Element $prev = null,
                                                 SplObjectStorage $processedOutlines = null)
    {
        if ($processedOutlines === null) {
            $processedOutlines = new SplObjectStorage();
        }
        $processedOutlines->attach($this);

        if ($updateNavigation) {
            $this->_outlineDictionary->touch();

            $this->_outlineDictionary->Parent = $parent;
            $this->_outlineDictionary->Prev   = $prev;
            $this->_outlineDictionary->Next   = null;
        }

        $updateChildNavigation = false;
        if (count($this->_originalChildOutlines) != count($this->childOutlines)) {
            // If original and current children arrays have different size then children list was updated
            $updateChildNavigation = true;
        } else if ( !(array_keys($this->_originalChildOutlines) === array_keys($this->childOutlines)) ) {
            // If original and current children arrays have different keys (with a glance to an order) then children list was updated
            $updateChildNavigation = true;
        } else {
            foreach ($this->childOutlines as $key => $childOutline) {
                if ($this->_originalChildOutlines[$key] !== $childOutline) {
                    $updateChildNavigation = true;
                    break;
                }
            }
        }

        $lastChild = null;
        if ($updateChildNavigation) {
            $this->_outlineDictionary->touch();
            $this->_outlineDictionary->First = null;

            foreach ($this->childOutlines as $childOutline) {
                if ($processedOutlines->contains($childOutline)) {
                    require_once 'Zend/Pdf/Exception.php';
                    throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.');
                }

                if ($lastChild === null) {
                    // First pass. Update Outlines dictionary First entry using corresponding value
                    $lastChild = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, null, $processedOutlines);
                    $this->_outlineDictionary->First = $lastChild;
                } else {
                    // Update previous outline dictionary Next entry (Prev is updated within dumpOutline() method)
                    $childOutlineDictionary = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, $lastChild, $processedOutlines);
                    $lastChild->Next = $childOutlineDictionary;
                    $lastChild       = $childOutlineDictionary;
                }
            }

            $this->_outlineDictionary->Last  = $lastChild;

            if (count($this->childOutlines) != 0) {
                $this->_outlineDictionary->Count = new Zend_Pdf_Element_Numeric(($this->isOpen()? 1 : -1)*count($this->childOutlines));
            } else {
                $this->_outlineDictionary->Count = null;
            }
        } else {
            foreach ($this->childOutlines as $childOutline) {
                if ($processedOutlines->contains($childOutline)) {
                    require_once 'Zend/Pdf/Exception.php';
                    throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.');
                }
                $lastChild = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, $lastChild, $processedOutlines);
            }
        }

        return $this->_outlineDictionary;
    }

    public function dump($level = 0)
    {
        printf(":%3d:%s:%s:%s%s  :\n", count($this->childOutlines),$this->isItalic()? 'i':' ', $this->isBold()? 'b':' ', str_pad('', 4*$level), $this->getTitle());

        if ($this->isOpen()  ||  true) {
            foreach ($this->childOutlines as $child) {
                $child->dump($level + 1);
            }
        }
    }
}


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: Created.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Internally used classes */
require_once 'Zend/Pdf/Element/Array.php';
require_once 'Zend/Pdf/Element/Dictionary.php';
require_once 'Zend/Pdf/Element/Numeric.php';
require_once 'Zend/Pdf/Element/String.php';

/** Zend_Pdf_Outline */
require_once 'Zend/Pdf/Outline.php';

/**
 * 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
 */
class Zend_Pdf_Outline_Created extends Zend_Pdf_Outline
{
    /**
     * Outline title.
     *
     * @var string
     */
    protected $_title;

    /**
     * Color to be used for the outline entry’s text.

     * It uses the DeviceRGB color space for color representation.
     * Null means default value - black ([0.0 0.0 0.0] in RGB representation).
     *
     * @var Zend_Pdf_Color_Rgb
     */
    protected $_color = null;

    /**
     * True if outline item is displayed in italic.
     * Default value is false.
     *
     * @var boolean
     */
    protected $_italic = false;

    /**
     * True if outline item is displayed in bold.
     * Default value is false.
     *
     * @var boolean
     */
    protected $_bold = false;

    /**
     * Target destination or action.
     * String means named destination
     *
     * Null means no target.
     *
     * @var Zend_Pdf_Destination|Zend_Pdf_Action
     */
    protected $_target = null;

    /**
     * Get outline title.
     *
     * @return string
     */
    public function getTitle()
    {
        return $this->_title;
    }

    /**
     * Set outline title
     *
     * @param string $title
     * @return Zend_Pdf_Outline
     */
    public function setTitle($title)
    {
        $this->_title = $title;
        return $this;
    }

    /**
     * Returns true if outline item is displayed in italic
     *
     * @return boolean
     */
    public function isItalic()
    {
        return $this->_italic;
    }

    /**
     * Sets 'isItalic' outline flag
     *
     * @param boolean $isItalic
     * @return Zend_Pdf_Outline
     */
    public function setIsItalic($isItalic)
    {
        $this->_italic = $isItalic;
        return $this;
    }

    /**
     * Returns true if outline item is displayed in bold
     *
     * @return boolean
     */
    public function isBold()
    {
        return $this->_bold;
    }

    /**
     * Sets 'isBold' outline flag
     *
     * @param boolean $isBold
     * @return Zend_Pdf_Outline
     */
    public function setIsBold($isBold)
    {
        $this->_bold = $isBold;
        return $this;
    }

    /**
     * Get outline text color.
     *
     * @return Zend_Pdf_Color_Rgb
     */
    public function getColor()
    {
        return $this->_color;
    }

    /**
     * Set outline text color.
     * (null means default color which is black)
     *
     * @param Zend_Pdf_Color_Rgb $color
     * @return Zend_Pdf_Outline
     */
    public function setColor(Zend_Pdf_Color_Rgb $color)
    {
        $this->_color = $color;
        return $this;
    }

    /**
     * Get outline target.
     *
     * @return Zend_Pdf_Target
     */
    public function getTarget()
    {
        return $this->_target;
    }

    /**
     * Set outline target.
     * Null means no target
     *
     * @param Zend_Pdf_Target|string $target
     * @return Zend_Pdf_Outline
     * @throws Zend_Pdf_Exception
     */
    public function setTarget($target = null)
    {
        if (is_string($target)) {
            require_once 'Zend/Pdf/Destination/Named.php';
            $target = new Zend_Pdf_Destination_Named($target);
        }

        if ($target === null  ||  $target instanceof Zend_Pdf_Target) {
            $this->_target = $target;
        } else {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination or Zend_Pdf_Action object or string');
        }

        return $this;
    }

    /**
     * Object constructor
     *
     * @param array $options
     * @throws Zend_Pdf_Exception
     */
    public function __construct($options = array())
    {
        if (!isset($options['title'])) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Title parameter is required.');
        }

        $this->setOptions($options);
    }

    /**
     * Dump Outline and its child outlines into PDF structures
     *
     * Returns dictionary indirect object or reference
     *
     * @internal
     * @param Zend_Pdf_ElementFactory    $factory object factory for newly created indirect objects
     * @param boolean $updateNavigation  Update navigation flag
     * @param Zend_Pdf_Element $parent   Parent outline dictionary reference
     * @param Zend_Pdf_Element $prev     Previous outline dictionary reference
     * @param SplObjectStorage $processedOutlines  List of already processed outlines
     * @return Zend_Pdf_Element
     * @throws Zend_Pdf_Exception
     */
    public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory,
                                                                  $updateNavigation,
                                                 Zend_Pdf_Element $parent,
                                                 Zend_Pdf_Element $prev = null,
                                                 SplObjectStorage $processedOutlines = null)
    {
        if ($processedOutlines === null) {
            $processedOutlines = new SplObjectStorage();
        }
        $processedOutlines->attach($this);

        $outlineDictionary = $factory->newObject(new Zend_Pdf_Element_Dictionary());

        $outlineDictionary->Title = new Zend_Pdf_Element_String($this->getTitle());

        $target = $this->getTarget();
        if ($target === null) {
            // Do nothing
        } else if ($target instanceof Zend_Pdf_Destination) {
            $outlineDictionary->Dest = $target->getResource();
        } else if ($target instanceof Zend_Pdf_Action) {
            $outlineDictionary->A    = $target->getResource();
        } else {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination, Zend_Pdf_Action object or null');
        }

        $color = $this->getColor();
        if ($color !== null) {
            $components = $color->getComponents();
            $colorComponentElements = array(new Zend_Pdf_Element_Numeric($components[0]),
                                            new Zend_Pdf_Element_Numeric($components[1]),
                                            new Zend_Pdf_Element_Numeric($components[2]));
            $outlineDictionary->C = new Zend_Pdf_Element_Array($colorComponentElements);
        }

        if ($this->isItalic()  ||  $this->isBold()) {
            $outlineDictionary->F = new Zend_Pdf_Element_Numeric(($this->isItalic()? 1 : 0)  |   // Bit 1 - Italic
                                                                 ($this->isBold()?   2 : 0));    // Bit 2 - Bold
        }

        $outlineDictionary->Parent = $parent;
        $outlineDictionary->Prev   = $prev;

        $lastChild = null;
        foreach ($this->childOutlines as $childOutline) {
            if ($processedOutlines->contains($childOutline)) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.');
            }

            if ($lastChild === null) {
                $lastChild = $childOutline->dumpOutline($factory, true, $outlineDictionary, null, $processedOutlines);
                $outlineDictionary->First = $lastChild;
            } else {
                $childOutlineDictionary = $childOutline->dumpOutline($factory, true, $outlineDictionary, $lastChild, $processedOutlines);
                $lastChild->Next = $childOutlineDictionary;
                $lastChild       = $childOutlineDictionary;
            }
        }
        $outlineDictionary->Last = $lastChild;

        if (count($this->childOutlines) != 0) {
            $outlineDictionary->Count = new Zend_Pdf_Element_Numeric(($this->isOpen()? 1 : -1)*count($this->childOutlines));
        }

        return $outlineDictionary;
    }
}


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: Interface.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * PDF element factory interface.
 * 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
 */
interface Zend_Pdf_ElementFactory_Interface
{
    /**
     * Get factory
     *
     * @return Zend_Pdf_ElementFactory_Interface
     */
    public function getFactory();

    /**
     * Close factory and clean-up resources
     *
     * @internal
     */
    public function close();

    /**
     * Get source factory object
     *
     * @return Zend_Pdf_ElementFactory
     */
    public function resolve();

    /**
     * Get factory ID
     *
     * @return integer
     */
    public function getId();

    /**
     * Set object counter
     *
     * @param integer $objCount
     */
    public function setObjectCount($objCount);

    /**
     * Get object counter
     *
     * @return integer
     */
    public function getObjectCount();

    /**
     * Attach factory to the current;
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     */
    public function attach(Zend_Pdf_ElementFactory_Interface $factory);

    /**
     * Calculate object enumeration shift.
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     */
    public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory);

    /**
     * Clean enumeration shift cache.
     * Has to be used after PDF render operation to let followed updates be correct.
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     */
    public function 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);

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

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

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

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

    /**
     * Enumerate modified objects.
     * Returns array of Zend_Pdf_UpdateInfoContainer
     *
     * @param Zend_Pdf_ElementFactory $rootFactory
     * @return array
     */
    public function listModifiedObjects($rootFactory = null);

    /**
     * Check if PDF file was modified
     *
     * @return boolean
     */
    public function isModified();
}


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: Proxy.php 23775 2011-03-01 17:25:24Z ralph $
 */

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

/**
 * PDF element factory interface.
 * 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_Proxy implements Zend_Pdf_ElementFactory_Interface
{
    /**
     * Factory object
     *
     * @var Zend_Pdf_ElementFactory_Interface
     */
    private $_factory;

    /**
     * Object constructor
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     */
    public function __construct(Zend_Pdf_ElementFactory_Interface $factory)
    {
        $this->_factory = $factory;
    }

    public function __destruct()
    {
        $this->_factory->close();
        $this->_factory = null;
    }

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

    /**
     * Close factory and clean-up resources
     *
     * @internal
     */
    public function close()
    {
        // Do nothing
    }

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

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

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

    /**
     * Get object counter
     *
     * @return integer
     */
    public function getObjectCount()
    {
        return $this->_factory->getObjectCount();
    }

    /**
     * Attach factory to the current;
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     */
    public function attach(Zend_Pdf_ElementFactory_Interface $factory)
    {
        $this->_factory->attach($factory);
    }

    /**
     * Calculate object enumeration shift.
     *
     * @internal
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     */
    public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory)
    {
        return $this->_factory->calculateShift($factory);
    }

    /**
     * Clean enumeration shift cache.
     * Has to be used after PDF render operation to let followed updates be correct.
     *
     * @param Zend_Pdf_ElementFactory_Interface $factory
     * @return integer
     */
    public function cleanEnumerationShiftCache()
    {
        return $this->_factory->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)
    {
        return $this->_factory->getEnumerationShift($factory);
    }

    /**
     * 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)
    {
        $this->_factory->markAsModified($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)
    {
        $this->_factory->remove($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)
    {
        return $this->_factory->newObject($objectValue);
    }

    /**
     * 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)
    {
        return $this->_factory->newStreamObject($streamValue);
    }

    /**
     * Enumerate modified objects.
     * Returns array of Zend_Pdf_UpdateInfoContainer
     *
     * @param Zend_Pdf_ElementFactory $rootFactory
     * @return array
     */
    public function listModifiedObjects($rootFactory = null)
    {
        return $this->_factory->listModifiedObjects($rootFactory);
    }

    /**
     * Check if PDF file was modified
     *
     * @return boolean
     */
    public function isModified()
    {
        return $this->_factory->isModified();
    }
}


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: Keeper.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Trailer */
require_once 'Zend/Pdf/Trailer.php';

/**
 * PDF file trailer.
 * Stores and provides access to the trailer parced from a PDF file
 *
 * @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_Trailer_Keeper extends Zend_Pdf_Trailer
{
    /**
     * Reference context
     *
     * @var Zend_Pdf_Element_Reference_Context
     */
    private $_context;

    /**
     * Previous trailer
     *
     * @var Zend_Pdf_Trailer
     */
    private $_prev;

    /**
     * Object constructor
     *
     * @param Zend_Pdf_Element_Dictionary $dict
     * @param Zend_Pdf_Element_Reference_Context $context
     * @param Zend_Pdf_Trailer $prev
     */
    public function __construct(Zend_Pdf_Element_Dictionary $dict,
                                Zend_Pdf_Element_Reference_Context $context,
                                Zend_Pdf_Trailer $prev = null)
    {
        parent::__construct($dict);

        $this->_context = $context;
        $this->_prev    = $prev;
    }

    /**
     * Setter for $this->_prev
     *
     * @param Zend_Pdf_Trailer_Keeper $prev
     */
    public function setPrev(Zend_Pdf_Trailer_Keeper $prev)
    {
        $this->_prev = $prev;
    }

    /**
     * Getter for $this->_prev
     *
     * @return Zend_Pdf_Trailer
     */
    public function getPrev()
    {
        return $this->_prev;
    }

    /**
     * Get length of source PDF
     *
     * @return string
     */
    public function getPDFLength()
    {
        return $this->_context->getParser()->getLength();
    }

    /**
     * Get PDF String
     *
     * @return string
     */
    public function getPDFString()
    {
        return $this->_context->getParser()->getString();
    }

    /**
     * Get reference table, which corresponds to the trailer.
     * Proxy to the $_context member methad call
     *
     * @return Zend_Pdf_Element_Reference_Context
     */
    public function getRefTable()
    {
        return $this->_context->getRefTable();
    }

    /**
     * Get header of free objects list
     * Returns object number of last free object
     *
     * @throws Zend_Pdf_Exception
     * @return integer
     */
    public function getLastFreeObject()
    {
        try {
            $this->_context->getRefTable()->getNextFree('0 65535 R');
        } catch (Zend_Pdf_Exception $e) {
            if ($e->getMessage() == 'Object not found.') {
                /**
                 * Here is work around for some wrong generated PDFs.
                 * We have not found reference to the header of free object list,
                 * thus we treat it as there are no free objects.
                 */
                return 0;
            }

            throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
        }
    }
}


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: Generator.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Trailer */
require_once 'Zend/Pdf/Trailer.php';

/**
 * PDF file trailer generator (used for just created PDF)
 *
 * @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_Trailer_Generator extends Zend_Pdf_Trailer
{
    /**
     * Object constructor
     *
     * @param Zend_Pdf_Element_Dictionary $dict
     */
    public function __construct(Zend_Pdf_Element_Dictionary $dict)
    {
        parent::__construct($dict);
    }

    /**
     * Get length of source PDF
     *
     * @return string
     */
    public function getPDFLength()
    {
        require_once 'Zend/Pdf.php';
        return strlen(Zend_Pdf::PDF_HEADER);
    }

    /**
     * Get PDF String
     *
     * @return string
     */
    public function getPDFString()
    {
        require_once 'Zend/Pdf.php';
        return Zend_Pdf::PDF_HEADER;
    }

    /**
     * Get header of free objects list
     * Returns object number of last free object
     *
     * @return integer
     */
    public function getLastFreeObject()
    {
        return 0;
    }
}


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: Compression.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Filter_Interface */
require_once 'Zend/Pdf/Filter/Interface.php';

/**
 * ASCII85 stream filter
 *
 * @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
 */
abstract class Zend_Pdf_Filter_Compression implements Zend_Pdf_Filter_Interface
{
    /**
     * Paeth prediction function
     *
     * @param integer $a
     * @param integer $b
     * @param integer $c
     * @return integer
     */
    private static function _paeth($a, $b, $c)
    {
        // $a - left, $b - above, $c - upper left
        $p  = $a + $b - $c;       // initial estimate
        $pa = abs($p - $a);       // distances to a, b, c
        $pb = abs($p - $b);
        $pc = abs($p - $c);

        // return nearest of a,b,c,
        // breaking ties in order a,b,c.
        if ($pa <= $pb && $pa <= $pc) {
            return $a;
        } else if ($pb <= $pc) {
            return $b;
        } else {
            return $c;
        }
    }

    /**
     * Get Predictor decode param value
     *
     * @param array $params
     * @return integer
     * @throws Zend_Pdf_Exception
     */
    private static function _getPredictorValue(&$params)
    {
        if (isset($params['Predictor'])) {
            $predictor = $params['Predictor'];

            if ($predictor != 1   &&  $predictor != 2   &&
                $predictor != 10  &&  $predictor != 11  &&   $predictor != 12  &&
                $predictor != 13  &&  $predictor != 14  &&   $predictor != 15) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Invalid value of \'Predictor\' decode param - ' . $predictor . '.' );
            }
            return $predictor;
        } else {
            return 1;
        }
    }

    /**
     * Get Colors decode param value
     *
     * @param array $params
     * @return integer
     * @throws Zend_Pdf_Exception
     */
    private static function _getColorsValue(&$params)
    {
        if (isset($params['Colors'])) {
            $colors = $params['Colors'];

            if ($colors != 1  &&  $colors != 2  &&  $colors != 3  &&  $colors != 4) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Invalid value of \'Color\' decode param - ' . $colors . '.' );
            }
            return $colors;
        } else {
            return 1;
        }
    }

    /**
     * Get BitsPerComponent decode param value
     *
     * @param array $params
     * @return integer
     * @throws Zend_Pdf_Exception
     */
    private static function _getBitsPerComponentValue(&$params)
    {
        if (isset($params['BitsPerComponent'])) {
            $bitsPerComponent = $params['BitsPerComponent'];

            if ($bitsPerComponent != 1  &&  $bitsPerComponent != 2  &&
                $bitsPerComponent != 4  &&  $bitsPerComponent != 8  &&
                $bitsPerComponent != 16 ) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Invalid value of \'BitsPerComponent\' decode param - ' . $bitsPerComponent . '.' );
            }
            return $bitsPerComponent;
        } else {
            return 8;
        }
    }

    /**
     * Get Columns decode param value
     *
     * @param array $params
     * @return integer
     */
    private static function _getColumnsValue(&$params)
    {
        if (isset($params['Columns'])) {
            return $params['Columns'];
        } else {
            return 1;
        }
    }

    /**
     * Convert stream data according to the filter params set before encoding.
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    protected static function _applyEncodeParams($data, $params) {
        $predictor        = self::_getPredictorValue($params);
        $colors           = self::_getColorsValue($params);
        $bitsPerComponent = self::_getBitsPerComponentValue($params);
        $columns          = self::_getColumnsValue($params);

        /** None of prediction */
        if ($predictor == 1) {
            return $data;
        }

        /** TIFF Predictor 2 */
        if ($predictor == 2) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Not implemented yet' );
        }

        /** Optimal PNG prediction */
        if ($predictor == 15) {
            /** Use Paeth prediction as optimal */
            $predictor = 14;
        }

        /** PNG prediction */
        if ($predictor == 10 ||  /** None of prediction */
            $predictor == 11 ||  /** Sub prediction     */
            $predictor == 12 ||  /** Up prediction      */
            $predictor == 13 ||  /** Average prediction */
            $predictor == 14     /** Paeth prediction   */
            ) {
            $predictor -= 10;

            if($bitsPerComponent == 16) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception("PNG Prediction with bit depth greater than 8 not yet supported.");
            }

            $bitsPerSample  = $bitsPerComponent*$colors;
            $bytesPerSample = (int)(($bitsPerSample + 7)/8);           // (int)ceil(...) emulation
            $bytesPerRow    = (int)(($bitsPerSample*$columns + 7)/8);  // (int)ceil(...) emulation
            $rows           = strlen($data)/$bytesPerRow;
            $output         = '';
            $offset         = 0;

            if (!is_integer($rows)) {
                require_once 'Zend/Pdf/Exception.php';
                throw new Zend_Pdf_Exception('Wrong data length.');
            }

            switch ($predictor) {
                case 0: // None of prediction
                    for ($count = 0; $count < $rows; $count++) {
                        $output .= chr($predictor);
                        $output .= substr($data, $offset, $bytesPerRow);
                        $offset += $bytesPerRow;
                    }
                    break;

                case 1: // Sub prediction
                    for ($count = 0; $count < $rows; $count++) {
                        $output .= chr($predictor);

                        $lastSample = array_fill(0, $bytesPerSample, 0);
                        for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
                            $newByte = ord($data[$offset++]);
                            // Note. chr() automatically cuts input to 8 bit
                            $output .= chr($newByte - $lastSample[$count2 % $bytesPerSample]);
                            $lastSample[$count2 % $bytesPerSample] = $newByte;
                        }
                    }
                    break;

                case 2: // Up prediction
                    $lastRow = array_fill(0, $bytesPerRow, 0);
                    for ($count = 0; $count < $rows; $count++) {
                        $output .= chr($predictor);

                        for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
                            $newByte = ord($data[$offset++]);
                            // Note. chr() automatically cuts input to 8 bit
                            $output .= chr($newByte - $lastRow[$count2]);
                            $lastRow[$count2] = $newByte;
                        }
                    }
                    break;

                case 3: // Average prediction
                    $lastRow = array_fill(0, $bytesPerRow, 0);
                    for ($count = 0; $count < $rows; $count++) {
                        $output .= chr($predictor);

                        $lastSample = array_fill(0, $bytesPerSample, 0);
                        for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
                            $newByte = ord($data[$offset++]);
                            // Note. chr() automatically cuts input to 8 bit
                            $output .= chr($newByte - floor(( $lastSample[$count2 % $bytesPerSample] + $lastRow[$count2])/2));
                            $lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $newByte;
                        }
                    }
                    break;

                case 4: // Paeth prediction
                    $lastRow    = array_fill(0, $bytesPerRow, 0);
                    $currentRow = array();
                    for ($count = 0; $count < $rows; $count++) {
                        $output .= chr($predictor);

                        $lastSample = array_fill(0, $bytesPerSample, 0);
                        for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
                            $newByte = ord($data[$offset++]);
                            // Note. chr() automatically cuts input to 8 bit
                            $output .= chr($newByte - self::_paeth( $lastSample[$count2 % $bytesPerSample],
                                                                    $lastRow[$count2],
                                                                    ($count2 - $bytesPerSample  <  0)?
                                                                         0 : $lastRow[$count2 - $bytesPerSample] ));
                            $lastSample[$count2 % $bytesPerSample] = $currentRow[$count2] = $newByte;
                        }
                        $lastRow = $currentRow;
                    }
                    break;
            }
            return $output;
        }

        require_once 'Zend/Pdf/Exception.php';
        throw new Zend_Pdf_Exception('Unknown prediction algorithm - ' . $predictor . '.' );
    }

    /**
     * Convert stream data according to the filter params set after decoding.
     *
     * @param string $data
     * @param array $params
     * @return string
     */
    protected static function _applyDecodeParams($data, $params) {
        $predictor        = self::_getPredictorValue($params);
        $colors           = self::_getColorsValue($params);
        $bitsPerComponent = self::_getBitsPerComponentValue($params);
        $columns          = self::_getColumnsValue($params);

        /** None of prediction */
        if ($predictor == 1) {
            return $data;
        }

        /** TIFF Predictor 2 */
        if ($predictor == 2) {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Not implemented yet' );
        }

        /**
         * PNG prediction
         * Prediction code is duplicated on each row.
         * Thus all cases can be brought to one
         */
        if ($predictor == 10 ||  /** None of prediction */
            $predictor == 11 ||  /** Sub prediction     */
            $predictor == 12 ||  /** Up prediction      */
            $predictor == 13 ||  /** Average prediction */
            $predictor == 14 ||  /** Paeth prediction   */
            $predictor == 15     /** Optimal prediction */) {

            $bitsPerSample  = $bitsPerComponent*$colors;
            $bytesPerSample = ceil($bitsPerSample/8);
            $bytesPerRow    = ceil($bitsPerSample*$columns/8);
            $rows           = ceil(strlen($data)/($bytesPerRow + 1));
            $output         = '';
            $offset         = 0;

            $lastRow = array_fill(0, $bytesPerRow, 0);
            for ($count = 0; $count < $rows; $count++) {
                $lastSample = array_fill(0, $bytesPerSample, 0);
                switch (ord($data[$offset++])) {
                    case 0: // None of prediction
                        $output .= substr($data, $offset, $bytesPerRow);
                        for ($count2 = 0; $count2 < $bytesPerRow  &&  $offset < strlen($data); $count2++) {
                            $lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = ord($data[$offset++]);
                        }
                        break;

                    case 1: // Sub prediction
                        for ($count2 = 0; $count2 < $bytesPerRow  &&  $offset < strlen($data); $count2++) {
                            $decodedByte = (ord($data[$offset++]) + $lastSample[$count2 % $bytesPerSample]) & 0xFF;
                            $lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
                            $output .= chr($decodedByte);
                        }
                        break;

                    case 2: // Up prediction
                        for ($count2 = 0; $count2 < $bytesPerRow  &&  $offset < strlen($data); $count2++) {
                            $decodedByte = (ord($data[$offset++]) + $lastRow[$count2]) & 0xFF;
                            $lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
                            $output .= chr($decodedByte);
                        }
                        break;

                    case 3: // Average prediction
                        for ($count2 = 0; $count2 < $bytesPerRow  &&  $offset < strlen($data); $count2++) {
                            $decodedByte = (ord($data[$offset++]) +
                                            floor(( $lastSample[$count2 % $bytesPerSample] + $lastRow[$count2])/2)
                                           ) & 0xFF;
                            $lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
                            $output .= chr($decodedByte);
                        }
                        break;

                    case 4: // Paeth prediction
                        $currentRow = array();
                        for ($count2 = 0; $count2 < $bytesPerRow  &&  $offset < strlen($data); $count2++) {
                            $decodedByte = (ord($data[$offset++]) +
                                            self::_paeth($lastSample[$count2 % $bytesPerSample],
                                                         $lastRow[$count2],
                                                         ($count2 - $bytesPerSample  <  0)?
                                                              0 : $lastRow[$count2 - $bytesPerSample])
                                           ) & 0xFF;
                            $lastSample[$count2 % $bytesPerSample] = $currentRow[$count2] = $decodedByte;
                            $output .= chr($decodedByte);
                        }
                        $lastRow = $currentRow;
                        break;

                    default:
                        require_once 'Zend/Pdf/Exception.php';
                        throw new Zend_Pdf_Exception('Unknown prediction tag.');
                }
            }
            return $output;
        }

        require_once 'Zend/Pdf/Exception.php';
        throw new Zend_Pdf_Exception('Unknown prediction algorithm - ' . $predictor . '.' );
    }
}


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: AsciiHex.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Filter_Interface */
require_once 'Zend/Pdf/Filter/Interface.php';

/**
 * AsciiHex stream filter
 *
 * @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_Filter_AsciiHex implements Zend_Pdf_Filter_Interface
{
    /**
     * Encode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function encode($data, $params = null)
    {
        return bin2hex($data) . '>';
    }

    /**
     * Decode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function decode($data, $params = null)
    {
        $output  = '';
        $oddCode = true;
        $commentMode = false;

        for ($count = 0; $count < strlen($data)  &&  $data[$count] != '>'; $count++) {
            $charCode = ord($data[$count]);

            if ($commentMode) {
                if ($charCode == 0x0A  || $charCode == 0x0D ) {
                    $commentMode = false;
                }

                continue;
            }

            switch ($charCode) {
                //Skip white space
                case 0x00: // null character
                    // fall through to next case
                case 0x09: // Tab
                    // fall through to next case
                case 0x0A: // Line feed
                    // fall through to next case
                case 0x0C: // Form Feed
                    // fall through to next case
                case 0x0D: // Carriage return
                    // fall through to next case
                case 0x20: // Space
                    // Do nothing
                    break;

                case 0x25: // '%'
                    // Switch to comment mode
                    $commentMode = true;
                    break;

                default:
                    if ($charCode >= 0x30 /*'0'*/ && $charCode <= 0x39 /*'9'*/) {
                        $code = $charCode - 0x30;
                    } else if ($charCode >= 0x41 /*'A'*/ && $charCode <= 0x46 /*'F'*/) {
                        $code = $charCode - 0x37/*0x41 - 0x0A*/;
                    } else if ($charCode >= 0x61 /*'a'*/ && $charCode <= 0x66 /*'f'*/) {
                        $code = $charCode - 0x57/*0x61 - 0x0A*/;
                    } else {
                        require_once 'Zend/Pdf/Exception.php';
                        throw new Zend_Pdf_Exception('Wrong character in a encoded stream');
                    }

                    if ($oddCode) {
                        // Odd pass. Store hex digit for next pass
                        // Scope of $hexCodeHigh variable is whole function
                        $hexCodeHigh = $code;
                    } else {
                        // Even pass.
                        // Add decoded character to the output
                        // ($hexCodeHigh is stored in previous pass)
                        $output .= chr($hexCodeHigh*16 + $code);
                    }
                    $oddCode = !$oddCode;

                    break;
            }
        }

        /* Check that stream is terminated by End Of Data marker */
        if ($data[$count] != '>') {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Wrong encoded stream End Of Data marker.');
        }

        /* Last '0' character is omitted */
        if (!$oddCode) {
            $output .= chr($hexCodeHigh*16);
        }

        return $output;
    }
}


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: Interface.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * PDF stream filter
 *
 * @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
 */
interface Zend_Pdf_Filter_Interface
{
    /**
     * Encode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function encode($data, $params = null);

    /**
     * Decode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function decode($data, $params = null);
}


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: Ascii85.php 23775 2011-03-01 17:25:24Z ralph $
 */

/** Zend_Pdf_Filter_Interface */
require_once 'Zend/Pdf/Filter/Interface.php';

/**
 * ASCII85 stream filter
 *
 * @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_Filter_Ascii85 implements Zend_Pdf_Filter_Interface
{
    /**
     * Encode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function encode($data, $params = null)
    {
        $output = '';
        $dataLength = strlen($data);

        for ($i = 0; $i < $dataLength; $i += 4) {
            //convert the 4 characters into a 32-bit number
            $chunk = substr($data, $i, 4);

            if (strlen($chunk) < 4) {
                //partial chunk
                break;
            }

            $b = unpack("N", $chunk);
            $b = $b[1];

            //special char for all 4 bytes = 0
            if ($b == 0) {
                $output .= 'z';
                continue;
            }

            //encode into 5 bytes
            for ($j = 4; $j >= 0; $j--) {
                $foo = (int) (($b / pow(85,$j)) + 33);
                $b %= pow(85,$j);
                $output .= chr($foo);
            }
        }

        //encode partial chunk
        if ($i < $dataLength) {
            $n = $dataLength - $i;
            $chunk = substr($data, -$n);

            //0 pad the rest
            for ($j = $n;$j < 4;$j++) {
                $chunk .= "\0";
            }

            $b = unpack("N", $chunk);
            $b = $b[1];

            //encode just $n + 1
            for ($j = 4; $j >= (4 - $n); $j--) {
                $foo = (int) (($b / pow(85,$j)) + 33);
                $b %= pow(85,$j);
                $output .= chr($foo);
            }
        }

        //EOD
        $output .= '~>';

        //make sure lines are split
        $output = chunk_split($output, 76, "\n");

        //get rid of new line at the end
        $output = substr($output, 0, -1);
        return $output;
    }

    /**
     * Decode data
     *
     * @param string $data
     * @param array $params
     * @return string
     * @throws Zend_Pdf_Exception
     */
    public static function decode($data, $params = null)
    {
        $output = '';

        //get rid of the whitespaces
        $whiteSpace = array("\x00", "\x09", "\x0A", "\x0C", "\x0D", "\x20");
        $data = str_replace($whiteSpace, '', $data);

        if (substr($data, -2) != '~>') {
            require_once 'Zend/Pdf/Exception.php';
            throw new Zend_Pdf_Exception('Invalid EOF marker');
            return '';
        }

        $data = substr($data, 0, (strlen($data) - 2));
        $dataLength = strlen($data);

        for ($i = 0; $i < $dataLength; $i += 5) {
            $b = 0;

            if (substr($data, $i, 1) == "z") {
                $i -= 4;
                $output .= pack("N", 0);
                continue;
            }

            $c = substr($data, $i, 5);

            if(strlen($c) < 5) {
                //partial chunk
                break;
            }

            $c = unpack('C5', $c);
            $value = 0;

            for ($j = 1; $j <= 5; $j++) {
                $value += (($c[$j] - 33) * pow(85, (5 - $j)));
            }

            $output .= pack("N", $value);
        }

        //decode partial
        if ($i < $dataLength) {
            $value = 0;
            $chunk = substr($data, $i);
            $partialLength = strlen($chunk);

            //pad the rest of the chunk with u's
            //until the lenght of the chunk is 5
            for ($j = 0; $j < (5 - $partialLength); $j++) {
                $chunk .= 'u';
            }

            $c = unpack('C5', $chunk);

            for ($j = 1; $j <= 5; $j++) {
                $value += (($c[$j] - 33) * pow(85, (5 - $j)));
            }

            $foo = pack("N", $value);
            $output .= substr($foo, 0, ($partialLength - 1));
        }

        return $output;
    }
}