PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/frapi/library/Zend/Pdf/ElementFactory.php

https://github.com/Martin1982/IBMessagingWorkshopServer
PHP | 436 lines | 171 code | 60 blank | 205 comment | 20 complexity | 3e68707d724d192541773c7fb2aede06 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Pdf
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id: ElementFactory.php 20096 2010-01-06 02:05:09Z bkarwin $
  20. */
  21. /** Zend_Pdf_ElementFactory_Interface */
  22. // require_once 'Zend/Pdf/ElementFactory/Interface.php';
  23. /**
  24. * PDF element factory.
  25. * Responsibility is to log PDF changes
  26. *
  27. * @package Zend_Pdf
  28. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Pdf_ElementFactory implements Zend_Pdf_ElementFactory_Interface
  32. {
  33. /**
  34. * List of the modified objects.
  35. * Also contains new and removed objects
  36. *
  37. * Array: ojbectNumber => Zend_Pdf_Element_Object
  38. *
  39. * @var array
  40. */
  41. private $_modifiedObjects = array();
  42. /**
  43. * List of the removed objects
  44. *
  45. * Array: ojbectNumber => Zend_Pdf_Element_Object
  46. *
  47. * @var SplObjectStorage
  48. */
  49. private $_removedObjects;
  50. /**
  51. * List of registered objects.
  52. * Used for resources clean up when factory is destroyed.
  53. *
  54. * Array of Zend_Pdf_Element objects
  55. *
  56. * @var array
  57. */
  58. private $_registeredObjects = array();
  59. /**
  60. * PDF object counter.
  61. * Actually it's an object number for new PDF object
  62. *
  63. * @var integer
  64. */
  65. private $_objectCount;
  66. /**
  67. * List of the attached object factories.
  68. * Array of Zend_Pdf_ElementFactory_Interface objects
  69. *
  70. * @var array
  71. */
  72. private $_attachedFactories = array();
  73. /**
  74. * Factory internal id
  75. *
  76. * @var integer
  77. */
  78. private $_factoryId;
  79. /**
  80. * Identity, used for factory id generation
  81. *
  82. * @var integer
  83. */
  84. private static $_identity = 0;
  85. /**
  86. * Internal cache to save calculated shifts
  87. *
  88. * @var array
  89. */
  90. private $_shiftCalculationCache = array();
  91. /**
  92. * Object constructor
  93. *
  94. * @param integer $objCount
  95. */
  96. public function __construct($objCount)
  97. {
  98. $this->_objectCount = (int)$objCount;
  99. $this->_factoryId = self::$_identity++;
  100. $this->_removedObjects = new SplObjectStorage();
  101. }
  102. /**
  103. * Factory generator
  104. *
  105. * @param integer $objCount
  106. * @return Zend_Pdf_ElementFactory_Interface
  107. */
  108. static public function createFactory($objCount)
  109. {
  110. // require_once 'Zend/Pdf/ElementFactory/Proxy.php';
  111. return new Zend_Pdf_ElementFactory_Proxy(new Zend_Pdf_ElementFactory($objCount));
  112. }
  113. /**
  114. * Close factory and clean-up resources
  115. *
  116. * @internal
  117. */
  118. public function close()
  119. {
  120. $this->_modifiedObjects = null;
  121. $this->_removedObjects = null;
  122. $this->_attachedFactories = null;
  123. foreach ($this->_registeredObjects as $obj) {
  124. $obj->cleanUp();
  125. }
  126. $this->_registeredObjects = null;
  127. }
  128. /**
  129. * Get source factory object
  130. *
  131. * @return Zend_Pdf_ElementFactory
  132. */
  133. public function resolve()
  134. {
  135. return $this;
  136. }
  137. /**
  138. * Get factory ID
  139. *
  140. * @return integer
  141. */
  142. public function getId()
  143. {
  144. return $this->_factoryId;
  145. }
  146. /**
  147. * Set object counter
  148. *
  149. * @param integer $objCount
  150. */
  151. public function setObjectCount($objCount)
  152. {
  153. $this->_objectCount = (int)$objCount;
  154. }
  155. /**
  156. * Get object counter
  157. *
  158. * @return integer
  159. */
  160. public function getObjectCount()
  161. {
  162. $count = $this->_objectCount;
  163. foreach ($this->_attachedFactories as $attached) {
  164. $count += $attached->getObjectCount() - 1; // -1 as "0" object is a special case and shared between factories
  165. }
  166. return $count;
  167. }
  168. /**
  169. * Attach factory to the current;
  170. *
  171. * @param Zend_Pdf_ElementFactory_Interface $factory
  172. */
  173. public function attach(Zend_Pdf_ElementFactory_Interface $factory)
  174. {
  175. if ( $factory === $this || isset($this->_attachedFactories[$factory->getId()])) {
  176. /**
  177. * Don't attach factory twice.
  178. * We do not check recusively because of nature of attach operation
  179. * (Pages are always attached to the Documents, Fonts are always attached
  180. * to the pages even if pages already use Document level object factory and so on)
  181. */
  182. return;
  183. }
  184. $this->_attachedFactories[$factory->getId()] = $factory;
  185. }
  186. /**
  187. * Calculate object enumeration shift.
  188. *
  189. * @param Zend_Pdf_ElementFactory_Interface $factory
  190. * @return integer
  191. */
  192. public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory)
  193. {
  194. if ($factory === $this) {
  195. return 0;
  196. }
  197. if (isset($this->_shiftCalculationCache[$factory->_factoryId])) {
  198. return $this->_shiftCalculationCache[$factory->_factoryId];
  199. }
  200. $shift = $this->_objectCount - 1;
  201. foreach ($this->_attachedFactories as $subFactory) {
  202. $subFactoryShift = $subFactory->calculateShift($factory);
  203. if ($subFactoryShift != -1) {
  204. // context found
  205. $this->_shiftCalculationCache[$factory->_factoryId] = $shift + $subFactoryShift;
  206. return $shift + $subFactoryShift;
  207. } else {
  208. $shift += $subFactory->getObjectCount()-1;
  209. }
  210. }
  211. $this->_shiftCalculationCache[$factory->_factoryId] = -1;
  212. return -1;
  213. }
  214. /**
  215. * Clean enumeration shift cache.
  216. * Has to be used after PDF render operation to let followed updates be correct.
  217. */
  218. public function cleanEnumerationShiftCache()
  219. {
  220. $this->_shiftCalculationCache = array();
  221. foreach ($this->_attachedFactories as $attached) {
  222. $attached->cleanEnumerationShiftCache();
  223. }
  224. }
  225. /**
  226. * Retrive object enumeration shift.
  227. *
  228. * @param Zend_Pdf_ElementFactory_Interface $factory
  229. * @return integer
  230. * @throws Zend_Pdf_Exception
  231. */
  232. public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory)
  233. {
  234. if (($shift = $this->calculateShift($factory)) == -1) {
  235. // require_once 'Zend/Pdf/Exception.php';
  236. throw new Zend_Pdf_Exception('Wrong object context');
  237. }
  238. return $shift;
  239. }
  240. /**
  241. * Mark object as modified in context of current factory.
  242. *
  243. * @param Zend_Pdf_Element_Object $obj
  244. * @throws Zend_Pdf_Exception
  245. */
  246. public function markAsModified(Zend_Pdf_Element_Object $obj)
  247. {
  248. if ($obj->getFactory() !== $this) {
  249. // require_once 'Zend/Pdf/Exception.php';
  250. throw new Zend_Pdf_Exception('Object is not generated by this factory');
  251. }
  252. $this->_modifiedObjects[$obj->getObjNum()] = $obj;
  253. }
  254. /**
  255. * Remove object in context of current factory.
  256. *
  257. * @param Zend_Pdf_Element_Object $obj
  258. * @throws Zend_Pdf_Exception
  259. */
  260. public function remove(Zend_Pdf_Element_Object $obj)
  261. {
  262. if (!$obj->compareFactory($this)) {
  263. // require_once 'Zend/Pdf/Exception.php';
  264. throw new Zend_Pdf_Exception('Object is not generated by this factory');
  265. }
  266. $this->_modifiedObjects[$obj->getObjNum()] = $obj;
  267. $this->_removedObjects->attach($obj);
  268. }
  269. /**
  270. * Generate new Zend_Pdf_Element_Object
  271. *
  272. * @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
  273. *
  274. * @param Zend_Pdf_Element $objectValue
  275. * @return Zend_Pdf_Element_Object
  276. */
  277. public function newObject(Zend_Pdf_Element $objectValue)
  278. {
  279. // require_once 'Zend/Pdf/Element/Object.php';
  280. $obj = new Zend_Pdf_Element_Object($objectValue, $this->_objectCount++, 0, $this);
  281. $this->_modifiedObjects[$obj->getObjNum()] = $obj;
  282. return $obj;
  283. }
  284. /**
  285. * Generate new Zend_Pdf_Element_Object_Stream
  286. *
  287. * @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
  288. *
  289. * @param mixed $objectValue
  290. * @return Zend_Pdf_Element_Object_Stream
  291. */
  292. public function newStreamObject($streamValue)
  293. {
  294. // require_once 'Zend/Pdf/Element/Object/Stream.php';
  295. $obj = new Zend_Pdf_Element_Object_Stream($streamValue, $this->_objectCount++, 0, $this);
  296. $this->_modifiedObjects[$obj->getObjNum()] = $obj;
  297. return $obj;
  298. }
  299. /**
  300. * Enumerate modified objects.
  301. * Returns array of Zend_Pdf_UpdateInfoContainer
  302. *
  303. * @param Zend_Pdf_ElementFactory_Interface $rootFactory
  304. * @return array
  305. */
  306. public function listModifiedObjects($rootFactory = null)
  307. {
  308. if ($rootFactory == null) {
  309. $rootFactory = $this;
  310. $shift = 0;
  311. } else {
  312. $shift = $rootFactory->getEnumerationShift($this);
  313. }
  314. ksort($this->_modifiedObjects);
  315. $result = array();
  316. // require_once 'Zend/Pdf/UpdateInfoContainer.php';
  317. foreach ($this->_modifiedObjects as $objNum => $obj) {
  318. if ($this->_removedObjects->contains($obj)) {
  319. $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
  320. $obj->getGenNum()+1,
  321. true);
  322. } else {
  323. $result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
  324. $obj->getGenNum(),
  325. false,
  326. $obj->dump($rootFactory));
  327. }
  328. }
  329. foreach ($this->_attachedFactories as $factory) {
  330. $result += $factory->listModifiedObjects($rootFactory);
  331. }
  332. return $result;
  333. }
  334. /**
  335. * Register object in the factory
  336. *
  337. * It's used to clear "parent object" referencies when factory is closed and clean up resources
  338. *
  339. * @param string $refString
  340. * @param Zend_Pdf_Element_Object $obj
  341. */
  342. public function registerObject(Zend_Pdf_Element_Object $obj, $refString)
  343. {
  344. $this->_registeredObjects[$refString] = $obj;
  345. }
  346. /**
  347. * Fetch object specified by reference
  348. *
  349. * @param string $refString
  350. * @return Zend_Pdf_Element_Object|null
  351. */
  352. public function fetchObject($refString)
  353. {
  354. if (!isset($this->_registeredObjects[$refString])) {
  355. return null;
  356. }
  357. return $this->_registeredObjects[$refString];
  358. }
  359. /**
  360. * Check if PDF file was modified
  361. *
  362. * @return boolean
  363. */
  364. public function isModified()
  365. {
  366. if (count($this->_modifiedObjects) != 0) {
  367. return true;
  368. }
  369. foreach ($this->_attachedFactories as $subFactory) {
  370. if ($subFactory->isModified()) {
  371. return true;
  372. }
  373. }
  374. return false;
  375. }
  376. }