Browse Source

Zend_Pdf: ZF-5832, ZF-6911, ZF-6914, ZF-6915 related commit.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@16803 44c647ce-9c0f-0410-b52a-842ac1e357ba
alexander 16 years ago
parent
commit
107f4cf6f2
41 changed files with 3514 additions and 16 deletions
  1. 395 6
      library/Zend/Pdf.php
  2. 402 0
      library/Zend/Pdf/Action.php
  3. 101 0
      library/Zend/Pdf/Action/GoTo.php
  4. 39 0
      library/Zend/Pdf/Action/GoTo3DView.php
  5. 38 0
      library/Zend/Pdf/Action/GoToE.php
  6. 38 0
      library/Zend/Pdf/Action/GoToR.php
  7. 39 0
      library/Zend/Pdf/Action/Hide.php
  8. 39 0
      library/Zend/Pdf/Action/ImportData.php
  9. 39 0
      library/Zend/Pdf/Action/JavaScript.php
  10. 38 0
      library/Zend/Pdf/Action/Launch.php
  11. 38 0
      library/Zend/Pdf/Action/Movie.php
  12. 39 0
      library/Zend/Pdf/Action/Named.php
  13. 39 0
      library/Zend/Pdf/Action/Rendition.php
  14. 39 0
      library/Zend/Pdf/Action/ResetForm.php
  15. 39 0
      library/Zend/Pdf/Action/SetOCGState.php
  16. 39 0
      library/Zend/Pdf/Action/Sound.php
  17. 39 0
      library/Zend/Pdf/Action/SubmitForm.php
  18. 38 0
      library/Zend/Pdf/Action/Thread.php
  19. 39 0
      library/Zend/Pdf/Action/Trans.php
  20. 37 0
      library/Zend/Pdf/Action/URI.php
  21. 38 0
      library/Zend/Pdf/Action/Unknown.php
  22. 195 0
      library/Zend/Pdf/Destination.php
  23. 77 0
      library/Zend/Pdf/Destination/Fit.php
  24. 77 0
      library/Zend/Pdf/Destination/FitBoundingBox.php
  25. 100 0
      library/Zend/Pdf/Destination/FitBoundingBoxHorizontally.php
  26. 101 0
      library/Zend/Pdf/Destination/FitBoundingBoxVertically.php
  27. 100 0
      library/Zend/Pdf/Destination/FitHorizontally.php
  28. 173 0
      library/Zend/Pdf/Destination/FitRectangle.php
  29. 100 0
      library/Zend/Pdf/Destination/FitVertically.php
  30. 37 0
      library/Zend/Pdf/Destination/Unknown.php
  31. 179 0
      library/Zend/Pdf/Destination/Zoom.php
  32. 0 3
      library/Zend/Pdf/Element.php
  33. 1 0
      library/Zend/Pdf/Element/Numeric.php
  34. 3 2
      library/Zend/Pdf/Page.php
  35. 22 2
      library/Zend/Pdf/Parser.php
  36. 387 0
      tests/Zend/Pdf/ActionTest.php
  37. 9 2
      tests/Zend/Pdf/AllTests.php
  38. 287 0
      tests/Zend/Pdf/DestinationTest.php
  39. 6 1
      tests/Zend/Pdf/DrawingTest.php
  40. 63 0
      tests/Zend/Pdf/NamedDestinationsTest.php
  41. 5 0
      tests/Zend/Pdf/ProcessingTest.php

+ 395 - 6
library/Zend/Pdf.php

@@ -73,6 +73,15 @@ require_once 'Zend/Pdf/Resource/Image/Png.php';
 /** Zend_Memory */
 require_once 'Zend/Memory.php';
 
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Exception.php';
+
 /**
  * General entity which describes PDF document.
  * It implements document abstraction with a document level operations.
@@ -95,7 +104,7 @@ class Zend_Pdf
     /**
      * Version number of generated PDF documents.
      */
-    const PDF_VERSION = 1.4;
+    const PDF_VERSION = '1.4';
 
     /**
      * PDF file header.
@@ -157,6 +166,12 @@ class Zend_Pdf
      */
     protected $_namedActions = array();
 
+    /**
+     * Document named destinations
+     *
+     * @var array   - array of Zend_Pdf_Destinations objects
+     */
+    protected $_namedDestinations = array();
 
     /**
      * Pdf trailer (last or just created)
@@ -165,7 +180,6 @@ class Zend_Pdf
      */
     protected $_trailer = null;
 
-
     /**
      * PDF objects factory.
      *
@@ -267,6 +281,28 @@ class Zend_Pdf
     }
 
     /**
+     * Parse destination structure (array or dictionary) and
+     * return it as a Zend_Pdf_Destination or Zend_Pdf_Action object
+     *
+     * $param Zend_Pdf_Element $destination
+     * @return Zend_Pdf_Destination|
+     * @throws Zend_Pdf_Exception
+     */
+    protected function _loadDestination(Zend_Pdf_Element $destination) {
+        if ($destination->getType() == Zend_Pdf_Element::TYPE_ARRAY) {
+            // Destination is an array, just treat it as an explicit destination array
+            return Zend_Pdf_Destination::load($destination);
+        } else if ($destination->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+        	// Load destination as appropriate action
+            return Zend_Pdf_Action::load($destination);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception( 'PDF named destination entry must be an array or dictionary.' );
+        }
+    }
+
+
+    /**
      * Creates or loads PDF document.
      *
      * If $source is null, then it creates a new document.
@@ -290,8 +326,9 @@ class Zend_Pdf
         $this->_objFactory = Zend_Pdf_ElementFactory::createFactory(1);
 
         if ($source !== null) {
-            $this->_parser  = new Zend_Pdf_Parser($source, $this->_objFactory, $load);
-            $this->_trailer = $this->_parser->getTrailer();
+            $this->_parser           = new Zend_Pdf_Parser($source, $this->_objFactory, $load);
+            $this->_pdfHeaderVersion = $this->_parser->getPDFVersion();
+            $this->_trailer          = $this->_parser->getTrailer();
             if ($this->_trailer->Encrypt !== null) {
                 require_once 'Zend/Pdf/Exception.php';
                 throw new Zend_Pdf_Exception('Encrypted document modification is not supported');
@@ -328,7 +365,80 @@ class Zend_Pdf
 
                 $this->_originalProperties = $this->properties;
             }
+
+            // Collect named destinations (exclude not referenced pages)
+            $root = $this->_trailer->Root;
+
+            $pdfHeaderVersion = $this->_parser->getPDFVersion();
+            if ($root->Version !== null  &&  version_compare($root->Version->value, $pdfHeaderVersion, '>')) {
+                $versionIs_1_2_plus = version_compare($root->Version->value,    '1.1', '>');
+            } else {
+                $versionIs_1_2_plus = version_compare($pdfHeaderVersion, '1.1', '>');
+            }
+
+            if ($versionIs_1_2_plus) {
+                // PDF version is 1.2+
+                // Look for Destinations structure at Name dictionary
+                if ($root->Names !== null  &&  $root->Names->Dests !== null) {
+                    $intermediateNodes = array();
+                    $leafNodes         = array();
+                    if ($root->Names->Dests->Kids !== null) {
+                        $intermediateNodes[] = $root->Names->Dests;
+                    } else {
+                        $leafNodes[] = $root->Names->Dests;
+                    }
+
+                    while (count($intermediateNodes) != 0) {
+                        $newIntermediateNodes = array();
+                        foreach ($intermediateNodes as $node) {
+                            foreach ($node->Kids->items as $childNode) {
+                                if ($childNode->Kids !== null) {
+                                    $newIntermediateNodes[] = $childNode;
+                                } else {
+                                    $leafNodes[] = $childNode;
+                                }
+                            }
+                        }
+                        $intermediateNodes = $newIntermediateNodes;
+                    }
+
+                    foreach ($leafNodes as $leafNode) {
+                        $destinationsCount = count($leafNode->items)/2;
+                        for ($count = 0; $count < $destinationsCount; $count++) {
+                            $destinationName = $leafNode->items[$count*2];
+                            $destination     = $this->_loadDestination($leafNode->items[$count*2 + 1]);
+
+                            if ($destination instanceof Zend_Pdf_Action) {
+                                $this->_namedActions[$destKey]      = $destination;
+                            } else {
+                                $this->_namedDestinations[$destKey] = $destination;
+                            }
+                        }
+                    }
+                }
+            } else {
+                // PDF version is 1.1 (or earlier)
+                // Look for Destinations sructure at Dest entry of document catalog
+                if ($root->Dests !== null) {
+                    if ($root->Dests->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
+                        require_once 'Zend/Pdf/Exception.php';
+                        throw new Zend_Pdf_Exception( 'Document catalog Dests entry must be a dictionary.' );
+                    }
+
+                    foreach ($root->Dests->getKeys() as $destKey) {
+                        $destination = $this->_loadDestination($root->Dests->$destKey);
+
+                        if ($destination instanceof Zend_Pdf_Action) {
+                        	$this->_namedActions[$destKey]      = $destination;
+                        } else {
+                        	$this->_namedDestinations[$destKey] = $destination;
+                        }
+                    }
+                }
+            }
         } else {
+            $this->_pdfHeaderVersion = Zend_Pdf::PDF_VERSION;
+
             $trailerDictionary = new Zend_Pdf_Element_Dictionary();
 
             /**
@@ -366,6 +476,17 @@ class Zend_Pdf
     }
 
     /**
+     * Destructor
+     * Clean up resources
+     */
+    public function __destruct()
+    {
+    	foreach ($this->_namedActions as $action) {
+    		$action->clean();
+    	}
+    }
+
+    /**
      * Retrive number of revisions.
      *
      * @return integer
@@ -453,7 +574,6 @@ class Zend_Pdf
         }
     }
 
-
     /**
      * Orginize pages to tha pages tree structure.
      *
@@ -464,10 +584,13 @@ class Zend_Pdf
      */
     protected function _dumpPages()
     {
-        $pagesContainer = $this->_trailer->Root->Pages;
+        $root = $this->_trailer->Root;
+        $pagesContainer = $root->Pages;
+
         $pagesContainer->touch();
         $pagesContainer->Kids->items->clear();
 
+        $pageDictionaries = new SplObjectStorage();
         foreach ($this->pages as $page ) {
             $page->render($this->_objFactory);
 
@@ -476,12 +599,153 @@ class Zend_Pdf
             $pageDictionary->Parent = $pagesContainer;
 
             $pagesContainer->Kids->items[] = $pageDictionary;
+
+            // Collect page dictionary
+            $pageDictionaries->attach($pageDictionary);
         }
 
         $pagesContainer->Count->touch();
         $pagesContainer->Count->value = count($this->pages);
+
+        // Refresh named actions list
+        foreach ($this->_namedActions as $name => $namedAction) {
+        	$rootAction = $namedAction;
+
+        	// Walk through chained actions
+        	foreach ($namedAction->getAllActions() as $chainedAction) {
+                if ($chainedAction instanceof Zend_Pdf_Action_GoTo) {
+                    $destination = $chainedAction->getDestination();
+                    if (!$destination instanceof Zend_Pdf_Destination) {
+                        require_once 'Zend/Pdf/Exception.php';
+                        throw new Zend_Pdf_Exception('PDF named actions (destinations) must refer target as an explicit destination.');
+                    }
+
+                    $target = $destination->getTarget();
+                    if ($target instanceof Zend_Pdf_Element) {
+                        if (!$pageDictionaries->contains($target)) {
+                            $rootAction = $chainedAction->extract();
+                        }
+                    } else if ($target > count($this->pages) ) {
+                        $rootAction = $chainedAction->extract();
+                    }
+                }
+        	}
+
+        	if ($rootAction === null) {
+        		unset($this->_namedActions[$name]);
+        	} else {
+        		$rootAction->rebuildSubtree();
+        		$this->_namedActions[$name] = $rootAction;
+        	}
+        }
+
+        // Refresh named destinations list
+        foreach ($this->_namedDestinations as $name => $destination) {
+            $target = $destination->getTarget();
+
+            if ($target instanceof Zend_Pdf_Element) {
+            	if (!$pageDictionaries->contains($target)) {
+                    unset($this->_namedDestinations[$name]);
+            	}
+            } else if ($target > count($this->pages) ) {
+                unset($this->_namedDestinations[$name]);
+            }
+        }
+
+
+        $openAction = $this->getOpenAction();
+        if ($openAction !== null) {
+        	if ($openAction instanceof Zend_Pdf_Action) {
+                $rootAction = $openAction;
+
+                // Walk through chained actions
+                foreach ($openAction->getAllActions() as $chainedAction) {
+                    if ($chainedAction instanceof Zend_Pdf_Action_GoTo) {
+                        $destination = $chainedAction->getDestination();
+                        if (!$destination instanceof Zend_Pdf_Destination) {
+                        	// Look for $destination within named destinations
+                            if (!isset($this->_namedActions[$destination])  &&  !isset($this->_namedDestinations[$destination])) {
+                            	$rootAction = $chainedAction->extract();
+                            }
+                        } else {
+                        	// Destination is Zend_Pdf_Destination object
+                            $target = $destination->getTarget();
+                            if ($target instanceof Zend_Pdf_Element) {
+                            	// which refers some page dictionary object
+                            	// (check if it's within a collected dictionaries for current document)
+                                if (!$pageDictionaries->contains($target)) {
+                                    $rootAction = $chainedAction->extract();
+                                }
+                            } else if ($target > count($this->pages) ) {
+                            	// it's a page number, check if we have enough pages
+                                $rootAction = $chainedAction->extract();
+                            }
+                        }
+                    }
+                }
+
+                if ($rootAction !== null) {
+                	$rootAction->rebuildSubtree();
+                	$this->setOpenAction($rootAction);
+                    $rootAction->clean();
+                } else {
+                    $this->setOpenAction(null);
+                }
+        	} else if ($openAction instanceof Zend_Pdf_Destination) {
+                $target = $openAction->getTarget();
+
+                if ($target instanceof Zend_Pdf_Element) {
+                    if (!$pageDictionaries->contains($target)) {
+                        $this->setOpenAction(null);
+                    }
+                } else if ($target > count($this->pages) ) {
+                    $this->setOpenAction(null);
+                }
+        	} else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('OpenAction has to be either PDF Action or Destination.');
+        	}
+        }
     }
 
+    /**
+     * Dump named destinations
+     *
+     * @todo Create a balanced tree instead of plain structure.
+     */
+    protected function _dumpNamedDestinations()
+    {
+        $namedDestinations = $this->_namedActions + $this->_namedDestinations;
+        ksort($namedDestinations, SORT_STRING);
+
+        $destArray = $this->_objFactory->newObject(new Zend_Pdf_Element_Array());
+        $destArrayItems = $destArray->items;
+        foreach ($namedDestinations as $name => $destination) {
+        	$destArrayItems[] = new Zend_Pdf_Element_String($name);
+
+        	if ($destination instanceof Zend_Pdf_Action) {
+        		$destArrayItems[] = $destination->getDictionary();
+        	} else if ($destination instanceof Zend_Pdf_Destination) {
+        		$destArrayItems[] = $destination->getDestinationArray();
+        	} else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('PDF named destinations must be Zend_Pdf_Action or Zend_Pdf_Destination objects.');
+        	}
+        }
+
+        $DestTree = $this->_objFactory->newObject(new Zend_Pdf_Element_Dictionary());
+        $DestTree->Names = $destArray;
+
+        $root = $this->_trailer->Root;
+
+        if ($root->Names === null) {
+            $root->touch();
+            $root->Names = new Zend_Pdf_Element_Dictionary();
+        } else {
+            $root->Names->touch();
+        }
+        $root->Names = $DestTree;
+    }
 
     /**
      * Create page object, attached to the PDF document.
@@ -555,6 +819,43 @@ class Zend_Pdf
         return $this->_javaScript;
     }
 
+    /**
+     * Get open Action
+     * Returns Zend_Pdf_Destination or Zend_Pdf_Action (which is actually GoTo Action) object
+     *
+     * @return Zend_Pdf_Destination|Zend_Pdf_Action
+     */
+    public function getOpenAction()
+    {
+        if ($this->_trailer->Root->OpenAction !== null) {
+        	return $this->_loadDestination($this->_trailer->Root->OpenAction);
+        } else {
+        	return null;
+        }
+    }
+
+    /**
+     * Set open Action which is actually Zend_Pdf_Destination or Zend_Pdf_Action object
+     *
+     * @param Zend_Pdf_Destination|Zend_Pdf_Action $openAction
+     * @throws Zend_Pdf_Exception
+     */
+    public function setOpenAction($openAction)
+    {
+        $root = $this->_trailer->Root;
+        $root->touch();
+
+        if ($openAction instanceof Zend_Pdf_Destination) {
+        	$root->OpenAction = $openAction->getDestinationArray();
+        } if ($openAction instanceof Zend_Pdf_Action) {
+        	$root->OpenAction = $openAction->getDictionary();
+        } if ($openAction === null) {
+        	$root->OpenAction = null;
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Open action must be a Zend_Pdf_Destination or Zend_Pdf_Action objects or null.');
+        }
+    }
 
     /**
      * Return an associative array containing all the named actions in the PDF.
@@ -569,6 +870,93 @@ class Zend_Pdf
     }
 
     /**
+     * Return specified named action
+     *
+     * @param string $name
+     * @return Zend_Pdf_Action
+     */
+    public function getNamedAction($name)
+    {
+    	if (isset($this->_namedActions[$name])) {
+    		return $this->_namedActions[$name];
+    	} else {
+    		return null;
+    	}
+    }
+
+    /**
+     * Set specified named action
+     *
+     * @param string $name
+     * @param Zend_Pdf_Action_GoTo $action
+     */
+    public function setNamedAction($name, Zend_Pdf_Action_GoTo $action)
+    {
+    	if (isset($this->_namedActions[$name])) {
+    		$this->_namedActions[$name]->clean();
+    	}
+    	// Clean corresponding named destination if set
+        unset($this->_namedDestinations[$name]);
+
+    	if (!$action->getDestination() instanceof Zend_Pdf_Destination) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('PDF named actions (destinations) must refer target as an explicit destination.');
+    	}
+
+    	if ($action !== null) {
+            $this->_namedActions[$name] = $action;
+    	} else {
+    		unset($this->_namedActions[$name]);
+    	}
+    }
+
+    /**
+     * Return an associative array containing all the named destinationss in the PDF.
+     *
+     * @return array
+     */
+    public function getNamedDestinations()
+    {
+        return $this->_namedDestinations;
+    }
+
+    /**
+     * Return specified named destination
+     *
+     * @param string $name
+     * @return Zend_Pdf_Destination
+     */
+    public function getNamedDestination($name)
+    {
+    	if (isset($this->_namedDestinations[$name])) {
+    		return $this->_namedDestinations[$name];
+    	} else {
+    		return null;
+    	}
+    }
+
+    /**
+     * Set specified named action
+     *
+     * @param string $name
+     * @param Zend_Pdf_Destination $destination
+     */
+    public function setNamedDestination($name, Zend_Pdf_Destination $destination)
+    {
+        // Clean corresponding named action if set
+    	if (isset($this->_namedActions[$name])) {
+            $this->_namedActions[$name]->clean();
+            unset($this->_namedActions[$name]);
+        }
+
+        if ($destination !== null) {
+    	   $this->_namedDestinations[$name] = $destination;
+        } else {
+        	unset($this->_namedDestinations[$name]);
+        }
+    }
+
+    /**
      * Extract fonts attached to the document
      *
      * returns array of Zend_Pdf_Resource_Font_Extracted objects
@@ -750,6 +1138,7 @@ class Zend_Pdf
         }
 
         $this->_dumpPages();
+        $this->_dumpNamedDestinations();
 
         // Check, that PDF file was modified
         // File is always modified by _dumpPages() now, but future implementations may eliminate this.

+ 402 - 0
library/Zend/Pdf/Action.php

@@ -0,0 +1,402 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_ElementFactory */
+require_once 'Zend/Pdf/ElementFactory.php';
+
+
+/**
+ * Abstract PDF action representation class
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Pdf_Action
+{
+	/**
+	 * Action dictionary
+	 *
+	 * @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
+	 */
+	protected $_actionDictionary;
+
+	/**
+	 * A list of next actions in actions tree (used for actions chaining)
+	 *
+	 * @var SplObjectStorage  Contains Zend_Pdf_Action objects
+	 */
+	protected $_next;
+
+	/**
+	 * Parent object in Actions tree (or null if it's a root object)
+	 *
+	 * @var Zend_Pdf_Action
+	 */
+	protected $_parent;
+
+	/**
+     * Object constructor
+     *
+     * @param Zend_Pdf_Element_Dictionary $dictionary
+     * @param Zend_Pdf_Action|null        $parentAction
+     * @param SplObjectStorage            $processedActions  list of already processed action dictionaries, used to avoid cyclic references
+     * @throws Zend_Pdf_Exception
+	 */
+	public function __construct(Zend_Pdf_Element $dictionary, $parentAction, SplObjectStorage $processedActions)
+	{
+        if ($dictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$dictionary mast be a direct or an indirect dictionary object.');
+        }
+        if ($parentAction !== null  &&  !$parentAction instanceof Zend_Pdf_Action) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Zend_Pdf_Action constructor $parentAction parameter must be a Zend_Pdf_Action object.');
+        }
+
+        $this->_actionDictionary = $dictionary;
+		$this->_parent           = $parentAction;
+        $this->_next             = new SplObjectStorage();
+
+		if ($dictionary->Next !== null) {
+			if ($dictionary->Next instanceof Zend_Pdf_Element_Dictionary) {
+				// Check if dictionary object is not already processed
+				if (!$processedActions->contains($dictionary->Next)) {
+					$processedActions->attach($dictionary->Next);
+					$this->_next->attach(Zend_Pdf_Action::load($dictionary->Next, $this, $processedActions));
+				}
+			} else if ($dictionary->Next instanceof Zend_Pdf_Element_Array) {
+				foreach ($dictionary->Next->items as $chainedActionDictionary) {
+					// Check if dictionary object is not already processed
+					if (!$processedActions->contains($chainedActionDictionary)) {
+                        $processedActions->attach($chainedActionDictionary);
+                        $this->_next->attach(Zend_Pdf_Action::load($chainedActionDictionary, $this, $processedActions));
+					}
+				}
+			} else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('PDF Action dictionary Next entry must be a dictionary or an array.');
+			}
+		}
+	}
+
+	/**
+	 * Load PDF action object using specified dictionary
+	 *
+     * @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 $processedActions  list of already processed action dictionaries, used to avoid cyclic references
+	 * @return Zend_Pdf_Action
+	 * @throws Zend_Pdf_Exception
+	 */
+	public static function load(Zend_Pdf_Element $dictionary, $parentAction = null, $processedActions = null)
+	{
+        if ($processedActions === null) {
+            $processedActions = new SplObjectStorage();
+        } else if (!$processedActions instanceof SplObjectStorage) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$processedActions parameter must be a SplObjectStorage object or null.');
+        }
+
+        if ($dictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$dictionary mast be a direct or an indirect dictionary object.');
+        }
+        if (isset($dictionary->Type)  &&  $dictionary->Type->value != 'Action') {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Action dictionary Type entry must be set to \'Action\'.');
+        }
+
+        if ($dictionary->S === null) {
+			require_once 'Zend/Pdf/Exception.php';
+			throw new Zend_Pdf_Exception('Action dictionary must have S entry');
+		}
+
+		switch ($dictionary->S->value) {
+			case 'GoTo':
+				require_once 'Zend/Pdf/Action/GoTo.php';
+				return new Zend_Pdf_Action_GoTo($dictionary, $parentAction, $processedActions);
+				brake;
+
+            case 'GoToR':
+                require_once 'Zend/Pdf/Action/GoToR.php';
+                return new Zend_Pdf_Action_GoToR($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'GoToE':
+                require_once 'Zend/Pdf/Action/GoToE.php';
+                return new Zend_Pdf_Action_GoToE($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Launch':
+                require_once 'Zend/Pdf/Action/Launch.php';
+                return new Zend_Pdf_Action_Launch($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Thread':
+                require_once 'Zend/Pdf/Action/Thread.php';
+                return new Zend_Pdf_Action_Thread($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'URI':
+                require_once 'Zend/Pdf/Action/URI.php';
+                return new Zend_Pdf_Action_URI($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Sound':
+                require_once 'Zend/Pdf/Action/Sound.php';
+                return new Zend_Pdf_Action_Sound($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Movie':
+                require_once 'Zend/Pdf/Action/Movie.php';
+                return new Zend_Pdf_Action_Movie($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Hide':
+                require_once 'Zend/Pdf/Action/Hide.php';
+                return new Zend_Pdf_Action_Hide($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Named':
+                require_once 'Zend/Pdf/Action/Named.php';
+                return new Zend_Pdf_Action_Named($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'SubmitForm':
+                require_once 'Zend/Pdf/Action/SubmitForm.php';
+                return new Zend_Pdf_Action_SubmitForm($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'ResetForm':
+                require_once 'Zend/Pdf/Action/ResetForm.php';
+                return new Zend_Pdf_Action_ResetForm($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'ImportData':
+                require_once 'Zend/Pdf/Action/ImportData.php';
+                return new Zend_Pdf_Action_ImportData($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'JavaScript':
+                require_once 'Zend/Pdf/Action/JavaScript.php';
+                return new Zend_Pdf_Action_JavaScript($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'SetOCGState':
+                require_once 'Zend/Pdf/Action/SetOCGState.php';
+                return new Zend_Pdf_Action_SetOCGState($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Rendition':
+                require_once 'Zend/Pdf/Action/Rendition.php';
+                return new Zend_Pdf_Action_Rendition($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'Trans':
+                require_once 'Zend/Pdf/Action/Trans.php';
+                return new Zend_Pdf_Action_Trans($dictionary, $parentAction, $processedActions);
+                brake;
+
+            case 'GoTo3DView':
+                require_once 'Zend/Pdf/Action/GoTo3DView.php';
+                return new Zend_Pdf_Action_GoTo3DView($dictionary, $parentAction, $processedActions);
+                brake;
+
+            default:
+                require_once 'Zend/Pdf/Action/Unknown.php';
+                return new Zend_Pdf_Action_Unknown($dictionary, $parentAction, $processedActions);
+                brake;
+		}
+	}
+
+	/**
+	 * Extract action from the chain
+	 *
+	 * Returns root of the updated actions tree
+	 *
+	 * @return Zend_Pdf_Action
+	 */
+	public function extract()
+	{
+		if (($parent = $this->_parent) !== null) {
+			$parent->_next->detach($this);
+
+            foreach ($this->_next as $chainedAction) {
+            	$parent->_next->attach($chainedAction);
+            	$chainedAction->_parent = $parent;
+            }
+
+            $this->_parent = null;
+            $this->_next   = new SplObjectStorage();
+
+            return $parent->getRoot();
+		} else {
+			// This is a root node. Treat first subaction as a new root
+
+			if ($this->_next->count() == 0) {
+				// There is no any action in a tree now
+				return null;
+			}
+
+			$this->_next->rewind();
+			$root = $this->_next->current();
+			$this->_next->detach($root);
+
+			$root->_parent = null;
+
+			foreach ($this->_next as $chainedAction) {
+				$root->_next->attach($chainedAction);
+				$chainedAction->_parent = $root;
+			}
+
+            $this->_next = new SplObjectStorage();
+
+			return $root;
+		}
+	}
+
+	/**
+	 * Destroy actions subtree
+	 *
+	 * Method has to be used to clean up resources after actions tree usage
+	 * since PHP doesn't do it automatically for objects with cyclic references
+	 */
+	public function clean()
+	{
+		$this->_parent = null;
+
+		foreach ($this->_next as $chainedAction) {
+			$chainedAction->clean();
+		}
+
+		$this->_next = new SplObjectStorage();
+	}
+
+	/**
+	 * Get root of actions tree
+	 *
+	 * @return Zend_Pdf_Action
+	 */
+	public function getRoot()
+	{
+		$root = $this;
+		while ($root->_parent !== null) {
+			$root = $root->_parent;
+		}
+		return $root;
+	}
+
+	/**
+	 * Return all subactions including this one
+	 *
+	 * @return SplObjectStorage
+	 */
+	public function getAllActions()
+	{
+		$actions = new SplObjectStorage();
+
+		$actions->attach($this);
+
+		foreach ($this->_next as $chainedAction) {
+			/** @todo Change  to $actions->addAll($subAction->allActions()) when PHP 5.3.0+ is required for ZF */
+			foreach ($chainedAction->getAllActions() as $action) {
+				$actions->attach($action);
+			}
+		}
+
+		return $actions;
+	}
+
+    /**
+     * Get handler
+     *
+     * @param string $property
+     * @return Zend_Pdf_Element | null
+     */
+    public function __get($property)
+    {
+        return $this->_actionDictionary->$property;
+    }
+
+    /**
+     * Set handler
+     *
+     * @param string $property
+     * @param  mixed $value
+     */
+    public function __set($item, $value)
+    {
+        $this->_actionDictionary->$property = $value;
+    }
+
+    /**
+     * Attach chained action
+     *
+     * @param Zend_Pdf_Action $action
+     */
+    public function attach(Zend_Pdf_Action $action)
+    {
+    	$this->_next->attach($action);
+    	$action->_parent = $this;
+    }
+
+    /**
+     * Rebuild PDF dictionaries corresponding to the current tree structure
+     */
+    public function rebuildSubtree()
+    {
+    	switch (count($this->_next)) {
+    		case 0:
+    			$this->_actionDictionary->Next = null;
+    			break;
+
+    		case 1:
+    			$this->_next->rewind();
+    			$chainedAction = $this->_next->current();
+                $chainedAction->rebuildSubtree();
+    			$this->_actionDictionary->Next = $chainedAction->_actionDictionary;
+    			break;
+
+    		default:
+    			$nextArray = new Zend_Pdf_Element_Array();
+    			foreach ($this->_next as $chainedAction) {
+                    $chainedAction->rebuildSubtree();
+    				$nextArray->items[] = $chainedAction->_actionDictionary;
+    			}
+    			$this->_actionDictionary->Next = $nextArray;
+    			break;
+    	}
+    }
+
+    /**
+     * Get Action dictionary
+     *
+     * @internal
+     * @return Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
+     */
+    public function getDictionary()
+    {
+    	return $this->_actionDictionary;
+    }
+}

+ 101 - 0
library/Zend/Pdf/Action/GoTo.php

@@ -0,0 +1,101 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * PDF 'Go to' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_GoTo extends Zend_Pdf_Action
+{
+	/**
+	 * Create new Zend_Pdf_Action_GoTo object using specified destination
+	 *
+	 * Object is created based on a provided dictionary. That allows to choose if it's
+	 * a direct or inderect object attached to some objects factory
+	 *
+	 * @param Zend_Pdf_Element|Zend_Pdf_Destination|string $destination
+	 * @param Zend_Pdf_ElementFactory $objectFactory
+	 * @return Zend_Pdf_Action_GoTo
+	 * @throws Zend_Pdf_Exception
+	 */
+	public static function create($destination, $objectFactory = null)
+    {
+    	if ($objectFactory === null) {
+    		$dictionary = new Zend_Pdf_Element_Dictionary();
+    	} else {
+    		$dictionary = $objectFactory->newObject(new Zend_Pdf_Element_Dictionary());
+    	}
+
+        if ($dictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$dictionary mast be a direct or an indirect dictionary object.');
+        }
+    	$dictionary->Type = new Zend_Pdf_Element_Name('Action');
+    	$dictionary->S    = new Zend_Pdf_Element_Name('GoTo');
+    	$dictionary->Next = null;
+
+    	if (is_string($destination)) {
+            // Named destination
+            $dictionary->D = new Zend_Pdf_Element_String($destination);
+    	} else if ($destination instanceof Zend_Pdf_Element_Array) {
+    		// DestinationArray
+            $dictionary->D = $destination;
+    	} else if ($destination instanceof Zend_Pdf_Destination) {
+    		$dictionary->D = $destination->getDestinationArray();
+    	} else {
+    		require_once 'Zend/Pdf/Exception.php';
+    		throw new Zend_Pdf_Exception('Wrong $destination parameter type');
+    	}
+
+    	return new Zend_Pdf_Action_GoTo($dictionary, null, new SplObjectStorage());
+    }
+
+	/**
+	 * Returns goto action destination
+	 * (Zend_Pdf_Element_Name or Zend_Pdf_Element_String for named destinations
+	 * or Zend_Pdf_Array for explicit destinations)
+	 *
+	 * @return Zend_Pdf_Destination|string
+	 */
+	public function getDestination()
+	{
+		$destination = $this->_actionDictionary->D;
+
+		if ($destination instanceof Zend_Pdf_Element_Name  ||  $destination instanceof Zend_Pdf_Element_String) {
+			return $destination->value;
+        }
+
+		return Zend_Pdf_Destination::load($this->_actionDictionary->D);
+	}
+}
+

+ 39 - 0
library/Zend/Pdf/Action/GoTo3DView.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Set the current view of a 3D annotation' action
+ * PDF 1.6+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_GoTo3DView extends Zend_Pdf_Action
+{
+}
+

+ 38 - 0
library/Zend/Pdf/Action/GoToE.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Go to a destination in an embedded file' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_GoToE extends Zend_Pdf_Action
+{
+}
+

+ 38 - 0
library/Zend/Pdf/Action/GoToR.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Go to a destination in another document' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_GoToR extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/Hide.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Set an annotation’s Hidden flag' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Hide extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/ImportData.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Import field values from a file' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_ImportData extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/JavaScript.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Execute a JavaScript script' action
+ * PDF 1.3+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_JavaScript extends Zend_Pdf_Action
+{
+}
+

+ 38 - 0
library/Zend/Pdf/Action/Launch.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Launch an application, usually to open a file' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Launch extends Zend_Pdf_Action
+{
+}
+

+ 38 - 0
library/Zend/Pdf/Action/Movie.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Play a movie' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Movie extends Zend_Pdf_Action
+{
+}

+ 39 - 0
library/Zend/Pdf/Action/Named.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Execute an action predefined by the viewer application' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Named extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/Rendition.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Controls the playing of multimedia content' action
+ * PDF 1.5+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Rendition extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/ResetForm.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Set fields to their default values' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_ResetForm extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/SetOCGState.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Set the states of optional content groups' action
+ * PDF 1.5+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_SetOCGState extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/Sound.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Play a sound' action representation class
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Sound extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/SubmitForm.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Send data to a uniform resource locator' action
+ * PDF 1.2+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_SubmitForm extends Zend_Pdf_Action
+{
+}
+

+ 38 - 0
library/Zend/Pdf/Action/Thread.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Begin reading an article thread' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Thread extends Zend_Pdf_Action
+{
+}
+

+ 39 - 0
library/Zend/Pdf/Action/Trans.php

@@ -0,0 +1,39 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Updates the display of a document, using a transition dictionary' action
+ * PDF 1.5+ feature
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Trans extends Zend_Pdf_Action
+{
+}
+

+ 37 - 0
library/Zend/Pdf/Action/URI.php

@@ -0,0 +1,37 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * PDF 'Resolve a uniform resource identifier' action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_URI extends Zend_Pdf_Action
+{
+}

+ 38 - 0
library/Zend/Pdf/Action/Unknown.php

@@ -0,0 +1,38 @@
+<?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-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+
+/**
+ * Unrecognized PDF action
+ *
+ * @package    Zend_Pdf
+ * @subpackage Actions
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Action_Unknown extends Zend_Pdf_Action
+{
+}
+

+ 195 - 0
library/Zend/Pdf/Destination.php

@@ -0,0 +1,195 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_ElementFactory */
+require_once 'Zend/Pdf/ElementFactory.php';
+
+/** Zend_Pdf_Page */
+require_once 'Zend/Pdf/Page.php';
+
+
+/**
+ * Abstract PDF explicit destination representation class
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+abstract class Zend_Pdf_Destination
+{
+	/**
+	 * Destination description array
+	 *
+	 * @var Zend_Pdf_Element_Array
+	 */
+	protected $_destinationArray;
+
+	/**
+	 * True if it's a remote destination
+	 *
+	 * @var boolean
+	 */
+	protected $_isRemote;
+
+	/**
+	 * Destination object constructor
+	 *
+	 * @param Zend_Pdf_Element $destinationArray
+	 * @throws Zend_Pdf_Exception
+	 */
+	public function __construct(Zend_Pdf_Element $destinationArray)
+	{
+        if ($destinationArray->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$destinationArray mast be direct or indirect array object.');
+        }
+
+        $this->_destinationArray = $destinationArray;
+
+        if (count($this->_destinationArray->items) == 0) {
+        	require_once 'Zend/Pdf/Exception.php';
+        	throw new Zend_Pdf_Exception('Destination array must contain a page reference.');
+        }
+        if (count($this->_destinationArray->items) == 1) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Destination array must contain a destination type name.');
+        }
+
+        switch ($this->_destinationArray->items[0]->getType()) {
+        	case Zend_Pdf_Element::TYPE_NUMERIC:
+        		$this->_isRemote = true;
+        		break;
+
+            case Zend_Pdf_Element::TYPE_DICTIONARY:
+            	$this->_isRemote = false;
+                break;
+
+            default:
+            	require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Destination target must be a page number or page dictionary object.');
+            	break;
+        }
+	}
+
+
+    public static function load(Zend_Pdf_Element $destinationArray)
+    {
+        if ($destinationArray->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('$destinationArray mast be direct or indirect array object.');
+        }
+        if (count($destinationArray->items) == 0) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Destination array must contain a page reference.');
+        }
+        if (count($destinationArray->items) == 1) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Destination array must contain a destination type name.');
+        }
+
+        switch ($destinationArray->items[1]->value) {
+        	case 'XYZ':
+        		require_once 'Zend/Pdf/Destination/Zoom.php';
+                return new Zend_Pdf_Destination_Zoom($destinationArray);
+        		break;
+
+            case 'Fit':
+                require_once 'Zend/Pdf/Destination/Fit.php';
+                return new Zend_Pdf_Destination_Fit($destinationArray);
+                break;
+
+            case 'FitH':
+                require_once 'Zend/Pdf/Destination/FitHorizontally.php';
+                return new Zend_Pdf_Destination_FitHorizontally($destinationArray);
+                break;
+
+            case 'FitV':
+                require_once 'Zend/Pdf/Destination/FitVertically.php';
+                return new Zend_Pdf_Destination_FitVertically($destinationArray);
+                break;
+
+            case 'FitR':
+                require_once 'Zend/Pdf/Destination/FitRectangle.php';
+                return new Zend_Pdf_Destination_FitRectangle($destinationArray);
+                break;
+
+            case 'FitB':
+                require_once 'Zend/Pdf/Destination/FitBoundingBox.php';
+                return new Zend_Pdf_Destination_FitBoundingBox($destinationArray);
+                break;
+
+            case 'FitBH':
+                require_once 'Zend/Pdf/Destination/FitBoundingBoxHorizontally.php';
+                return new Zend_Pdf_Destination_FitBoundingBoxHorizontally($destinationArray);
+                break;
+
+            case 'FitBV':
+                require_once 'Zend/Pdf/Destination/FitBoundingBoxVertically.php';
+                return new Zend_Pdf_Destination_FitBoundingBoxVertically($destinationArray);
+                break;
+
+            default:
+                require_once 'Zend/Pdf/Destination/Unknown.php';
+                return new Zend_Pdf_Destination_Unknown($destinationArray);
+                break;
+        }
+    }
+
+    /**
+     * Returns true if it's a remote destination
+     *
+     * @return boolean
+     */
+    public function isRemote()
+    {
+    	return $this->_isRemote;
+    }
+
+    /**
+     * Returns destination target
+     *
+     * Returns page number for remote destinations and
+     * page dictionary object reference otherwise
+     *
+     * @return integer|Zend_Pdf_Element_Dictionary
+     */
+    public function getTarget()
+    {
+    	if ($this->isRemote()) {
+            return $this->_destinationArray->items[0]->value;
+    	} else {
+    		return $this->_destinationArray->items[0];
+    	}
+    }
+
+    /**
+     * Get destination array object
+     *
+     * @internal
+     * @return Zend_Pdf_Element_Array|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
+     */
+    public function getDestinationArray()
+    {
+    	return $this->_destinationArray;
+    }
+}

+ 77 - 0
library/Zend/Pdf/Destination/Fit.php

@@ -0,0 +1,77 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /Fit]
+ *
+ * Display the page designated by page, with its contents magnified just enough
+ * to fit the entire page within the window both horizontally and vertically. If
+ * the required horizontal and vertical magnification factors are different, use
+ * the smaller of the two, centering the page within the window in the other
+ * dimension.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_Fit extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @return Zend_Pdf_Destination_Fit
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+        	if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+        		// Page destination entry is a page number or page dictionary object
+        		$destinationArray->items[] = $page;
+        	} else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+        	$destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('Fit');
+
+        return new Zend_Pdf_Destination_Fit($destinationArray);
+    }
+}

+ 77 - 0
library/Zend/Pdf/Destination/FitBoundingBox.php

@@ -0,0 +1,77 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitB]
+ *
+ * (PDF 1.1) Display the page designated by page, with its contents magnified
+ * just enough to fit its bounding box entirely within the window both horizontally
+ * and vertically. If the required horizontal and vertical magnification
+ * factors are different, use the smaller of the two, centering the bounding box
+ * within the window in the other dimension.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitBoundingBox extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @return Zend_Pdf_Destination_FitBoundingBox
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitB');
+
+        return new Zend_Pdf_Destination_FitBoundingBox($destinationArray);
+    }
+}

+ 100 - 0
library/Zend/Pdf/Destination/FitBoundingBoxHorizontally.php

@@ -0,0 +1,100 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitBH top]
+ *
+ * (PDF 1.1) Display the page designated by page, with the vertical coordinate
+ * top positioned at the top edge of the window and the contents of the page
+ * magnified just enough to fit the entire width of its bounding box within the
+ * window.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitBoundingBoxHorizontally extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @param float $top   Top edge of displayed page
+     * @return Zend_Pdf_Destination_FitBoundingBoxHorizontally
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page, $top)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitBH');
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($top);
+
+        return new Zend_Pdf_Destination_FitBoundingBoxHorizontally($destinationArray);
+    }
+
+    /**
+     * Get top edge of the displayed page
+     *
+     * @return float
+     */
+    public function getTopEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set top edge of the displayed page
+     *
+     * @param float $top
+     * @return Zend_Pdf_Action_FitBoundingBoxHorizontally
+     */
+    public function setTopEdge($top)
+    {
+        $this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($top);
+        return $this;
+    }
+}

+ 101 - 0
library/Zend/Pdf/Destination/FitBoundingBoxVertically.php

@@ -0,0 +1,101 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitBV left]
+ *
+ * (PDF 1.1) Display the page designated by page, with the horizontal coordinate
+ * left positioned at the left edge of the window and the contents of the page
+ * magnified just enough to fit the entire height of its bounding box within the
+ * window.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitBoundingBoxVertically extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @param float $left  Left edge of displayed page
+     * @return Zend_Pdf_Destination_FitBoundingBoxVertically
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page, $left)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitBV');
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($left);
+
+        return new Zend_Pdf_Destination_FitBoundingBoxVertically($destinationArray);
+    }
+
+    /**
+     * Get left edge of the displayed page
+     *
+     * @return float
+     */
+    public function getLeftEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set left edge of the displayed page
+     *
+     * @param float $left
+     * @return Zend_Pdf_Action_FitBoundingBoxVertically
+     */
+    public function setLeftEdge($left)
+    {
+        $this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($left);
+        return $this;
+    }
+
+}

+ 100 - 0
library/Zend/Pdf/Destination/FitHorizontally.php

@@ -0,0 +1,100 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitH top]
+ *
+ * Display the page designated by page, with the vertical coordinate top positioned
+ * at the top edge of the window and the contents of the page magnified
+ * just enough to fit the entire width of the page within the window.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitHorizontally extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @param float $top  Top edge of displayed page
+     * @return Zend_Pdf_Destination_FitHorizontally
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page, $top)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitH');
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($top);
+
+        return new Zend_Pdf_Destination_FitHorizontally($destinationArray);
+    }
+
+    /**
+     * Get top edge of the displayed page
+     *
+     * @return float
+     */
+    public function getTopEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set top edge of the displayed page
+     *
+     * @param float $top
+     * @return Zend_Pdf_Action_FitHorizontally
+     */
+    public function setTopEdge($top)
+    {
+        $this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($top);
+
+        return $this;
+    }
+}

+ 173 - 0
library/Zend/Pdf/Destination/FitRectangle.php

@@ -0,0 +1,173 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitR left bottom right top]
+ *
+ * Display the page designated by page, with its contents magnified just enough
+ * to fit the rectangle specified by the coordinates left, bottom, right, and top
+ * entirely within the window both horizontally and vertically. If the required
+ * horizontal and vertical magnification factors are different, use the smaller of
+ * the two, centering the rectangle within the window in the other dimension.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitRectangle extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @param float $left    Left edge of displayed page
+     * @param float $bottom  Bottom edge of displayed page
+     * @param float $right   Right edge of displayed page
+     * @param float $top     Top edge of displayed page
+     * @return Zend_Pdf_Destination_FitRectangle
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page, $left, $bottom, $right, $top)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitR');
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($left);
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($bottom);
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($right);
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($top);
+
+        return new Zend_Pdf_Destination_FitRectangle($destinationArray);
+    }
+
+    /**
+     * Get left edge of the displayed page
+     *
+     * @return float
+     */
+    public function getLeftEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set left edge of the displayed page
+     *
+     * @param float $left
+     * @return Zend_Pdf_Action_FitRectangle
+     */
+    public function setLeftEdge($left)
+    {
+        $this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($left);
+        return $this;
+    }
+
+    /**
+     * Get bottom edge of the displayed page
+     *
+     * @return float
+     */
+    public function getBottomEdge()
+    {
+        return $this->_destinationArray->items[3]->value;
+    }
+
+    /**
+     * Set bottom edge of the displayed page
+     *
+     * @param float $bottom
+     * @return Zend_Pdf_Action_FitRectangle
+     */
+    public function setBottomEdge($bottom)
+    {
+        $this->_destinationArray->items[3] = new Zend_Pdf_Element_Numeric($bottom);
+        return $this;
+    }
+
+    /**
+     * Get right edge of the displayed page
+     *
+     * @return float
+     */
+    public function getRightEdge()
+    {
+        return $this->_destinationArray->items[4]->value;
+    }
+
+    /**
+     * Set right edge of the displayed page
+     *
+     * @param float $right
+     * @return Zend_Pdf_Action_FitRectangle
+     */
+    public function setRightEdge($right)
+    {
+        $this->_destinationArray->items[4] = new Zend_Pdf_Element_Numeric($right);
+        return $this;
+    }
+
+    /**
+     * Get top edge of the displayed page
+     *
+     * @return float
+     */
+    public function getTopEdge()
+    {
+        return $this->_destinationArray->items[5]->value;
+    }
+
+    /**
+     * Set top edge of the displayed page
+     *
+     * @param float $top
+     * @return Zend_Pdf_Action_FitRectangle
+     */
+    public function setTopEdge($top)
+    {
+        $this->_destinationArray->items[5] = new Zend_Pdf_Element_Numeric($top);
+        return $this;
+    }
+}

+ 100 - 0
library/Zend/Pdf/Destination/FitVertically.php

@@ -0,0 +1,100 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /FitV left]
+ *
+ * Display the page designated by page, with the horizontal coordinate left positioned
+ * at the left edge of the window and the contents of the page magnified
+ * just enough to fit the entire height of the page within the window.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_FitVertically extends Zend_Pdf_Destination
+{
+    /**
+     * Create destination object
+     *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+     * @param float $left  Left edge of displayed page
+     * @return Zend_Pdf_Destination_FitVertically
+     * @throws Zend_Pdf_Exception
+     */
+    public static function create($page, $left)
+    {
+        $destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+        $destinationArray->items[] = new Zend_Pdf_Element_Name('FitV');
+        $destinationArray->items[] = new Zend_Pdf_Element_Numeric($left);
+
+        return new Zend_Pdf_Destination_FitVertically($destinationArray);
+    }
+
+    /**
+     * Get left edge of the displayed page
+     *
+     * @return float
+     */
+    public function getLeftEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set left edge of the displayed page
+     *
+     * @param float $left
+     * @return Zend_Pdf_Action_FitVertically
+     */
+    public function setLeftEdge($left)
+    {
+        $this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($left);
+
+        return $this;
+    }
+}

+ 37 - 0
library/Zend/Pdf/Destination/Unknown.php

@@ -0,0 +1,37 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Unrecognized destination representation class
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_Unknown extends Zend_Pdf_Destination
+{
+}

+ 179 - 0
library/Zend/Pdf/Destination/Zoom.php

@@ -0,0 +1,179 @@
+<?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 Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id$
+ */
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+
+/**
+ * Destination array: [page /XYZ left top zoom]
+ *
+ * Display the page designated by page, with the coordinates (left, top) positioned
+ * at the upper-left corner of the window and the contents of the page
+ * magnified by the factor zoom. A null value for any of the parameters left, top,
+ * or zoom specifies that the current value of that parameter is to be retained unchanged.
+ * A zoom value of 0 has the same meaning as a null value.
+ *
+ * @package    Zend_Pdf
+ * @subpackage Destination
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Destination_Zoom extends Zend_Pdf_Destination
+{
+	/**
+	 * Create destination object
+	 *
+     * @param Zend_Pdf_Page|Zend_Pdf_Element|integer $page  Page object,
+     *                                                      page number (integer or Zend_Pdf_Element_Numeric object) or
+     *                                                      page dictionary object
+	 * @param float $left  Left edge of displayed page
+	 * @param float $top   Top edge of displayed page
+	 * @param float $zoom  Zoom factor
+	 * @return Zend_Pdf_Destination_Zoom
+	 * @throws Zend_Pdf_Exception
+	 */
+    public static function create($page, $left = null, $top = null, $zoom = null)
+    {
+    	$destinationArray = new Zend_Pdf_Element_Array();
+
+        if ($page instanceof Zend_Pdf_Element) {
+            if ($page->getType() == Zend_Pdf_Element::TYPE_NUMERIC  ||  $page->getType() == Zend_Pdf_Element::TYPE_DICTIONARY) {
+                // Page destination entry is a page number or page dictionary object
+                $destinationArray->items[] = $page;
+            } else {
+                require_once 'Zend/Pdf/Exception.php';
+                throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+            }
+        } else if ($page instanceof Zend_Pdf_Page) {
+            $destinationArray->items[] = $page->getPageDictionary();
+        } else if (is_integer($page)) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($page);
+        } else {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Page entry must be a Zend_Pdf_Page object, page number or page dictionary reference.');
+        }
+
+    	$destinationArray->items[] = new Zend_Pdf_Element_Name('XYZ');
+
+    	if ($left === null) {
+    		$destinationArray->items[] = new Zend_Pdf_Element_Null();
+    	} else {
+    		$destinationArray->items[] = new Zend_Pdf_Element_Numeric($left);
+    	}
+
+        if ($top === null) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Null();
+        } else {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($top);
+        }
+
+        if ($zoom === null) {
+            $destinationArray->items[] = new Zend_Pdf_Element_Null();
+        } else {
+            $destinationArray->items[] = new Zend_Pdf_Element_Numeric($zoom);
+        }
+
+    	return new Zend_Pdf_Destination_Zoom($destinationArray);
+    }
+
+    /**
+     * Get left edge of the displayed page (null means viewer application 'current value')
+     *
+     * @return float
+     */
+    public function getLeftEdge()
+    {
+        return $this->_destinationArray->items[2]->value;
+    }
+
+    /**
+     * Set left edge of the displayed page (null means viewer application 'current value')
+     *
+     * @param float $left
+     * @return Zend_Pdf_Action_Zoom
+     */
+    public function setLeftEdge($left)
+    {
+    	if ($left === null) {
+    		$this->_destinationArray->items[2] = new Zend_Pdf_Element_Null();
+    	} else {
+    		$this->_destinationArray->items[2] = new Zend_Pdf_Element_Numeric($left);
+    	}
+
+        return $this;
+    }
+
+    /**
+     * Get top edge of the displayed page (null means viewer application 'current value')
+     *
+     * @return float
+     */
+    public function getTopEdge()
+    {
+        return $this->_destinationArray->items[3]->value;
+    }
+
+    /**
+     * Set top edge of the displayed page (null means viewer application 'current viewer')
+     *
+     * @param float $top
+     * @return Zend_Pdf_Action_Zoom
+     */
+    public function setTopEdge($top)
+    {
+        if ($top === null) {
+            $this->_destinationArray->items[3] = new Zend_Pdf_Element_Null();
+        } else {
+            $this->_destinationArray->items[3] = new Zend_Pdf_Element_Numeric($top);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get ZoomFactor of the displayed page (null or 0 means viewer application 'current value')
+     *
+     * @return float
+     */
+    public function getZoomFactor()
+    {
+        return $this->_destinationArray->items[4]->value;
+    }
+
+    /**
+     * Set ZoomFactor of the displayed page (null or 0 means viewer application 'current viewer')
+     *
+     * @param float $zoom
+     * @return Zend_Pdf_Action_Zoom
+     */
+    public function setZoomFactor($zoom)
+    {
+        if ($zoom === null) {
+            $this->_destinationArray->items[4] = new Zend_Pdf_Element_Null();
+        } else {
+        	$this->_destinationArray->items[4] = new Zend_Pdf_Element_Numeric($zoom);
+        }
+
+        return $this;
+    }
+}

+ 0 - 3
library/Zend/Pdf/Element.php

@@ -20,9 +20,6 @@
  */
 
 
-/** Zend_Pdf_Element */
-require_once 'Zend/Pdf/Element.php';
-
 /** Zend_Pdf_Element_Object */
 require_once 'Zend/Pdf/Element/Object.php';
 

+ 1 - 0
library/Zend/Pdf/Element/Numeric.php

@@ -51,6 +51,7 @@ class Zend_Pdf_Element_Numeric extends Zend_Pdf_Element
     public function __construct($val)
     {
         if ( !is_numeric($val) ) {
+        	require_once 'Zend/Pdf/Exception.php';
             throw new Zend_Pdf_Exception('Argument must be numeric');
         }
 

+ 3 - 2
library/Zend/Pdf/Page.php

@@ -122,9 +122,9 @@ class Zend_Pdf_Page
 
 
     /**
-     * Reference to the object with page dictionary.
+     * Page dictionary (refers to an inderect Zend_Pdf_Element_Dictionary object).
      *
-     * @var Zend_Pdf_Element_Reference
+     * @var Zend_Pdf_Element_Reference|Zend_Pdf_Element_Object
      */
     protected $_pageDictionary;
 
@@ -414,6 +414,7 @@ class Zend_Pdf_Page
     /**
      * Retrive PDF file reference to the page
      *
+     * @internal
      * @return Zend_Pdf_Element_Dictionary
      */
     public function getPageDictionary()

+ 22 - 2
library/Zend/Pdf/Parser.php

@@ -100,6 +100,13 @@ class Zend_Pdf_Parser
      */
     private $_trailer;
 
+    /**
+     * PDF version specified in the file header
+     *
+     * @var string
+     */
+    private $_pdfVersion;
+
 
     /**
      * Get length of source PDF
@@ -122,6 +129,16 @@ class Zend_Pdf_Parser
     }
 
     /**
+     * PDF version specified in the file header
+     *
+     * @return string
+     */
+    public function getPDFVersion()
+    {
+    	return $this->_pdfVersion;
+    }
+
+    /**
      * Load XReference table and referenced objects
      *
      * @param integer $offset
@@ -400,8 +417,10 @@ class Zend_Pdf_Parser
             throw new Zend_Pdf_Exception('File is not a PDF.');
         }
 
-        $pdfVersion = (float)substr($pdfVersionComment, 5);
-        if ($pdfVersion < 0.9 || $pdfVersion >= 1.61) {
+        $pdfVersion = substr($pdfVersionComment, 5);
+        if (version_compare($pdfVersion, '0.9',  '<')  ||
+            version_compare($pdfVersion, '1.61', '>=')
+           ) {
             /**
              * @todo
              * To support PDF versions 1.5 (Acrobat 6) and PDF version 1.7 (Acrobat 7)
@@ -410,6 +429,7 @@ class Zend_Pdf_Parser
              */
             throw new Zend_Pdf_Exception(sprintf('Unsupported PDF version. Zend_Pdf supports PDF 1.0-1.4. Current version - \'%f\'', $pdfVersion));
         }
+        $this->_pdfVersion = $pdfVersion;
 
         $this->_stringParser->offset = strrpos($this->_stringParser->data, '%%EOF');
         if ($this->_stringParser->offset === false ||

+ 387 - 0
tests/Zend/Pdf/ActionTest.php

@@ -0,0 +1,387 @@
+<?php
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/Action.php';
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/ElementFactory.php';
+
+/** Zend_Pdf */
+require_once 'Zend/Pdf.php';
+
+
+/** PHPUnit Test Case */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+class Zend_Pdf_ActionTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        date_default_timezone_set('GMT');
+    }
+
+	public function testLoad()
+    {
+    	$dictionary = new Zend_Pdf_Element_Dictionary();
+    	$dictionary->Type = new Zend_Pdf_Element_Name('Action');
+    	$dictionary->S    = new Zend_Pdf_Element_Name('GoTo');
+    	$dictionary->D    = new Zend_Pdf_Element_String('SomeNamedDestination');
+
+        $action2Dictionary = new Zend_Pdf_Element_Dictionary();
+        $action2Dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $action2Dictionary->S    = new Zend_Pdf_Element_Name('Thread');
+        $action2Dictionary->D    = new Zend_Pdf_Element_String('NamedDestination 2');
+        $action2Dictionary->Next = new Zend_Pdf_Element_Array();
+
+        $dictionary->Next = $action2Dictionary;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoTo');
+        $leafAction->D    = new Zend_Pdf_Element_String('NamedDestination 3');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoToR');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoToE');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Launch');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Thread');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('URI');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Sound');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Movie');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Hide');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Named');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('SubmitForm');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('ResetForm');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('ImportData');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('JavaScript');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('SetOCGState');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Rendition');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Trans');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoTo3DView');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $action = Zend_Pdf_Action::load($dictionary);
+
+        $this->assertEquals(20, count($action->getAllActions()));
+
+        $action->clean();
+    }
+
+    public function testExtract()
+    {
+        $dictionary = new Zend_Pdf_Element_Dictionary();
+        $dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $dictionary->S    = new Zend_Pdf_Element_Name('GoTo');
+        $dictionary->D    = new Zend_Pdf_Element_String('SomeNamedDestination');
+
+        $action2Dictionary = new Zend_Pdf_Element_Dictionary();
+        $action2Dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $action2Dictionary->S    = new Zend_Pdf_Element_Name('Thread');
+        $action2Dictionary->D    = new Zend_Pdf_Element_String('NamedDestination 2');
+        $action2Dictionary->Next = new Zend_Pdf_Element_Array();
+
+        $dictionary->Next = $action2Dictionary;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoTo');
+        $leafAction->D    = new Zend_Pdf_Element_String('NamedDestination 3');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoToR');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoToE');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Launch');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Thread');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('URI');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Sound');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Movie');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Hide');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Named');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('SubmitForm');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('ResetForm');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('ImportData');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('JavaScript');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('SetOCGState');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Rendition');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('Trans');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoTo3DView');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $action = Zend_Pdf_Action::load($dictionary);
+
+        foreach ($action->getAllActions() as $action) {
+            if ($action instanceof Zend_Pdf_Action_Thread) {
+                $root = $action->extract();
+            }
+        }
+        $this->assertTrue($root instanceof Zend_Pdf_Action_GoTo);
+        $this->assertEquals(18, count($root->getAllActions()));
+
+        foreach ($root->getAllActions() as $action) {
+            if ($action instanceof Zend_Pdf_Action_Goto) {
+                $root = $action->extract();
+            }
+        }
+        $this->assertTrue($root instanceof Zend_Pdf_Action_GoToR);
+        $this->assertEquals(16, count($root->getAllActions()));
+
+        $root->rebuildSubtree();
+
+        $this->assertEquals(
+            $root->getDictionary()->toString(),
+            '<</Type /Action /S /GoToR '
+            . "/Next [<</Type /Action /S /GoToE >> <</Type /Action /S /Launch >> <</Type /Action /S /URI >> <</Type /Action /S /Sound >> <</Type /Action /S /Movie >> \n"
+            .        "<</Type /Action /S /Hide >> <</Type /Action /S /Named >> <</Type /Action /S /SubmitForm >> <</Type /Action /S /ResetForm >> <</Type /Action /S /ImportData >> \n"
+            .        "<</Type /Action /S /JavaScript >> <</Type /Action /S /SetOCGState >> <</Type /Action /S /Rendition >> <</Type /Action /S /Trans >> \n"
+            .        '<</Type /Action /S /GoTo3DView >> ] >>');
+
+        $root->clean();
+    }
+
+    public function testAttach()
+    {
+        $action1Dictionary = new Zend_Pdf_Element_Dictionary();
+        $action1Dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $action1Dictionary->S    = new Zend_Pdf_Element_Name('GoTo');
+        $action1Dictionary->D    = new Zend_Pdf_Element_String('Destination 1');
+        $action1 = Zend_Pdf_Action::load($action1Dictionary);
+
+
+        $action2Dictionary = new Zend_Pdf_Element_Dictionary();
+        $action2Dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $action2Dictionary->S    = new Zend_Pdf_Element_Name('Thread');
+        $action2Dictionary->D    = new Zend_Pdf_Element_String('Destination 2');
+        $action2Dictionary->Next = new Zend_Pdf_Element_Array();
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoTo');
+        $leafAction->D    = new Zend_Pdf_Element_String('Destination 3');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $leafAction = new Zend_Pdf_Element_Dictionary();
+        $leafAction->Type = new Zend_Pdf_Element_Name('Action');
+        $leafAction->S    = new Zend_Pdf_Element_Name('GoToR');
+        $action2Dictionary->Next->items[] = $leafAction;
+
+        $action2 = Zend_Pdf_Action::load($action2Dictionary);
+
+        $action1->attach($action2);
+        $action1->rebuildSubtree();
+
+        $this->assertEquals(
+            $action1->getDictionary()->toString(),
+            '<</Type /Action /S /GoTo /D (Destination 1) '
+            . '/Next <</Type /Action /S /Thread /D (Destination 2) '
+            .         '/Next [<</Type /Action /S /GoTo /D (Destination 3) >> <</Type /Action /S /GoToR >> ] >> >>');
+
+        $action1->clean();
+    }
+
+    public function testCreate()
+    {
+    	$action1 = Zend_Pdf_Action_GoTo::create('SomeNamedDestination');
+    	$action1->attach(Zend_Pdf_Action_GoTo::create('AnotherNamedDestination'));
+
+    	$action1->rebuildSubtree();
+
+    	$this->assertEquals($action1->getDictionary()->toString(),
+    	                    '<</Type /Action /S /GoTo /D (SomeNamedDestination) /Next <</Type /Action /S /GoTo /D (AnotherNamedDestination) >> >>');
+
+    	$action1->clean();
+    }
+
+    public function testCreate1()
+    {
+    	$pdf = new Zend_Pdf();
+    	$page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+    	$page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+
+    	require_once 'Zend/Pdf/Destination/Fit.php';
+    	$destination = Zend_Pdf_Destination_Fit::create($page2);
+
+        $action = Zend_Pdf_Action_GoTo::create($destination);
+        $action->rebuildSubtree();
+
+        $this->assertEquals($action->getDictionary()->toString(),
+                            '<</Type /Action /S /GoTo /D [4 0 R /Fit ] >>');
+
+        $action->clean();
+    }
+
+    public function testGetDestination()
+    {
+        $dictionary = new Zend_Pdf_Element_Dictionary();
+        $dictionary->Type = new Zend_Pdf_Element_Name('Action');
+        $dictionary->S    = new Zend_Pdf_Element_Name('GoTo');
+        $dictionary->D    = new Zend_Pdf_Element_String('SomeNamedDestination');
+
+        $action = Zend_Pdf_Action::load($dictionary);
+
+        $this->assertEquals($action->getDestination(), 'SomeNamedDestination');
+
+        $action->clean();
+    }
+
+    public function testGetDestination2()
+    {
+        $pdf = new Zend_Pdf();
+        $page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+
+        require_once 'Zend/Pdf/Destination/Fit.php';
+        $destination = Zend_Pdf_Destination_Fit::create($page2);
+
+        $action = Zend_Pdf_Action_GoTo::create($destination);
+
+        $this->assertTrue($action->getDestination() == $destination);
+
+        $action->clean();
+    }
+}

+ 9 - 2
tests/Zend/Pdf/AllTests.php

@@ -5,9 +5,12 @@ if (!defined('PHPUnit_MAIN_METHOD')) {
 
 require_once dirname(__FILE__) . '/../../TestHelper.php';
 
-require_once 'Zend/Pdf/ProcessingTest.php';
+require_once 'Zend/Pdf/ActionTest.php';
+require_once 'Zend/Pdf/DestinationTest.php';
 require_once 'Zend/Pdf/DrawingTest.php';
 require_once 'Zend/Pdf/FactoryTest.php';
+require_once 'Zend/Pdf/NamedDestinationsTest.php';
+require_once 'Zend/Pdf/ProcessingTest.php';
 
 require_once 'Zend/Pdf/Element/AllTests.php';
 
@@ -22,8 +25,12 @@ class Zend_Pdf_AllTests
     {
         $suite = new PHPUnit_Framework_TestSuite('Zend Framework - Zend_Pdf');
 
-        $suite->addTestSuite('Zend_Pdf_ProcessingTest');
+        $suite->addTestSuite('Zend_Pdf_ActionTest');
+        $suite->addTestSuite('Zend_Pdf_DestinationTest');
         $suite->addTestSuite('Zend_Pdf_DrawingTest');
+        $suite->addTestSuite('Zend_Pdf_FactoryTest');
+        $suite->addTestSuite('Zend_Pdf_NamedDestinationsTest');
+        $suite->addTestSuite('Zend_Pdf_ProcessingTest');
 
         $suite->addTest(Zend_Pdf_Element_AllTests::suite());
 

+ 287 - 0
tests/Zend/Pdf/DestinationTest.php

@@ -0,0 +1,287 @@
+<?php
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+
+
+/** Zend_Pdf_Destination */
+require_once 'Zend/Pdf/Destination.php';
+
+/** Zend_Pdf_Action */
+require_once 'Zend/Pdf/ElementFactory.php';
+
+/** Zend_Pdf */
+require_once 'Zend/Pdf.php';
+
+
+/** PHPUnit Test Case */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+class Zend_Pdf_DestinationTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        date_default_timezone_set('GMT');
+    }
+
+	public function testLoad()
+    {
+        $pdf = new Zend_Pdf();
+        $page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+
+
+        // Zend_Pdf_Destination_Zoom
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('XYZ');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(1);    // zoom
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_Zoom);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /XYZ 0 842 1 ]');
+
+
+        // Zend_Pdf_Destination_Fit
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('Fit');
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_Fit);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /Fit ]');
+
+
+        // Zend_Pdf_Destination_FitHorizontally
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitH');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitHorizontally);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitH 842 ]');
+
+
+        // Zend_Pdf_Destination_FitVertically
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitV');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitVertically);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitV 0 ]');
+
+
+        // Zend_Pdf_Destination_FitRectangle
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitR');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(10);   // bottom
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(595);  // right
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitRectangle);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitR 0 10 595 842 ]');
+
+
+        // Zend_Pdf_Destination_FitBoundingBox
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitB');
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBox);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitB ]');
+
+
+        // Zend_Pdf_Destination_FitBoundingBoxHorizontally
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitBH');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBoxHorizontally);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitBH 842 ]');
+
+
+        // Zend_Pdf_Destination_FitBoundingBoxVertically
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitBV');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBoxVertically);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitBV 0 ]');
+    }
+
+    public function testGettersSetters()
+    {
+        $pdf = new Zend_Pdf();
+        $page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+
+
+        // Zend_Pdf_Destination_Zoom
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('XYZ');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(1);    // zoom
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getLeftEdge(), 0);
+        $destination->setLeftEdge(5);
+        $this->assertEquals($destination->getLeftEdge(), 5);
+
+        $this->assertEquals($destination->getTopEdge(), 842);
+        $destination->setTopEdge(825);
+        $this->assertEquals($destination->getTopEdge(), 825);
+
+        $this->assertEquals($destination->getZoomFactor(), 1);
+        $destination->setZoomFactor(0.5);
+        $this->assertEquals($destination->getZoomFactor(), 0.5);
+
+
+        // Zend_Pdf_Destination_FitHorizontally
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitH');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getTopEdge(), 842);
+        $destination->setTopEdge(825);
+        $this->assertEquals($destination->getTopEdge(), 825);
+
+
+        // Zend_Pdf_Destination_FitVertically
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitV');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getLeftEdge(), 0);
+        $destination->setLeftEdge(5);
+        $this->assertEquals($destination->getLeftEdge(), 5);
+
+
+        // Zend_Pdf_Destination_FitRectangle
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitR');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(10);   // bottom
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(595);  // right
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getLeftEdge(), 0);
+        $destination->setLeftEdge(5);
+        $this->assertEquals($destination->getLeftEdge(), 5);
+
+        $this->assertEquals($destination->getBottomEdge(), 10);
+        $destination->setBottomEdge(20);
+        $this->assertEquals($destination->getBottomEdge(), 20);
+
+        $this->assertEquals($destination->getRightEdge(), 595);
+        $destination->setRightEdge(590);
+        $this->assertEquals($destination->getRightEdge(), 590);
+
+        $this->assertEquals($destination->getTopEdge(), 842);
+        $destination->setTopEdge(825);
+        $this->assertEquals($destination->getTopEdge(), 825);
+
+
+        // Zend_Pdf_Destination_FitBoundingBoxHorizontally
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitBH');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(842);  // top
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getTopEdge(), 842);
+        $destination->setTopEdge(825);
+        $this->assertEquals($destination->getTopEdge(), 825);
+
+
+        // Zend_Pdf_Destination_FitBoundingBoxVertically
+        $destArray = new Zend_Pdf_Element_Array();
+        $destArray->items[] = $page2->getPageDictionary();
+        $destArray->items[] = new Zend_Pdf_Element_Name('FitBV');
+        $destArray->items[] = new Zend_Pdf_Element_Numeric(0);    // left
+
+        $destination = Zend_Pdf_Destination::load($destArray);
+
+        $this->assertEquals($destination->getLeftEdge(), 0);
+        $destination->setLeftEdge(5);
+        $this->assertEquals($destination->getLeftEdge(), 5);
+    }
+
+    public function testCreate()
+    {
+        $pdf = new Zend_Pdf();
+        $page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+
+        $destination = Zend_Pdf_Destination_Zoom::create($page2, 0, 842, 0.5);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_Zoom);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /XYZ 0 842 0.5 ]');
+
+        $destination = Zend_Pdf_Destination_Fit::create($page2->getPageDictionary());
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_Fit);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /Fit ]');
+
+        $destination = Zend_Pdf_Destination_FitHorizontally::create($page2->getPageDictionary(), 842);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitHorizontally);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitH 842 ]');
+
+        $destination = Zend_Pdf_Destination_FitVertically::create(2, 0);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitVertically);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[2 /FitV 0 ]');
+
+        $destination = Zend_Pdf_Destination_FitRectangle::create($page1, 0, 10, 595, 842);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitRectangle);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[3 0 R /FitR 0 10 595 842 ]');
+
+        $destination = Zend_Pdf_Destination_FitBoundingBox::create(1);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBox);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[1 /FitB ]');
+
+        $destination = Zend_Pdf_Destination_FitBoundingBoxHorizontally::create($page2, 842);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBoxHorizontally);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitBH 842 ]');
+
+        $destination = Zend_Pdf_Destination_FitBoundingBoxVertically::create($page2, 0);
+        $this->assertTrue($destination instanceof Zend_Pdf_Destination_FitBoundingBoxVertically);
+        $this->assertEquals($destination->getDestinationArray()->toString(), '[4 0 R /FitBV 0 ]');
+    }
+}

+ 6 - 1
tests/Zend/Pdf/DrawingTest.php

@@ -18,7 +18,12 @@ require_once 'PHPUnit/Framework/TestCase.php';
  */
 class Zend_Pdf_DrawingTest extends PHPUnit_Framework_TestCase
 {
-    public function testDrawing()
+    public function setUp()
+    {
+        date_default_timezone_set('GMT');
+    }
+
+	public function testDrawing()
     {
         $pdf = new Zend_Pdf();
 

+ 63 - 0
tests/Zend/Pdf/NamedDestinationsTest.php

@@ -0,0 +1,63 @@
+<?php
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+
+
+/** Zend_Pdf */
+require_once 'Zend/Pdf.php';
+
+
+/** PHPUnit Test Case */
+require_once 'PHPUnit/Framework/TestCase.php';
+
+
+/**
+ * @package    Zend_Pdf
+ * @subpackage UnitTests
+ */
+class Zend_Pdf_NamedDestinationsTest extends PHPUnit_Framework_TestCase
+{
+    public function setUp()
+    {
+        date_default_timezone_set('GMT');
+    }
+
+	public function testProcessing()
+    {
+        $pdf = new Zend_Pdf();
+        $page1 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page2 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
+        $page3 = $pdf->newPage(Zend_Pdf_Page::SIZE_A4); // not actually included into pages array
+
+        $pdf->pages[] = $page1;
+        $pdf->pages[] = $page2;
+
+
+        $this->assertTrue(count($pdf->getNamedActions()) == 0);
+        $this->assertTrue(count($pdf->getNamedDestinations()) == 0);
+
+        require_once 'Zend/Pdf/Destination/Fit.php';
+        $destination1 = Zend_Pdf_Destination_Fit::create($page1);
+        $destination2 = Zend_Pdf_Destination_Fit::create($page2);
+        $action1 = Zend_Pdf_Action_GoTo::create($destination1);
+
+        $pdf->setNamedAction('GoToPage1', $action1);
+        $this->assertTrue($pdf->getNamedAction('GoToPage1') === $action1);
+        $this->assertTrue($pdf->getNamedAction('GoToPage9') === null);
+
+        $pdf->setNamedDestination('Page2', $destination2);
+        $this->assertTrue($pdf->getNamedDestination('Page2') === $destination2);
+        $this->assertTrue($pdf->getNamedDestination('Page9') === null);
+
+        $pdf->setNamedDestination('Page1',   $destination1);
+        $pdf->setNamedDestination('Page1_1', Zend_Pdf_Destination_Fit::create(1));
+        $pdf->setNamedDestination('Page9_1', Zend_Pdf_Destination_Fit::create(9)); // will be egnored
+
+        $action3 = Zend_Pdf_Action_GoTo::create(Zend_Pdf_Destination_Fit::create($page3));
+        $pdf->setNamedAction('GoToPage3', $action3);
+
+        $this->assertTrue(strpos($pdf->render(), '[(GoToPage1) <</Type /Action /S /GoTo /D [3 0 R /Fit ] >> (Page1) [3 0 R /Fit ] (Page1_1) [1 /Fit ] (Page2) [4 0 R /Fit ] ]') !== false);
+    }
+}

+ 5 - 0
tests/Zend/Pdf/ProcessingTest.php

@@ -18,6 +18,11 @@ require_once 'PHPUnit/Framework/TestCase.php';
  */
 class Zend_Pdf_ProcessingTest extends PHPUnit_Framework_TestCase
 {
+	public function setUp()
+	{
+		date_default_timezone_set('GMT');
+	}
+
     public function testCreate()
     {
         $pdf = new Zend_Pdf();