You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<?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-2015 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id$ */
/** Zend_Pdf_ElementFactory_Interface */ // require_once 'Zend/Pdf/ElementFactory/Interface.php';
/** * PDF element factory. * Responsibility is to log PDF changes * * @package Zend_Pdf * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Pdf_ElementFactory implements Zend_Pdf_ElementFactory_Interface { /** * List of the modified objects. * Also contains new and removed objects * * Array: ojbectNumber => Zend_Pdf_Element_Object * * @var array */ private $_modifiedObjects = array();
/** * List of the removed objects * * Array: ojbectNumber => Zend_Pdf_Element_Object * * @var SplObjectStorage */ private $_removedObjects;
/** * List of registered objects. * Used for resources clean up when factory is destroyed. * * Array of Zend_Pdf_Element objects * * @var array */ private $_registeredObjects = array();
/** * PDF object counter. * Actually it's an object number for new PDF object * * @var integer */ private $_objectCount;
/** * List of the attached object factories. * Array of Zend_Pdf_ElementFactory_Interface objects * * @var array */ private $_attachedFactories = array();
/** * Factory internal id * * @var integer */ private $_factoryId;
/** * Identity, used for factory id generation * * @var integer */ private static $_identity = 0;
/** * Internal cache to save calculated shifts * * @var array */ private $_shiftCalculationCache = array();
/** * Object constructor * * @param integer $objCount */ public function __construct($objCount) { $this->_objectCount = (int)$objCount; $this->_factoryId = self::$_identity++; $this->_removedObjects = new SplObjectStorage(); }
/** * Get factory * * @return Zend_Pdf_ElementFactory_Interface */ public function getFactory() { return $this; }
/** * Factory generator * * @param integer $objCount * @return Zend_Pdf_ElementFactory_Interface */ static public function createFactory($objCount) { // require_once 'Zend/Pdf/ElementFactory/Proxy.php';
return new Zend_Pdf_ElementFactory_Proxy(new Zend_Pdf_ElementFactory($objCount)); }
/** * Close factory and clean-up resources * * @internal */ public function close() { $this->_modifiedObjects = null; $this->_removedObjects = null; $this->_attachedFactories = null;
foreach ($this->_registeredObjects as $obj) { $obj->cleanUp(); } $this->_registeredObjects = null; }
/** * Get source factory object * * @return Zend_Pdf_ElementFactory */ public function resolve() { return $this; }
/** * Get factory ID * * @return integer */ public function getId() { return $this->_factoryId; }
/** * Set object counter * * @param integer $objCount */ public function setObjectCount($objCount) { $this->_objectCount = (int)$objCount; }
/** * Get object counter * * @return integer */ public function getObjectCount() { $count = $this->_objectCount;
foreach ($this->_attachedFactories as $attached) { $count += $attached->getObjectCount() - 1; // -1 as "0" object is a special case and shared between factories
}
return $count; }
/** * Attach factory to the current; * * @param Zend_Pdf_ElementFactory_Interface $factory */ public function attach(Zend_Pdf_ElementFactory_Interface $factory) { if ( $factory === $this || isset($this->_attachedFactories[$factory->getId()])) { /** * Don't attach factory twice. * We do not check recusively because of nature of attach operation * (Pages are always attached to the Documents, Fonts are always attached * to the pages even if pages already use Document level object factory and so on) */ return; }
$this->_attachedFactories[$factory->getId()] = $factory; }
/** * Calculate object enumeration shift. * * @param Zend_Pdf_ElementFactory_Interface $factory * @return integer */ public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory) { if ($factory === $this) { return 0; }
if (isset($this->_shiftCalculationCache[$factory->_factoryId])) { return $this->_shiftCalculationCache[$factory->_factoryId]; }
$shift = $this->_objectCount - 1;
foreach ($this->_attachedFactories as $subFactory) { $subFactoryShift = $subFactory->calculateShift($factory);
if ($subFactoryShift != -1) { // context found
$this->_shiftCalculationCache[$factory->_factoryId] = $shift + $subFactoryShift; return $shift + $subFactoryShift; } else { $shift += $subFactory->getObjectCount()-1; } }
$this->_shiftCalculationCache[$factory->_factoryId] = -1; return -1; }
/** * Clean enumeration shift cache. * Has to be used after PDF render operation to let followed updates be correct. */ public function cleanEnumerationShiftCache() { $this->_shiftCalculationCache = array();
foreach ($this->_attachedFactories as $attached) { $attached->cleanEnumerationShiftCache(); } }
/** * Retrive object enumeration shift. * * @param Zend_Pdf_ElementFactory_Interface $factory * @return integer * @throws Zend_Pdf_Exception */ public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory) { if (($shift = $this->calculateShift($factory)) == -1) { // require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong object context'); }
return $shift; }
/** * Mark object as modified in context of current factory. * * @param Zend_Pdf_Element_Object $obj * @throws Zend_Pdf_Exception */ public function markAsModified(Zend_Pdf_Element_Object $obj) { if ($obj->getFactory() !== $this) { // require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not generated by this factory'); }
$this->_modifiedObjects[$obj->getObjNum()] = $obj; }
/** * Remove object in context of current factory. * * @param Zend_Pdf_Element_Object $obj * @throws Zend_Pdf_Exception */ public function remove(Zend_Pdf_Element_Object $obj) { if (!$obj->compareFactory($this)) { // require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not generated by this factory'); }
$this->_modifiedObjects[$obj->getObjNum()] = $obj; $this->_removedObjects->attach($obj); }
/** * Generate new Zend_Pdf_Element_Object * * @todo Reusage of the freed object. It's not a support of new feature, but only improvement. * * @param Zend_Pdf_Element $objectValue * @return Zend_Pdf_Element_Object */ public function newObject(Zend_Pdf_Element $objectValue) { // require_once 'Zend/Pdf/Element/Object.php';
$obj = new Zend_Pdf_Element_Object($objectValue, $this->_objectCount++, 0, $this); $this->_modifiedObjects[$obj->getObjNum()] = $obj; return $obj; }
/** * Generate new Zend_Pdf_Element_Object_Stream * * @todo Reusage of the freed object. It's not a support of new feature, but only improvement. * * @param mixed $objectValue * @return Zend_Pdf_Element_Object_Stream */ public function newStreamObject($streamValue) { // require_once 'Zend/Pdf/Element/Object/Stream.php';
$obj = new Zend_Pdf_Element_Object_Stream($streamValue, $this->_objectCount++, 0, $this); $this->_modifiedObjects[$obj->getObjNum()] = $obj; return $obj; }
/** * Enumerate modified objects. * Returns array of Zend_Pdf_UpdateInfoContainer * * @param Zend_Pdf_ElementFactory_Interface $rootFactory * @return array */ public function listModifiedObjects($rootFactory = null) { if ($rootFactory == null) { $rootFactory = $this; $shift = 0; } else { $shift = $rootFactory->getEnumerationShift($this); }
ksort($this->_modifiedObjects);
$result = array(); // require_once 'Zend/Pdf/UpdateInfoContainer.php';
foreach ($this->_modifiedObjects as $objNum => $obj) { if ($this->_removedObjects->contains($obj)) { $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift, $obj->getGenNum()+1, true); } else { $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift, $obj->getGenNum(), false, $obj->dump($rootFactory)); } }
foreach ($this->_attachedFactories as $factory) { $result += $factory->listModifiedObjects($rootFactory); }
return $result; }
/** * Register object in the factory * * It's used to clear "parent object" referencies when factory is closed and clean up resources * * @param string $refString * @param Zend_Pdf_Element_Object $obj */ public function registerObject(Zend_Pdf_Element_Object $obj, $refString) { $this->_registeredObjects[$refString] = $obj; }
/** * Fetch object specified by reference * * @param string $refString * @return Zend_Pdf_Element_Object|null */ public function fetchObject($refString) { if (!isset($this->_registeredObjects[$refString])) { return null; } return $this->_registeredObjects[$refString]; }
/** * Check if PDF file was modified * * @return boolean */ public function isModified() { if (count($this->_modifiedObjects) != 0) { return true; }
foreach ($this->_attachedFactories as $subFactory) { if ($subFactory->isModified()) { return true; } }
return false; } }
|