--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/lib/Zend/Pdf/Page.php Fri Mar 11 15:05:35 2011 +0100
@@ -0,0 +1,773 @@
+<?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-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Page.php 22909 2010-08-27 19:57:48Z alexander $
+ */
+
+/** Internally used classes */
+require_once 'Zend/Pdf/Element.php';
+require_once 'Zend/Pdf/Element/Array.php';
+require_once 'Zend/Pdf/Element/String/Binary.php';
+require_once 'Zend/Pdf/Element/Boolean.php';
+require_once 'Zend/Pdf/Element/Dictionary.php';
+require_once 'Zend/Pdf/Element/Name.php';
+require_once 'Zend/Pdf/Element/Null.php';
+require_once 'Zend/Pdf/Element/Numeric.php';
+require_once 'Zend/Pdf/Element/String.php';
+require_once 'Zend/Pdf/Resource/Unified.php';
+
+require_once 'Zend/Pdf/Canvas/Abstract.php';
+
+
+/**
+ * PDF Page
+ *
+ * @package Zend_Pdf
+ * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Pdf_Page extends Zend_Pdf_Canvas_Abstract
+{
+ /**** Class Constants ****/
+
+
+ /* Page Sizes */
+
+ /**
+ * Size representing an A4 page in portrait (tall) orientation.
+ */
+ const SIZE_A4 = '595:842:';
+
+ /**
+ * Size representing an A4 page in landscape (wide) orientation.
+ */
+ const SIZE_A4_LANDSCAPE = '842:595:';
+
+ /**
+ * Size representing a US Letter page in portrait (tall) orientation.
+ */
+ const SIZE_LETTER = '612:792:';
+
+ /**
+ * Size representing a US Letter page in landscape (wide) orientation.
+ */
+ const SIZE_LETTER_LANDSCAPE = '792:612:';
+
+
+ /* Shape Drawing */
+
+ /**
+ * Stroke the path only. Do not fill.
+ */
+ const SHAPE_DRAW_STROKE = 0;
+
+ /**
+ * Fill the path only. Do not stroke.
+ */
+ const SHAPE_DRAW_FILL = 1;
+
+ /**
+ * Fill and stroke the path.
+ */
+ const SHAPE_DRAW_FILL_AND_STROKE = 2;
+
+
+ /* Shape Filling Methods */
+
+ /**
+ * Fill the path using the non-zero winding rule.
+ */
+ const FILL_METHOD_NON_ZERO_WINDING = 0;
+
+ /**
+ * Fill the path using the even-odd rule.
+ */
+ const FILL_METHOD_EVEN_ODD = 1;
+
+
+ /* Line Dash Types */
+
+ /**
+ * Solid line dash.
+ */
+ const LINE_DASHING_SOLID = 0;
+
+
+
+ /**
+ * Page dictionary (refers to an inderect Zend_Pdf_Element_Dictionary object).
+ *
+ * @var Zend_Pdf_Element_Reference|Zend_Pdf_Element_Object
+ */
+ protected $_dictionary;
+
+ /**
+ * PDF objects factory.
+ *
+ * @var Zend_Pdf_ElementFactory_Interface
+ */
+ protected $_objFactory = null;
+
+ /**
+ * Flag which signals, that page is created separately from any PDF document or
+ * attached to anyone.
+ *
+ * @var boolean
+ */
+ protected $_attached;
+
+ /**
+ * Safe Graphics State semafore
+ *
+ * If it's false, than we can't be sure Graphics State is restored withing
+ * context of previous contents stream (ex. drawing coordinate system may be rotated).
+ * We should encompass existing content with save/restore GS operators
+ *
+ * @var boolean
+ */
+ protected $_safeGS;
+
+ /**
+ * Object constructor.
+ * Constructor signatures:
+ *
+ * 1. Load PDF page from a parsed PDF file.
+ * Object factory is created by PDF parser.
+ * ---------------------------------------------------------
+ * new Zend_Pdf_Page(Zend_Pdf_Element_Dictionary $pageDict,
+ * Zend_Pdf_ElementFactory_Interface $factory);
+ * ---------------------------------------------------------
+ *
+ * 2. Make a copy of the PDF page.
+ * New page is created in the same context as source page. Object factory is shared.
+ * Thus it will be attached to the document, but need to be placed into Zend_Pdf::$pages array
+ * to be included into output.
+ * ---------------------------------------------------------
+ * new Zend_Pdf_Page(Zend_Pdf_Page $page);
+ * ---------------------------------------------------------
+ *
+ * 3. Create new page with a specified pagesize.
+ * If $factory is null then it will be created and page must be attached to the document to be
+ * included into output.
+ * ---------------------------------------------------------
+ * new Zend_Pdf_Page(string $pagesize, Zend_Pdf_ElementFactory_Interface $factory = null);
+ * ---------------------------------------------------------
+ *
+ * 4. Create new page with a specified pagesize (in default user space units).
+ * If $factory is null then it will be created and page must be attached to the document to be
+ * included into output.
+ * ---------------------------------------------------------
+ * new Zend_Pdf_Page(numeric $width, numeric $height, Zend_Pdf_ElementFactory_Interface $factory = null);
+ * ---------------------------------------------------------
+ *
+ *
+ * @param mixed $param1
+ * @param mixed $param2
+ * @param mixed $param3
+ * @throws Zend_Pdf_Exception
+ */
+ public function __construct($param1, $param2 = null, $param3 = null)
+ {
+ if (($param1 instanceof Zend_Pdf_Element_Reference ||
+ $param1 instanceof Zend_Pdf_Element_Object
+ ) &&
+ $param2 instanceof Zend_Pdf_ElementFactory_Interface &&
+ $param3 === null
+ ) {
+ switch ($param1->getType()) {
+ case Zend_Pdf_Element::TYPE_DICTIONARY:
+ $this->_dictionary = $param1;
+ $this->_objFactory = $param2;
+ $this->_attached = true;
+ $this->_safeGS = false;
+ return;
+ break;
+
+ case Zend_Pdf_Element::TYPE_NULL:
+ $this->_objFactory = $param2;
+ $pageWidth = $pageHeight = 0;
+ break;
+
+ default:
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Unrecognized object type.');
+ break;
+
+ }
+ } else if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) {
+ // Duplicate existing page.
+ // Let already existing content and resources to be shared between pages
+ // We don't give existing content modification functionality, so we don't need "deep copy"
+ $this->_objFactory = $param1->_objFactory;
+ $this->_attached = &$param1->_attached;
+ $this->_safeGS = false;
+
+ $this->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
+
+ foreach ($param1->_dictionary->getKeys() as $key) {
+ if ($key == 'Contents') {
+ // Clone Contents property
+
+ $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
+
+ if ($param1->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
+ // Prepare array of content streams and add existing stream
+ $this->_dictionary->Contents->items[] = $param1->_dictionary->Contents;
+ } else {
+ // Clone array of the content streams
+ foreach ($param1->_dictionary->Contents->items as $srcContentStream) {
+ $this->_dictionary->Contents->items[] = $srcContentStream;
+ }
+ }
+ } else {
+ $this->_dictionary->$key = $param1->_dictionary->$key;
+ }
+ }
+
+ return;
+ } else if (is_string($param1) &&
+ ($param2 === null || $param2 instanceof Zend_Pdf_ElementFactory_Interface) &&
+ $param3 === null) {
+ if ($param2 !== null) {
+ $this->_objFactory = $param2;
+ } else {
+ require_once 'Zend/Pdf/ElementFactory.php';
+ $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
+ }
+ $this->_attached = false;
+ $this->_safeGS = true; /** New page created. That's users App responsibility to track GS changes */
+
+ switch (strtolower($param1)) {
+ case 'a4':
+ $param1 = Zend_Pdf_Page::SIZE_A4;
+ break;
+ case 'a4-landscape':
+ $param1 = Zend_Pdf_Page::SIZE_A4_LANDSCAPE;
+ break;
+ case 'letter':
+ $param1 = Zend_Pdf_Page::SIZE_LETTER;
+ break;
+ case 'letter-landscape':
+ $param1 = Zend_Pdf_Page::SIZE_LETTER_LANDSCAPE;
+ break;
+ default:
+ // should be in "x:y" or "x:y:" form
+ }
+
+ $pageDim = explode(':', $param1);
+ if(count($pageDim) == 2 || count($pageDim) == 3) {
+ $pageWidth = $pageDim[0];
+ $pageHeight = $pageDim[1];
+ } else {
+ /**
+ * @todo support of user defined pagesize notations, like:
+ * "210x297mm", "595x842", "8.5x11in", "612x792"
+ */
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Wrong pagesize notation.');
+ }
+ /**
+ * @todo support of pagesize recalculation to "default user space units"
+ */
+
+ } else if (is_numeric($param1) && is_numeric($param2) &&
+ ($param3 === null || $param3 instanceof Zend_Pdf_ElementFactory_Interface)) {
+ if ($param3 !== null) {
+ $this->_objFactory = $param3;
+ } else {
+ require_once 'Zend/Pdf/ElementFactory.php';
+ $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
+ }
+
+ $this->_attached = false;
+ $this->_safeGS = true; /** New page created. That's users App responsibility to track GS changes */
+ $pageWidth = $param1;
+ $pageHeight = $param2;
+
+ } else {
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Unrecognized method signature, wrong number of arguments or wrong argument types.');
+ }
+
+ $this->_dictionary = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
+ $this->_dictionary->Type = new Zend_Pdf_Element_Name('Page');
+ require_once 'Zend/Pdf.php';
+ $this->_dictionary->LastModified = new Zend_Pdf_Element_String(Zend_Pdf::pdfDate());
+ $this->_dictionary->Resources = new Zend_Pdf_Element_Dictionary();
+ $this->_dictionary->MediaBox = new Zend_Pdf_Element_Array();
+ $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
+ $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric(0);
+ $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageWidth);
+ $this->_dictionary->MediaBox->items[] = new Zend_Pdf_Element_Numeric($pageHeight);
+ $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
+ }
+
+
+ /**
+ * Attach resource to the canvas
+ *
+ * Method returns a name of the resource which can be used
+ * as a resource reference within drawing instructions stream
+ * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
+ * 'XObject', 'Font', 'Properties'
+ *
+ * @param string $type
+ * @param Zend_Pdf_Resource $resource
+ * @return string
+ */
+ protected function _attachResource($type, Zend_Pdf_Resource $resource)
+ {
+ // Check that Resources dictionary contains appropriate resource set
+ if ($this->_dictionary->Resources->$type === null) {
+ $this->_dictionary->Resources->touch();
+ $this->_dictionary->Resources->$type = new Zend_Pdf_Element_Dictionary();
+ } else {
+ $this->_dictionary->Resources->$type->touch();
+ }
+
+ // Check, that resource is already attached to resource set.
+ $resObject = $resource->getResource();
+ foreach ($this->_dictionary->Resources->$type->getKeys() as $ResID) {
+ if ($this->_dictionary->Resources->$type->$ResID === $resObject) {
+ return $ResID;
+ }
+ }
+
+ $idCounter = 1;
+ do {
+ $newResName = $type[0] . $idCounter++;
+ } while ($this->_dictionary->Resources->$type->$newResName !== null);
+
+ $this->_dictionary->Resources->$type->$newResName = $resObject;
+ $this->_objFactory->attach($resource->getFactory());
+
+ return $newResName;
+ }
+
+ /**
+ * Add procedureSet to the Page description
+ *
+ * @param string $procSetName
+ */
+ protected function _addProcSet($procSetName)
+ {
+ // Check that Resources dictionary contains ProcSet entry
+ if ($this->_dictionary->Resources->ProcSet === null) {
+ $this->_dictionary->Resources->touch();
+ $this->_dictionary->Resources->ProcSet = new Zend_Pdf_Element_Array();
+ } else {
+ $this->_dictionary->Resources->ProcSet->touch();
+ }
+
+ foreach ($this->_dictionary->Resources->ProcSet->items as $procSetEntry) {
+ if ($procSetEntry->value == $procSetName) {
+ // Procset is already included into a ProcSet array
+ return;
+ }
+ }
+
+ $this->_dictionary->Resources->ProcSet->items[] = new Zend_Pdf_Element_Name($procSetName);
+ }
+
+ /**
+ * Returns dictionaries of used resources.
+ *
+ * Used for canvas implementations interoperability
+ *
+ * Structure of the returned array:
+ * array(
+ * <resTypeName> => array(
+ * <resName> => <Zend_Pdf_Resource object>,
+ * <resName> => <Zend_Pdf_Resource object>,
+ * <resName> => <Zend_Pdf_Resource object>,
+ * ...
+ * ),
+ * <resTypeName> => array(
+ * <resName> => <Zend_Pdf_Resource object>,
+ * <resName> => <Zend_Pdf_Resource object>,
+ * <resName> => <Zend_Pdf_Resource object>,
+ * ...
+ * ),
+ * ...
+ * 'ProcSet' => array()
+ * )
+ *
+ * where ProcSet array is a list of used procedure sets names (strings).
+ * Allowed procedure set names: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'
+ *
+ * @internal
+ * @return array
+ */
+ public function getResources()
+ {
+ $resources = array();
+ $resDictionary = $this->_dictionary->Resources;
+
+ foreach ($resDictionary->getKeys() as $resType) {
+ $resources[$resType] = array();
+
+ if ($resType == 'ProcSet') {
+ foreach ($resDictionary->ProcSet->items as $procSetEntry) {
+ $resources[$resType][] = $procSetEntry->value;
+ }
+ } else {
+ $resMap = $resDictionary->$resType;
+
+ foreach ($resMap->getKeys() as $resId) {
+ $resources[$resType][$resId] =new Zend_Pdf_Resource_Unified($resMap->$resId);
+ }
+ }
+ }
+
+ return $resources;
+ }
+
+ /**
+ * Get drawing instructions stream
+ *
+ * It has to be returned as a PDF stream object to make it reusable.
+ *
+ * @internal
+ * @returns Zend_Pdf_Resource_ContentStream
+ */
+ public function getContents()
+ {
+ /** @todo implementation */
+ }
+
+ /**
+ * Return the height of this page in points.
+ *
+ * @return float
+ */
+ public function getHeight()
+ {
+ return $this->_dictionary->MediaBox->items[3]->value -
+ $this->_dictionary->MediaBox->items[1]->value;
+ }
+
+ /**
+ * Return the width of this page in points.
+ *
+ * @return float
+ */
+ public function getWidth()
+ {
+ return $this->_dictionary->MediaBox->items[2]->value -
+ $this->_dictionary->MediaBox->items[0]->value;
+ }
+
+ /**
+ * Clone page, extract it and dependent objects from the current document,
+ * so it can be used within other docs.
+ */
+ public function __clone()
+ {
+ $factory = Zend_Pdf_ElementFactory::createFactory(1);
+ $processed = array();
+
+ // Clone dictionary object.
+ // Do it explicitly to prevent sharing page attributes between different
+ // results of clonePage() operation (other resources are still shared)
+ $dictionary = new Zend_Pdf_Element_Dictionary();
+ foreach ($this->_dictionary->getKeys() as $key) {
+ $dictionary->$key = $this->_dictionary->$key->makeClone($factory->getFactory(),
+ $processed,
+ Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
+ }
+
+ $this->_dictionary = $factory->newObject($dictionary);
+ $this->_objFactory = $factory;
+ $this->_attached = false;
+ $this->_style = null;
+ $this->_font = null;
+ }
+
+ /**
+ * Clone page, extract it and dependent objects from the current document,
+ * so it can be used within other docs.
+ *
+ * @internal
+ * @param Zend_Pdf_ElementFactory_Interface $factory
+ * @param array $processed
+ * @return Zend_Pdf_Page
+ */
+ public function clonePage($factory, &$processed)
+ {
+ // Clone dictionary object.
+ // Do it explicitly to prevent sharing page attributes between different
+ // results of clonePage() operation (other resources are still shared)
+ $dictionary = new Zend_Pdf_Element_Dictionary();
+ foreach ($this->_dictionary->getKeys() as $key) {
+ $dictionary->$key = $this->_dictionary->$key->makeClone($factory->getFactory(),
+ $processed,
+ Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
+ }
+
+ $clonedPage = new Zend_Pdf_Page($factory->newObject($dictionary), $factory);
+ $clonedPage->_attached = false;
+
+ return $clonedPage;
+ }
+
+ /**
+ * Retrive PDF file reference to the page
+ *
+ * @internal
+ * @return Zend_Pdf_Element_Dictionary
+ */
+ public function getPageDictionary()
+ {
+ return $this->_dictionary;
+ }
+
+ /**
+ * Dump current drawing instructions into the content stream.
+ *
+ * @todo Don't forget to close all current graphics operations (like path drawing)
+ *
+ * @throws Zend_Pdf_Exception
+ */
+ public function flush()
+ {
+ if ($this->_saveCount != 0) {
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Saved graphics state is not restored');
+ }
+
+ if ($this->_contents == '') {
+ return;
+ }
+
+ if ($this->_dictionary->Contents->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
+ /**
+ * It's a stream object.
+ * Prepare Contents page attribute for update.
+ */
+ $this->_dictionary->touch();
+
+ $currentPageContents = $this->_dictionary->Contents;
+ $this->_dictionary->Contents = new Zend_Pdf_Element_Array();
+ $this->_dictionary->Contents->items[] = $currentPageContents;
+ } else {
+ $this->_dictionary->Contents->touch();
+ }
+
+ if ((!$this->_safeGS) && (count($this->_dictionary->Contents->items) != 0)) {
+ /**
+ * Page already has some content which is not treated as safe.
+ *
+ * Add save/restore GS operators
+ */
+ $this->_addProcSet('PDF');
+
+ $newContentsArray = new Zend_Pdf_Element_Array();
+ $newContentsArray->items[] = $this->_objFactory->newStreamObject(" q\n");
+ foreach ($this->_dictionary->Contents->items as $contentStream) {
+ $newContentsArray->items[] = $contentStream;
+ }
+ $newContentsArray->items[] = $this->_objFactory->newStreamObject(" Q\n");
+
+ $this->_dictionary->touch();
+ $this->_dictionary->Contents = $newContentsArray;
+
+ $this->_safeGS = true;
+ }
+
+ $this->_dictionary->Contents->items[] =
+ $this->_objFactory->newStreamObject($this->_contents);
+
+ $this->_contents = '';
+ }
+
+ /**
+ * Prepare page to be rendered into PDF.
+ *
+ * @todo Don't forget to close all current graphics operations (like path drawing)
+ *
+ * @param Zend_Pdf_ElementFactory_Interface $objFactory
+ * @throws Zend_Pdf_Exception
+ */
+ public function render(Zend_Pdf_ElementFactory_Interface $objFactory)
+ {
+ $this->flush();
+
+ if ($objFactory === $this->_objFactory) {
+ // Page is already attached to the document.
+ return;
+ }
+
+ if ($this->_attached) {
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Page is attached to other documen. Use clone $page to get it context free.');
+ } else {
+ $objFactory->attach($this->_objFactory);
+ }
+ }
+
+ /**
+ * Extract resources attached to the page
+ *
+ * This method is not intended to be used in userland, but helps to optimize some document wide operations
+ *
+ * returns array of Zend_Pdf_Element_Dictionary objects
+ *
+ * @internal
+ * @return array
+ */
+ public function extractResources()
+ {
+ return $this->_dictionary->Resources;
+ }
+
+ /**
+ * Extract fonts attached to the page
+ *
+ * returns array of Zend_Pdf_Resource_Font_Extracted objects
+ *
+ * @return array
+ * @throws Zend_Pdf_Exception
+ */
+ public function extractFonts()
+ {
+ if ($this->_dictionary->Resources->Font === null) {
+ // Page doesn't have any font attached
+ // Return empty array
+ return array();
+ }
+
+ $fontResources = $this->_dictionary->Resources->Font;
+
+ $fontResourcesUnique = array();
+ foreach ($fontResources->getKeys() as $fontResourceName) {
+ $fontDictionary = $fontResources->$fontResourceName;
+
+ if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference ||
+ $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
+ }
+
+ $fontResourcesUnique[spl_object_hash($fontDictionary->getObject())] = $fontDictionary;
+ }
+
+ $fonts = array();
+ require_once 'Zend/Pdf/Exception.php';
+ foreach ($fontResourcesUnique as $resourceId => $fontDictionary) {
+ try {
+ require_once 'Zend/Pdf/Resource/Font/Extracted.php';
+ // Try to extract font
+ $extractedFont = new Zend_Pdf_Resource_Font_Extracted($fontDictionary);
+
+ $fonts[$resourceId] = $extractedFont;
+ } catch (Zend_Pdf_Exception $e) {
+ if ($e->getMessage() != 'Unsupported font type.') {
+ throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+ }
+
+ return $fonts;
+ }
+
+ /**
+ * Extract font attached to the page by specific font name
+ *
+ * $fontName should be specified in UTF-8 encoding
+ *
+ * @return Zend_Pdf_Resource_Font_Extracted|null
+ * @throws Zend_Pdf_Exception
+ */
+ public function extractFont($fontName)
+ {
+ if ($this->_dictionary->Resources->Font === null) {
+ // Page doesn't have any font attached
+ return null;
+ }
+
+ $fontResources = $this->_dictionary->Resources->Font;
+
+ $fontResourcesUnique = array();
+
+ require_once 'Zend/Pdf/Exception.php';
+ foreach ($fontResources->getKeys() as $fontResourceName) {
+ $fontDictionary = $fontResources->$fontResourceName;
+
+ if (! ($fontDictionary instanceof Zend_Pdf_Element_Reference ||
+ $fontDictionary instanceof Zend_Pdf_Element_Object) ) {
+ require_once 'Zend/Pdf/Exception.php';
+ throw new Zend_Pdf_Exception('Font dictionary has to be an indirect object or object reference.');
+ }
+
+ $resourceId = spl_object_hash($fontDictionary->getObject());
+ if (isset($fontResourcesUnique[$resourceId])) {
+ continue;
+ } else {
+ // Mark resource as processed
+ $fontResourcesUnique[$resourceId] = 1;
+ }
+
+ if ($fontDictionary->BaseFont->value != $fontName) {
+ continue;
+ }
+
+ try {
+ // Try to extract font
+ require_once 'Zend/Pdf/Resource/Font/Extracted.php';
+ return new Zend_Pdf_Resource_Font_Extracted($fontDictionary);
+ } catch (Zend_Pdf_Exception $e) {
+ if ($e->getMessage() != 'Unsupported font type.') {
+ throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
+ }
+
+ // Continue searhing font with specified name
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ *
+ * @param Zend_Pdf_Annotation $annotation
+ * @return Zend_Pdf_Page
+ */
+ public function attachAnnotation(Zend_Pdf_Annotation $annotation)
+ {
+ $annotationDictionary = $annotation->getResource();
+ if (!$annotationDictionary instanceof Zend_Pdf_Element_Object &&
+ !$annotationDictionary instanceof Zend_Pdf_Element_Reference) {
+ $annotationDictionary = $this->_objFactory->newObject($annotationDictionary);
+ }
+
+ if ($this->_dictionary->Annots === null) {
+ $this->_dictionary->touch();
+ $this->_dictionary->Annots = new Zend_Pdf_Element_Array();
+ } else {
+ $this->_dictionary->Annots->touch();
+ }
+
+ $this->_dictionary->Annots->items[] = $annotationDictionary;
+
+ $annotationDictionary->touch();
+ $annotationDictionary->P = $this->_dictionary;
+
+ return $this;
+ }
+}
+