diff -r 5b37998e522e -r 162c1de6545a web/lib/Zend/Pdf/Outline/Loaded.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/Zend/Pdf/Outline/Loaded.php Fri Mar 11 15:05:35 2011 +0100 @@ -0,0 +1,460 @@ +_outlineDictionary->Title === null) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outline dictionary Title entry is required.'); + } + return $this->_outlineDictionary->Title->value; + } + + /** + * Set outline title + * + * @param string $title + * @return Zend_Pdf_Outline + */ + public function setTitle($title) + { + $this->_outlineDictionary->Title->touch(); + $this->_outlineDictionary->Title = new Zend_Pdf_Element_String($title); + return $this; + } + + /** + * Sets 'isOpen' outline flag + * + * @param boolean $isOpen + * @return Zend_Pdf_Outline + */ + public function setIsOpen($isOpen) + { + parent::setIsOpen($isOpen); + + if ($this->_outlineDictionary->Count === null) { + // Do Nothing. + return this; + } + + $childrenCount = $this->_outlineDictionary->Count->value; + $isOpenCurrentState = ($childrenCount > 0); + if ($isOpen != $isOpenCurrentState) { + $this->_outlineDictionary->Count->touch(); + $this->_outlineDictionary->Count->value = ($isOpen? 1 : -1)*abs($childrenCount); + } + + return $this; + } + + /** + * Returns true if outline item is displayed in italic + * + * @return boolean + */ + public function isItalic() + { + if ($this->_outlineDictionary->F === null) { + return false; + } + return $this->_outlineDictionary->F->value & 1; + } + + /** + * Sets 'isItalic' outline flag + * + * @param boolean $isItalic + * @return Zend_Pdf_Outline + */ + public function setIsItalic($isItalic) + { + if ($this->_outlineDictionary->F === null) { + $this->_outlineDictionary->touch(); + $this->_outlineDictionary->F = new Zend_Pdf_Element_Numeric($isItalic? 1 : 0); + } else { + $this->_outlineDictionary->F->touch(); + if ($isItalic) { + $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | 1; + } else { + $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | ~1; + } + } + return $this; + } + + /** + * Returns true if outline item is displayed in bold + * + * @return boolean + */ + public function isBold() + { + if ($this->_outlineDictionary->F === null) { + return false; + } + return $this->_outlineDictionary->F->value & 2; + } + + /** + * Sets 'isBold' outline flag + * + * @param boolean $isBold + * @return Zend_Pdf_Outline + */ + public function setIsBold($isBold) + { + if ($this->_outlineDictionary->F === null) { + $this->_outlineDictionary->touch(); + $this->_outlineDictionary->F = new Zend_Pdf_Element_Numeric($isBold? 2 : 0); + } else { + $this->_outlineDictionary->F->touch(); + if ($isBold) { + $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | 2; + } else { + $this->_outlineDictionary->F->value = $this->_outlineDictionary->F->value | ~2; + } + } + return $this; + } + + + /** + * Get outline text color. + * + * @return Zend_Pdf_Color_Rgb + */ + public function getColor() + { + if ($this->_outlineDictionary->C === null) { + return null; + } + + $components = $this->_outlineDictionary->C->items; + + require_once 'Zend/Pdf/Color/Rgb.php'; + return new Zend_Pdf_Color_Rgb($components[0], $components[1], $components[2]); + } + + /** + * Set outline text color. + * (null means default color which is black) + * + * @param Zend_Pdf_Color_Rgb $color + * @return Zend_Pdf_Outline + */ + public function setColor(Zend_Pdf_Color_Rgb $color) + { + $this->_outlineDictionary->touch(); + + if ($color === null) { + $this->_outlineDictionary->C = null; + } else { + $components = $color->getComponents(); + $colorComponentElements = array(new Zend_Pdf_Element_Numeric($components[0]), + new Zend_Pdf_Element_Numeric($components[1]), + new Zend_Pdf_Element_Numeric($components[2])); + $this->_outlineDictionary->C = new Zend_Pdf_Element_Array($colorComponentElements); + } + + return $this; + } + + /** + * Get outline target. + * + * @return Zend_Pdf_Target + * @throws Zend_Pdf_Exception + */ + public function getTarget() + { + if ($this->_outlineDictionary->Dest !== null) { + if ($this->_outlineDictionary->A !== null) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outline dictionary may contain Dest or A entry, but not both.'); + } + + require_once 'Zend/Pdf/Destination.php'; + return Zend_Pdf_Destination::load($this->_outlineDictionary->Dest); + } else if ($this->_outlineDictionary->A !== null) { + require_once 'Zend/Pdf/Action.php'; + return Zend_Pdf_Action::load($this->_outlineDictionary->A); + } + + return null; + } + + /** + * Set outline target. + * Null means no target + * + * @param Zend_Pdf_Target|string $target + * @return Zend_Pdf_Outline + * @throws Zend_Pdf_Exception + */ + public function setTarget($target = null) + { + $this->_outlineDictionary->touch(); + + if (is_string($target)) { + require_once 'Zend/Pdf/Destination/Named.php'; + $target = Zend_Pdf_Destination_Named::create($target); + } + + if ($target === null) { + $this->_outlineDictionary->Dest = null; + $this->_outlineDictionary->A = null; + } else if ($target instanceof Zend_Pdf_Destination) { + $this->_outlineDictionary->Dest = $target->getResource(); + $this->_outlineDictionary->A = null; + } else if ($target instanceof Zend_Pdf_Action) { + $this->_outlineDictionary->Dest = null; + $this->_outlineDictionary->A = $target->getResource(); + } else { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination or Zend_Pdf_Action object or string'); + } + + return $this; + } + + /** + * Set outline options + * + * @param array $options + * @return Zend_Pdf_Actions_Traceable + * @throws Zend_Pdf_Exception + */ + public function setOptions(array $options) + { + parent::setOptions($options); + + return $this; + } + + + + /** + * Create PDF outline object using specified dictionary + * + * @internal + * @param Zend_Pdf_Element $dictionary (It's actually Dictionary or Dictionary Object or Reference to a Dictionary Object) + * @param Zend_Pdf_Action $parentAction + * @param SplObjectStorage $processedOutlines List of already processed Outline dictionaries, + * used to avoid cyclic references + * @return Zend_Pdf_Action + * @throws Zend_Pdf_Exception + */ + public function __construct(Zend_Pdf_Element $dictionary, SplObjectStorage $processedDictionaries = null) + { + if ($dictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('$dictionary mast be an indirect dictionary object.'); + } + + if ($processedDictionaries === null) { + $processedDictionaries = new SplObjectStorage(); + } + $processedDictionaries->attach($dictionary); + + $this->_outlineDictionary = $dictionary; + + if ($dictionary->Count !== null) { + if ($dictionary->Count->getType() != Zend_Pdf_Element::TYPE_NUMERIC) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outline dictionary Count entry must be a numeric element.'); + } + + $childOutlinesCount = $dictionary->Count->value; + if ($childOutlinesCount > 0) { + $this->_open = true; + } + $childOutlinesCount = abs($childOutlinesCount); + + $childDictionary = $dictionary->First; + + $children = new SplObjectStorage(); + while ($childDictionary !== null) { + // Check children structure for cyclic references + if ($children->contains($childDictionary)) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outline childs load error.'); + } + + if (!$processedDictionaries->contains($childDictionary)) { + $this->childOutlines[] = new Zend_Pdf_Outline_Loaded($childDictionary, $processedDictionaries); + } + + $childDictionary = $childDictionary->Next; + } + + $this->_originalChildOutlines = $this->childOutlines; + } + } + + /** + * Dump Outline and its child outlines into PDF structures + * + * Returns dictionary indirect object or reference + * + * @internal + * @param Zend_Pdf_ElementFactory $factory object factory for newly created indirect objects + * @param boolean $updateNavigation Update navigation flag + * @param Zend_Pdf_Element $parent Parent outline dictionary reference + * @param Zend_Pdf_Element $prev Previous outline dictionary reference + * @param SplObjectStorage $processedOutlines List of already processed outlines + * @return Zend_Pdf_Element + * @throws Zend_Pdf_Exception + */ + public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory, + $updateNavigation, + Zend_Pdf_Element $parent, + Zend_Pdf_Element $prev = null, + SplObjectStorage $processedOutlines = null) + { + if ($processedOutlines === null) { + $processedOutlines = new SplObjectStorage(); + } + $processedOutlines->attach($this); + + if ($updateNavigation) { + $this->_outlineDictionary->touch(); + + $this->_outlineDictionary->Parent = $parent; + $this->_outlineDictionary->Prev = $prev; + $this->_outlineDictionary->Next = null; + } + + $updateChildNavigation = false; + if (count($this->_originalChildOutlines) != count($this->childOutlines)) { + // If original and current children arrays have different size then children list was updated + $updateChildNavigation = true; + } else if ( !(array_keys($this->_originalChildOutlines) === array_keys($this->childOutlines)) ) { + // If original and current children arrays have different keys (with a glance to an order) then children list was updated + $updateChildNavigation = true; + } else { + foreach ($this->childOutlines as $key => $childOutline) { + if ($this->_originalChildOutlines[$key] !== $childOutline) { + $updateChildNavigation = true; + break; + } + } + } + + $lastChild = null; + if ($updateChildNavigation) { + $this->_outlineDictionary->touch(); + $this->_outlineDictionary->First = null; + + foreach ($this->childOutlines as $childOutline) { + if ($processedOutlines->contains($childOutline)) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.'); + } + + if ($lastChild === null) { + // First pass. Update Outlines dictionary First entry using corresponding value + $lastChild = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, null, $processedOutlines); + $this->_outlineDictionary->First = $lastChild; + } else { + // Update previous outline dictionary Next entry (Prev is updated within dumpOutline() method) + $childOutlineDictionary = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, $lastChild, $processedOutlines); + $lastChild->Next = $childOutlineDictionary; + $lastChild = $childOutlineDictionary; + } + } + + $this->_outlineDictionary->Last = $lastChild; + + if (count($this->childOutlines) != 0) { + $this->_outlineDictionary->Count = new Zend_Pdf_Element_Numeric(($this->isOpen()? 1 : -1)*count($this->childOutlines)); + } else { + $this->_outlineDictionary->Count = null; + } + } else { + foreach ($this->childOutlines as $childOutline) { + if ($processedOutlines->contains($childOutline)) { + require_once 'Zend/Pdf/Exception.php'; + throw new Zend_Pdf_Exception('Outlines cyclyc reference is detected.'); + } + $lastChild = $childOutline->dumpOutline($factory, $updateChildNavigation, $this->_outlineDictionary, $lastChild, $processedOutlines); + } + } + + return $this->_outlineDictionary; + } + + public function dump($level = 0) + { + printf(":%3d:%s:%s:%s%s :\n", count($this->childOutlines),$this->isItalic()? 'i':' ', $this->isBold()? 'b':' ', str_pad('', 4*$level), $this->getTitle()); + + if ($this->isOpen() || true) { + foreach ($this->childOutlines as $child) { + $child->dump($level + 1); + } + } + } +}