Selaa lähdekoodia

Zend_Pdf: canvases support implementation update. Still needs content stream parser. [ZF-2139].

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@22909 44c647ce-9c0f-0410-b52a-842ac1e357ba
alexander 15 vuotta sitten
vanhempi
commit
d9d8d93c48

+ 52 - 2
library/Zend/Pdf/Canvas.php

@@ -34,6 +34,8 @@ class Zend_Pdf_Canvas extends Zend_Pdf_Canvas_Abstract
     /**
      * Canvas procedure sets.
      *
+     * Allowed values: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'.
+     *
      * @var array
      */
     protected $_procSet = array();
@@ -83,7 +85,8 @@ class Zend_Pdf_Canvas extends Zend_Pdf_Canvas_Abstract
      *
      * Method returns a name of the resource which can be used
      * as a resource reference within drawing instructions stream
-     * Allowed types: 'XObject' (image), 'Font', 'ExtGState'
+     * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
+     * 'XObject', 'Font', 'Properties'
      *
      * @param string $type
      * @param Zend_Pdf_Resource $resource
@@ -93,7 +96,6 @@ class Zend_Pdf_Canvas extends Zend_Pdf_Canvas_Abstract
     {
         // Check, that resource is already attached to resource set.
         $resObject = $resource->getResource();
-
         foreach ($this->_resources[$type] as $resName => $collectedResObject) {
             if ($collectedResObject === $resObject) {
                 return $resName;
@@ -111,6 +113,54 @@ class Zend_Pdf_Canvas extends Zend_Pdf_Canvas_Abstract
     }
 
     /**
+     * Returns dictionaries of used resources.
+     *
+     * Used for canvas implementations interoperability
+     *
+     * Structure of the returned array:
+     * array(
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   ...
+     *   'ProcSet' => array()
+     * )
+     *
+     * where ProcSet array is a list of used procedure sets names (strings).
+     * Allowed procedure set names: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'
+     *
+     * @internal
+     * @return array
+     */
+    public function getResources()
+    {
+        $this->_resources['ProcSet'] = array_keys($this->_procSet);
+        return $this->_resources;
+    }
+
+    /**
+     * Get drawing instructions stream
+     *
+     * It has to be returned as a PDF stream object to make it reusable.
+     *
+     * @internal
+     * @returns Zend_Pdf_Resource_ContentStream
+     */
+    public function getContents()
+    {
+        /** @todo implementation */
+    }
+
+    /**
      * Return the height of this page in points.
      *
      * @return float

+ 41 - 3
library/Zend/Pdf/Canvas/Abstract.php

@@ -92,7 +92,8 @@ abstract class Zend_Pdf_Canvas_Abstract implements Zend_Pdf_Canvas_Interface
      *
      * Method returns a name of the resource which can be used
      * as a resource reference within drawing instructions stream
-     * Allowed types: 'XObject' (image), 'Font', 'ExtGState'
+     * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
+     * 'XObject', 'Font', 'Properties'
      *
      * @param string $type
      * @param Zend_Pdf_Resource $resource
@@ -113,9 +114,46 @@ abstract class Zend_Pdf_Canvas_Abstract implements Zend_Pdf_Canvas_Interface
      * @param float $y2
      * @return Zend_Pdf_Canvas_Interface
      */
-    public function drawCanvas($canvas, $x1, $y1, $x2 = null, $y2 = null)
+    public function drawCanvas(Zend_Pdf_Canvas_Interface $canvas, $x1, $y1, $x2 = null, $y2 = null)
     {
-        /** @todo implementation */
+        $this->saveGS();
+
+        $this->translate($x1, $y1);
+
+        if ($x2 === null) {
+            $with = $canvas->getWidth();
+        } else {
+            $with = $x2 - $x1;
+        }
+        if ($y2 === null) {
+            $height = $canvas->getHeight();
+        } else {
+            $height = $y2 - $y1;
+        }
+
+        $this->clipRectangle(0, 0, $with, $height);
+
+        if ($x2 !== null  ||  $y2 !== null) {
+            // Drawn canvas has to be scaled.
+            if ($x2 !== null) {
+                $xScale = $with/$canvas->getWidth();
+            } else {
+                $xScale = 1;
+            }
+
+            if ($y2 !== null) {
+                $yScale = $height/$canvas->getHeight();
+            } else {
+                $yScale = 1;
+            }
+
+            $this->scale($xScale, $yScale);
+        }
+
+        $contentsToDraw = $canvas->_getContents();
+
+        $this->restoreGS();
+
         return $this;
     }
 

+ 41 - 1
library/Zend/Pdf/Canvas/Interface.php

@@ -30,6 +30,46 @@
  */
 interface Zend_Pdf_Canvas_Interface
 {
+    /**
+     * Returns dictionaries of used resources.
+     *
+     * Used for canvas implementations interoperability
+     *
+     * Structure of the returned array:
+     * array(
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   ...
+     *   'ProcSet' => array()
+     * )
+     *
+     * where ProcSet array is a list of used procedure sets names (strings).
+     * Allowed procedure set names: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'
+     *
+     * @internal
+     * @return array
+     */
+    public function getResources();
+
+    /**
+     * Get drawing instructions stream
+     *
+     * It has to be returned as a PDF stream object to make it reusable.
+     *
+     * @internal
+     * @returns Zend_Pdf_Resource_ContentStream
+     */
+    public function getContents();
 
     /**
      * Return canvas height.
@@ -58,7 +98,7 @@ interface Zend_Pdf_Canvas_Interface
      * @param float $y2
      * @return Zend_Pdf_Canvas_Interface
      */
-    public function drawCanvas($canvas, $x1, $y1, $x2 = null, $y2 = null);
+    public function drawCanvas(Zend_Pdf_Canvas_Interface $canvas, $x1, $y1, $x2 = null, $y2 = null);
 
     /**
      * Set fill color.

+ 1 - 1
library/Zend/Pdf/Element/Object/Stream.php

@@ -298,7 +298,7 @@ class Zend_Pdf_Element_Object_Stream extends Zend_Pdf_Element_Object
     {
         if ($property == 'dictionary') {
             /**
-             * If stream is note decoded yet, then store original decoding options (do it only once).
+             * If stream is not decoded yet, then store original decoding options (do it only once).
              */
             if (( !$this->_streamDecoded ) && ($this->_initialDictionaryData === null)) {
                 $this->_initialDictionaryData = $this->_extractDictionaryData();

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

@@ -29,6 +29,7 @@ require_once 'Zend/Pdf/Element/Name.php';
 require_once 'Zend/Pdf/Element/Null.php';
 require_once 'Zend/Pdf/Element/Numeric.php';
 require_once 'Zend/Pdf/Element/String.php';
+require_once 'Zend/Pdf/Resource/Unified.php';
 
 require_once 'Zend/Pdf/Canvas/Abstract.php';
 
@@ -209,7 +210,7 @@ class Zend_Pdf_Page extends Zend_Pdf_Canvas_Abstract
 
             }
         } else if ($param1 instanceof Zend_Pdf_Page && $param2 === null && $param3 === null) {
-            // Clone existing page.
+            // Duplicate existing page.
             // Let already existing content and resources to be shared between pages
             // We don't give existing content modification functionality, so we don't need "deep copy"
             $this->_objFactory = $param1->_objFactory;
@@ -322,7 +323,8 @@ class Zend_Pdf_Page extends Zend_Pdf_Canvas_Abstract
      *
      * Method returns a name of the resource which can be used
      * as a resource reference within drawing instructions stream
-     * Allowed types: 'XObject' (image), 'Font', 'ExtGState'
+     * Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
+     * 'XObject', 'Font', 'Properties'
      *
      * @param string $type
      * @param Zend_Pdf_Resource $resource
@@ -383,6 +385,72 @@ class Zend_Pdf_Page extends Zend_Pdf_Canvas_Abstract
     }
 
     /**
+     * Returns dictionaries of used resources.
+     *
+     * Used for canvas implementations interoperability
+     *
+     * Structure of the returned array:
+     * array(
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   <resTypeName> => array(
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      <resName> => <Zend_Pdf_Resource object>,
+     *                      ...
+     *                    ),
+     *   ...
+     *   'ProcSet' => array()
+     * )
+     *
+     * where ProcSet array is a list of used procedure sets names (strings).
+     * Allowed procedure set names: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'
+     *
+     * @internal
+     * @return array
+     */
+    public function getResources()
+    {
+        $resources = array();
+        $resDictionary = $this->_dictionary->Resources;
+
+        foreach ($resDictionary->getKeys() as $resType) {
+            $resources[$resType] = array();
+
+            if ($resType == 'ProcSet') {
+                foreach ($resDictionary->ProcSet->items as $procSetEntry) {
+                    $resources[$resType][] = $procSetEntry->value;
+                }
+            } else {
+                $resMap = $resDictionary->$resType;
+
+                foreach ($resMap->getKeys() as $resId) {
+                    $resources[$resType][$resId] =new Zend_Pdf_Resource_Unified($resMap->$resId);
+                }
+            }
+        }
+
+        return $resources;
+    }
+
+    /**
+     * Get drawing instructions stream
+     *
+     * It has to be returned as a PDF stream object to make it reusable.
+     *
+     * @internal
+     * @returns Zend_Pdf_Resource_ContentStream
+     */
+    public function getContents()
+    {
+        /** @todo implementation */
+    }
+
+    /**
      * Return the height of this page in points.
      *
      * @return float

+ 36 - 32
library/Zend/Pdf/Resource.php

@@ -89,28 +89,30 @@ abstract class Zend_Pdf_Resource
      */
     public function __clone()
     {
-        $factory = Zend_Pdf_ElementFactory::createFactory(1);
-        $processed = array();
+        /** @todo implementation*/
 
-        // Clone dictionary object.
-        // Do it explicitly to prevent sharing page attributes between different
-        // results of clonePage() operation (other resources are still shared)
-        $dictionary = new Zend_Pdf_Element_Dictionary();
-        foreach ($this->_pageDictionary->getKeys() as $key) {
-            $dictionary->$key = $this->_pageDictionary->$key->makeClone($factory->getFactory(),
-                                                                        $processed,
-                                                                        Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
-        }
-
-        $this->_pageDictionary = $factory->newObject($dictionary);
-        $this->_objectFactory  = $factory;
-        $this->_attached       = false;
-        $this->_style          = null;
-        $this->_font           = null;
+//        $factory = Zend_Pdf_ElementFactory::createFactory(1);
+//        $processed = array();
+//
+//        // Clone dictionary object.
+//        // Do it explicitly to prevent sharing resource attributes between different
+//        // results of clone operation (other resources are still shared)
+//        $dictionary = new Zend_Pdf_Element_Dictionary();
+//        foreach ($this->_pageDictionary->getKeys() as $key) {
+//         $dictionary->$key = $this->_pageDictionary->$key->makeClone($factory->getFactory(),
+//                                                                     $processed,
+//                                                                     Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
+//        }
+//
+//        $this->_pageDictionary = $factory->newObject($dictionary);
+//        $this->_objectFactory  = $factory;
+//        $this->_attached       = false;
+//        $this->_style          = null;
+//        $this->_font           = null;
     }
 
     /**
-     * Clone page, extract it and dependent objects from the current document,
+     * Clone resource, extract it and dependent objects from the current document,
      * so it can be used within other docs.
      *
      * @internal
@@ -118,22 +120,24 @@ abstract class Zend_Pdf_Resource
      * @param array $processed
      * @return Zend_Pdf_Page
      */
-    public function clonePage($factory, &$processed)
+    public function cloneResource($factory, &$processed)
     {
-        // Clone dictionary object.
-        // Do it explicitly to prevent sharing page attributes between different
-        // results of clonePage() operation (other resources are still shared)
-        $dictionary = new Zend_Pdf_Element_Dictionary();
-        foreach ($this->_pageDictionary->getKeys() as $key) {
-            $dictionary->$key = $this->_pageDictionary->$key->makeClone($factory->getFactory(),
-                                                                        $processed,
-                                                                        Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
-        }
-
-        $clonedPage = new Zend_Pdf_Page($factory->newObject($dictionary), $factory);
-        $clonedPage->_attached = false;
+        /** @todo implementation*/
 
-        return $clonedPage;
+//        // Clone dictionary object.
+//        // Do it explicitly to prevent sharing page attributes between different
+//        // results of clonePage() operation (other resources are still shared)
+//        $dictionary = new Zend_Pdf_Element_Dictionary();
+//        foreach ($this->_pageDictionary->getKeys() as $key) {
+//            $dictionary->$key = $this->_pageDictionary->$key->makeClone($factory->getFactory(),
+//                                                                        $processed,
+//                                                                        Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES);
+//        }
+//
+//        $clonedPage = new Zend_Pdf_Page($factory->newObject($dictionary), $factory);
+//        $clonedPage->_attached = false;
+//
+//        return $clonedPage;
     }
 
     /**

+ 114 - 0
library/Zend/Pdf/Resource/ContentStream.php

@@ -0,0 +1,114 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Pdf
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Image.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+
+/** Internally used classes */
+require_once 'Zend/Pdf/Element/Object.php';
+require_once 'Zend/Pdf/Element/Dictionary.php';
+require_once 'Zend/Pdf/Element/Name.php';
+require_once 'Zend/Pdf/Element/Numeric.php';
+
+
+/** Zend_Pdf_Resource */
+require_once 'Zend/Pdf/Resource.php';
+
+
+/**
+ * Content stream (drawing instructions container)
+ *
+ * @package    Zend_Pdf
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Resource_ContentStream extends Zend_Pdf_Resource
+{
+    /**
+     * Buffered content
+     *
+     * @var string
+     */
+    protected $_bufferedContent = '';
+
+    /**
+     * Object constructor.
+     *
+     * @param Zend_Pdf_Element_Object_Stream|string $contentStreamObject
+     * @throws Zend_Pdf_Exception
+     */
+    public function __construct($contentStreamObject = '')
+    {
+        if ($contentStreamObject !== null &&
+            !$contentStreamObject instanceof Zend_Pdf_Element_Object_Stream &&
+            !is_string($contentStreamObject)
+        ) {
+            require_once 'Zend/Pdf/Exception.php';
+            throw new Zend_Pdf_Exception('Content stream parameter must be a string or stream object');
+        }
+
+        parent::__construct($contentStreamObject);
+    }
+
+    /**
+     * Appends instructions to the end of the content stream
+     *
+     * @param string $instructions
+     * @return Zend_Pdf_Resource_ContentStream
+     */
+    public function addInstructions($instructions)
+    {
+        $this->_bufferedContent .= $instructions;
+        return $this;
+    }
+
+    /**
+     * Get current stream content
+     *
+     * @return string
+     */
+    public function getInstructions()
+    {
+        $this->flush();
+        return $this->_resource->value;
+    }
+
+    /**
+     * Clear stream content.
+     *
+     * @return Zend_Pdf_Resource_ContentStream
+     */
+    public function clear()
+    {
+        $this->_resource->value = '';
+        $this->_bufferedContent = '';
+        return $this;
+    }
+
+    /**
+     * Flush buffered content
+     */
+    public function flush()
+    {
+        $this->_resource->value .= $this->_bufferedContent;
+        $this->_bufferedContent = '';
+
+        return $this;
+    }
+}

+ 1 - 1
library/Zend/Pdf/Resource/GraphicsState.php

@@ -47,7 +47,7 @@ class Zend_Pdf_Resource_GraphicsState extends Zend_Pdf_Resource
     /**
      * Object constructor.
      *
-     * @param Zend_Pdf_Element_Object
+     * @param Zend_Pdf_Element_Object $extGStateObject
      * @throws Zend_Pdf_Exception
      */
     public function __construct(Zend_Pdf_Element_Object $extGStateObject = null)

+ 38 - 0
library/Zend/Pdf/Resource/Unified.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
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: Image.php 20096 2010-01-06 02:05:09Z bkarwin $
+ */
+
+
+/** Zend_Pdf_Resource */
+require_once 'Zend/Pdf/Resource.php';
+
+/**
+ * Unified resource.
+ *
+ * Class is used to represent any resource when resource type not actually important.
+ *
+ * @package    Zend_Pdf
+ * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Pdf_Resource_Unified extends Zend_Pdf_Resource
+{
+}
+