Initial commit.

This commit is contained in:
Jesper Ek
2014-01-02 15:06:06 +01:00
commit a7748612ee
141 changed files with 30906 additions and 0 deletions

83
INSTALL.txt Normal file
View File

@ -0,0 +1,83 @@
INSTALLATION
------------
Zend Framework requires no special installation steps. Simply download the framework,
extract it to the folder you would like to keep it in, and add the library directory
to your PHP include_path. To use components in the extras library, add the extras/library
directory to your PHP include_path, as well.
If you would like to use Zend_Tool, simply add bin/zf.bat (for Windows) or
bin/zf.sh (for anything else) to your system executable path.
SYSTEM REQUIREMENTS
-------------------
Zend Framework requires PHP 5.2.11 or later. Please see the system requirements
appendix for more detailed information:
http://framework.zend.com/manual/en/requirements.html
DEVELOPMENT VERSIONS
--------------------
If you would like to preview enhancements or bug fixes that have not yet been
released, you can obtain the current development version of Zend Framework using one
of the following methods:
* Download the latest nightly snapshot. For those who care to brave the cutting
(often bleeding) edge, the nightly snapshots represent the latest single-
download development version of Zend Framework development. Snapshots are bundled
with documentation in English only or in all available languages. If you anticipate
updating to the latest development version of Zend Framework often, consider using
Subversion as described below.
http://framework.zend.com/download/snapshot
* Using a Subversion (SVN) client. Zend Framework is open source software, and
the Subversion repository used for its development is publicly available. Consider
using SVN to get Zend Framework if you already use SVN for your application
development, want to contribute back to the framework, or need to upgrade your
framework version very often.
Exporting is useful if you want to get a particular framework revision without the
.svn directories as created in a working copy.
Checking out a working copy is necessary if you would like to directly contribute
to Zend Framework; a working copy can be updated any time with svn update.
An externals definition is highly convenient for developers already using SVN to
manage their application working copies.
The URL for the trunk of the Zend Framework SVN repository is:
http://framework.zend.com/svn/framework/trunk
For more information about Subversion, please see the official website:
http://subversion.tigris.org
CONFIGURING THE INCLUDE PATH
----------------------------
Once you have a copy of Zend Framework available, your application will need to
access the framework classes. Though there are several ways to achieve this, your
PHP include_path needs to contain the path to the Zend Framework classes under the
/library directory in this distribution. You can find out more about the PHP
include_path configuration directive here:
http://www.php.net/manual/en/ini.core.php#ini.include-path
Instructions on how to change PHP configuration directives can be found here:
http://www.php.net/manual/en/configuration.changes.php
GETTING STARTED
---------------
A great place to get up-to-speed quickly is the Zend Framework QuickStart:
http://framework.zend.com/docs/quickstart
The QuickStart covers some of the most commonly used components of ZF. Since
Zend Framework is designed with a use-at-will architecture and components are
loosely coupled, you can select and use only those components that are needed for
your project.

27
LICENSE.txt Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2005-2012, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

22
README.md Normal file
View File

@ -0,0 +1,22 @@
Zend Framework 1 for Composer
=============================
This package is a part of the Zend Framework 1. Each component was separated and put into its own composer package. Some modifications were made for improved [Composer](http://getcomposer.org/) integration. This package can also be found at [Packagist](http://packagist.org/packages/zf1).
## Why?
**Size!** Zend Framework is very large and contains a huge amount of files (over 72000 files in the main repository!). If you're only using a part of the framework, using the separated packages will greatly reduce the amount of files. This will make setup faster and easier on your disks.
**Autoloading!** Explicit `require_once` calls in the source code has been commented out to rely on composer autoloading, this reduces the number of included files to a minimum.
**Migration!** Zend Framework 2 has been around for a while now, and migrating all your projects takes a lot of time. Using these packages makes it easier to migrate each component separately. Also, some packages doesn't exist in zf2 (such as the zend-search-lucene), now you can continue using that package without requiring the entire framework.
If you're using major parts of the framework, I would recommend checking out the [zendframework1 package](https://github.com/bombayworks/zendframework1), which contains the entire framework optimized for composer usage.
## How to use
Add `"zf1/zend-pdf": "~1.12"` to the require section of your composer.json, include the composer autoloader and you're good to go.
## Broken dependencies?
Dependencies have been set automatically based on the [requirements from the zend framework manual](http://framework.zend.com/manual/1.12/en/requirements.introduction.html), if you find any broken dependencies please submit an issue.

160
README.txt Normal file
View File

@ -0,0 +1,160 @@
Welcome to the Zend Framework 1.12 Release!
RELEASE INFORMATION
---------------
Zend Framework 1.12.3 Release ([INSERT REV NUM HERE]).
Released on March 13, 2013
IMPORTANT FIXES FOR 1.12.3
--------------------------
This release incorporates is primarily aimed to update
Zend_Service_Twitter to the Twitter v1.1 API:
- http://framework.zend.com/issues/browse/ZF-12530
Because the Twitter v1.1 API is not backwards compatible with v1.0, the
API for Zend_Service_Twitter has been changed; if you have been using it
previously, you will need to update your code accordingly. Both the
end-user and API documentation have been updated to reflect the changes.
NEW FEATURES
============
Zend_Loader changes
----
A number of autoloaders and autoloader facilities were back ported from
ZF2 to provide performant alternatives to those already available in the
1.X releases. These include: Zend_Loader_StandardAutoloader, which
improves on Zend_Loader_Autoloader by allowing the ability to specify a
specific path to associate with a vendor prefix or namespace;
Zend_Loader_ClassMapAutoloader, which provides the ability to use lookup
tables for autoloading (which are typically the fastest possible way to
autoload); and Zend_Loader_AutoloaderFactory, which can both create and
update autoloaders for you, as well as register them with
spl_autoload_register().
The Zend_Loader changes were back ported from ZF2 by Matthew Weier
OPhinney
Zend_EventManager
----
Zend_EventManager is a component that allows you to attach and detach
listeners to named events, both on a per-instance basis as well as via
shared collections; trigger events; and interrupt execution of
listeners.
Zend_EventManager was back ported from ZF2 by Matthew Weier OPhinney
Zend_Http_UserAgent_Features_Adapter_Browscap
----
This class provides a features adapter that calls get_browser() in order
to discover mobile device capabilities to inject into UserAgent device
instances.
Browscap (http://browsers.garykeith.com/) is an open project dedicated
to collecting an disseminating a “database” of browser capabilities. PHP
has built-in support for using these files via the get_browser()
function. This function requires that your php.ini provides a browscap
entry pointing to the PHP-specific php_browscap.ini file which is
available at http://browsers.garykeith.com/stream.asp?PHP_BrowsCapINI.
Zend_Http_UserAgent_Features_Adapter_Browscap was created by Matthew
Weier OPhinney
Zend_Mobile_Push
----
Zend_Mobile_Push is a component for implementing push notifications for
the 3 major push notification platforms (Apple (Apns), Google (C2dm) and
Microsoft (Mpns).
Zend_Mobile_Push was contributed by Mike Willbanks.
Zend_Gdata_Analytics
----
Zend_Gdata_Analytics is an extension to Zend_Gdata to allow interaction
with Googles Analytics Data Export API. This extension does not
encompass any major changes in the overall operation of Zend_Gdata
components.
Zend_Gdata_Analytics was contributed by Daniel Hartmann.
Removed features
================
Zend_Http_UserAgent_Features_Adapter_WurflApi
----
Due to the changes in licensing of WURFL, we have removed the WurflApi
adapter. We will be providing the WurflApi adapter to ScientiaMobile so
that users of WURFL will still have that option.
Bug Fixes
=========
In addition, over 200 reported issues in the tracker have been fixed.
Wed like to particularly thank Adam Lundrigan, Frank Brückner and
Martin Hujer for their efforts in making this happen. Thanks also to the
many people who ran the ZF1 unit tests and reported their results!
For a complete list, visit:
* http://framework.zend.com/issues/secure/IssueNavigator.jspa?requestId=12877
* http://framework.zend.com/changelog/
MIGRATION NOTES
---------------
A detailed list of migration notes may be found at:
http://framework.zend.com/manual/en/migration.html
SYSTEM REQUIREMENTS
-------------------
Zend Framework requires PHP 5.2.11 or later. Please see our reference
guide for more detailed system requirements:
http://framework.zend.com/manual/en/requirements.html
INSTALLATION
------------
Please see INSTALL.txt.
QUESTIONS AND FEEDBACK
----------------------
Online documentation can be found at http://framework.zend.com/manual.
Questions that are not addressed in the manual should be directed to the
appropriate mailing list:
http://framework.zend.com/wiki/display/ZFDEV/Mailing+Lists
If you find code in this release behaving in an unexpected manner or
contrary to its documented behavior, please create an issue in the Zend
Framework issue tracker at:
http://framework.zend.com/issues
If you would like to be notified of new releases, you can subscribe to
the fw-announce mailing list by sending a blank message to
fw-announce-subscribe@lists.zend.com.
LICENSE
-------
The files in this archive are released under the Zend Framework license.
You can find a copy of this license in LICENSE.txt.
ACKNOWLEDGEMENTS
----------------
The Zend Framework team would like to thank all the contributors to the Zend
Framework project, our corporate sponsor, and you, the Zend Framework user.
Please visit us sometime soon at http://framework.zend.com.

23
composer.json Normal file
View File

@ -0,0 +1,23 @@
{
"name": "zf1/zend-pdf",
"description": "Zend Framework 1 Pdf package",
"keywords": [
"framework",
"zf1",
"zend",
"pdf"
],
"homepage": "http://framework.zend.com/",
"license": "BSD-3-Clause",
"require": {
"php": ">=5.2.11",
"zf1/zend-exception": "self.version",
"zf1/zend-log": "self.version",
"zf1/zend-memory": "self.version"
},
"autoload": {
"psr-0": {
"Zend_Pdf": "library/"
}
}
}

1428
library/Zend/Pdf.php Normal file

File diff suppressed because it is too large Load Diff

404
library/Zend/Pdf/Action.php Normal file
View File

@ -0,0 +1,404 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Action.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
/** Zend_Pdf_Target */
// require_once 'Zend/Pdf/Target.php';
/**
* Abstract PDF action representation class
*
* @package Zend_Pdf
* @subpackage Actions
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Action extends Zend_Pdf_Target implements RecursiveIterator, Countable
{
/**
* Action dictionary
*
* @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
*/
protected $_actionDictionary;
/**
* An original list of chained actions
*
* @var array Array of Zend_Pdf_Action objects
*/
protected $_originalNextList;
/**
* A list of next actions in actions tree (used for actions chaining)
*
* @var array Array of Zend_Pdf_Action objects
*/
public $next = array();
/**
* Object constructor
*
* @param Zend_Pdf_Element_Dictionary $dictionary
* @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, SplObjectStorage $processedActions)
{
// require_once 'Zend/Pdf/Element.php';
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.');
}
$this->_actionDictionary = $dictionary;
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[] = Zend_Pdf_Action::load($dictionary->Next, $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[] = Zend_Pdf_Action::load($chainedActionDictionary, $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.');
}
}
$this->_originalNextList = $this->next;
}
/**
* Load PDF action object using specified dictionary
*
* @internal
* @param Zend_Pdf_Element $dictionary (It's actually Dictionary or Dictionary Object or Reference to a Dictionary Object)
* @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, SplObjectStorage $processedActions = null)
{
if ($processedActions === null) {
$processedActions = new SplObjectStorage();
}
// require_once 'Zend/Pdf/Element.php';
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 contain S entry');
}
switch ($dictionary->S->value) {
case 'GoTo':
// require_once 'Zend/Pdf/Action/GoTo.php';
return new Zend_Pdf_Action_GoTo($dictionary, $processedActions);
break;
case 'GoToR':
// require_once 'Zend/Pdf/Action/GoToR.php';
return new Zend_Pdf_Action_GoToR($dictionary, $processedActions);
break;
case 'GoToE':
// require_once 'Zend/Pdf/Action/GoToE.php';
return new Zend_Pdf_Action_GoToE($dictionary, $processedActions);
break;
case 'Launch':
// require_once 'Zend/Pdf/Action/Launch.php';
return new Zend_Pdf_Action_Launch($dictionary, $processedActions);
break;
case 'Thread':
// require_once 'Zend/Pdf/Action/Thread.php';
return new Zend_Pdf_Action_Thread($dictionary, $processedActions);
break;
case 'URI':
// require_once 'Zend/Pdf/Action/URI.php';
return new Zend_Pdf_Action_URI($dictionary, $processedActions);
break;
case 'Sound':
// require_once 'Zend/Pdf/Action/Sound.php';
return new Zend_Pdf_Action_Sound($dictionary, $processedActions);
break;
case 'Movie':
// require_once 'Zend/Pdf/Action/Movie.php';
return new Zend_Pdf_Action_Movie($dictionary, $processedActions);
break;
case 'Hide':
// require_once 'Zend/Pdf/Action/Hide.php';
return new Zend_Pdf_Action_Hide($dictionary, $processedActions);
break;
case 'Named':
// require_once 'Zend/Pdf/Action/Named.php';
return new Zend_Pdf_Action_Named($dictionary, $processedActions);
break;
case 'SubmitForm':
// require_once 'Zend/Pdf/Action/SubmitForm.php';
return new Zend_Pdf_Action_SubmitForm($dictionary, $processedActions);
break;
case 'ResetForm':
// require_once 'Zend/Pdf/Action/ResetForm.php';
return new Zend_Pdf_Action_ResetForm($dictionary, $processedActions);
break;
case 'ImportData':
// require_once 'Zend/Pdf/Action/ImportData.php';
return new Zend_Pdf_Action_ImportData($dictionary, $processedActions);
break;
case 'JavaScript':
// require_once 'Zend/Pdf/Action/JavaScript.php';
return new Zend_Pdf_Action_JavaScript($dictionary, $processedActions);
break;
case 'SetOCGState':
// require_once 'Zend/Pdf/Action/SetOCGState.php';
return new Zend_Pdf_Action_SetOCGState($dictionary, $processedActions);
break;
case 'Rendition':
// require_once 'Zend/Pdf/Action/Rendition.php';
return new Zend_Pdf_Action_Rendition($dictionary, $processedActions);
break;
case 'Trans':
// require_once 'Zend/Pdf/Action/Trans.php';
return new Zend_Pdf_Action_Trans($dictionary, $processedActions);
break;
case 'GoTo3DView':
// require_once 'Zend/Pdf/Action/GoTo3DView.php';
return new Zend_Pdf_Action_GoTo3DView($dictionary, $processedActions);
break;
default:
// require_once 'Zend/Pdf/Action/Unknown.php';
return new Zend_Pdf_Action_Unknown($dictionary, $processedActions);
break;
}
}
/**
* Get resource
*
* @internal
* @return Zend_Pdf_Element
*/
public function getResource()
{
return $this->_actionDictionary;
}
/**
* Dump Action and its child actions into PDF structures
*
* Returns dictionary indirect object or reference
*
* @internal
* @param Zend_Pdf_ElementFactory $factory Object factory for newly created indirect objects
* @param SplObjectStorage $processedActions list of already processed actions (used to prevent infinity loop caused by cyclic references)
* @return Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference Dictionary indirect object
*/
public function dumpAction(Zend_Pdf_ElementFactory_Interface $factory, SplObjectStorage $processedActions = null)
{
if ($processedActions === null) {
$processedActions = new SplObjectStorage();
}
if ($processedActions->contains($this)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Action chain cyclyc reference is detected.');
}
$processedActions->attach($this);
$childListUpdated = false;
if (count($this->_originalNextList) != count($this->next)) {
// If original and current children arrays have different size then children list was updated
$childListUpdated = true;
} else if ( !(array_keys($this->_originalNextList) === array_keys($this->next)) ) {
// If original and current children arrays have different keys (with a glance to an order) then children list was updated
$childListUpdated = true;
} else {
foreach ($this->next as $key => $childAction) {
if ($this->_originalNextList[$key] !== $childAction) {
$childListUpdated = true;
break;
}
}
}
if ($childListUpdated) {
$this->_actionDictionary->touch();
switch (count($this->next)) {
case 0:
$this->_actionDictionary->Next = null;
break;
case 1:
$child = reset($this->next);
$this->_actionDictionary->Next = $child->dumpAction($factory, $processedActions);
break;
default:
// require_once 'Zend/Pdf/Element/Array.php';
$pdfChildArray = new Zend_Pdf_Element_Array();
foreach ($this->next as $child) {
$pdfChildArray->items[] = $child->dumpAction($factory, $processedActions);
}
$this->_actionDictionary->Next = $pdfChildArray;
break;
}
} else {
foreach ($this->next as $child) {
$child->dumpAction($factory, $processedActions);
}
}
if ($this->_actionDictionary instanceof Zend_Pdf_Element_Dictionary) {
// It's a newly created action. Register it within object factory and return indirect object
return $factory->newObject($this->_actionDictionary);
} else {
// It's a loaded object
return $this->_actionDictionary;
}
}
////////////////////////////////////////////////////////////////////////
// RecursiveIterator interface methods
//////////////
/**
* Returns current child action.
*
* @return Zend_Pdf_Action
*/
public function current()
{
return current($this->next);
}
/**
* Returns current iterator key
*
* @return integer
*/
public function key()
{
return key($this->next);
}
/**
* Go to next child
*/
public function next()
{
return next($this->next);
}
/**
* Rewind children
*/
public function rewind()
{
return reset($this->next);
}
/**
* Check if current position is valid
*
* @return boolean
*/
public function valid()
{
return current($this->next) !== false;
}
/**
* Returns the child action.
*
* @return Zend_Pdf_Action|null
*/
public function getChildren()
{
return current($this->next);
}
/**
* Implements RecursiveIterator interface.
*
* @return bool whether container has any pages
*/
public function hasChildren()
{
return count($this->next) > 0;
}
////////////////////////////////////////////////////////////////////////
// Countable interface methods
//////////////
/**
* count()
*
* @return int
*/
public function count()
{
return count($this->childOutlines);
}
}

View File

@ -0,0 +1,116 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GoTo.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Destination.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
/** Zend_Pdf_Action */
// require_once 'Zend/Pdf/Action.php';
/**
* PDF 'Go to' action
*
* @package Zend_Pdf
* @subpackage Actions
* @copyright Copyright (c) 2005-2012 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
{
/**
* GoTo Action destination
*
* @var Zend_Pdf_Destination
*/
protected $_destination;
/**
* Object constructor
*
* @param Zend_Pdf_Element_Dictionary $dictionary
* @param SplObjectStorage $processedActions list of already processed action dictionaries, used to avoid cyclic references
*/
public function __construct(Zend_Pdf_Element $dictionary, SplObjectStorage $processedActions)
{
parent::__construct($dictionary, $processedActions);
$this->_destination = Zend_Pdf_Destination::load($dictionary->D);
}
/**
* Create new Zend_Pdf_Action_GoTo object using specified destination
*
* @param Zend_Pdf_Destination|string $destination
* @return Zend_Pdf_Action_GoTo
*/
public static function create($destination)
{
if (is_string($destination)) {
// require_once 'Zend/Pdf/Destination/Named.php';
$destination = Zend_Pdf_Destination_Named::create($destination);
}
if (!$destination instanceof Zend_Pdf_Destination) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('$destination parameter must be a Zend_Pdf_Destination object or string.');
}
$dictionary = new Zend_Pdf_Element_Dictionary();
$dictionary->Type = new Zend_Pdf_Element_Name('Action');
$dictionary->S = new Zend_Pdf_Element_Name('GoTo');
$dictionary->Next = null;
$dictionary->D = $destination->getResource();
return new Zend_Pdf_Action_GoTo($dictionary, new SplObjectStorage());
}
/**
* Set goto action destination
*
* @param Zend_Pdf_Destination|string $destination
* @return Zend_Pdf_Action_GoTo
*/
public function setDestination(Zend_Pdf_Destination $destination)
{
$this->_destination = $destination;
$this->_actionDictionary->touch();
$this->_actionDictionary->D = $destination->getResource();
return $this;
}
/**
* Get goto action destination
*
* @return Zend_Pdf_Destination
*/
public function getDestination()
{
return $this->_destination;
}
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GoTo3DView.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GoToE.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GoToR.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Hide.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Action */
// require_once 'Zend/Pdf/Action.php';
/**
* PDF 'Set an annotations Hidden flag' action
* PDF 1.2+ feature
*
* @package Zend_Pdf
* @subpackage Actions
* @copyright Copyright (c) 2005-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ImportData.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: JavaScript.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Launch.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Movie.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Named.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rendition.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ResetForm.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: SetOCGState.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Sound.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: SubmitForm.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Thread.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Trans.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** 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-2012 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
{
}

View File

@ -0,0 +1,167 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: URI.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/String.php';
// require_once 'Zend/Pdf/Element/Boolean.php';
/** Zend_Pdf_Action */
// require_once 'Zend/Pdf/Action.php';
/**
* PDF 'Resolve a uniform resource identifier' action
*
* A URI action causes a URI to be resolved.
*
* @package Zend_Pdf
* @subpackage Actions
* @copyright Copyright (c) 2005-2012 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
{
/**
* Object constructor
*
* @param Zend_Pdf_Element_Dictionary $dictionary
* @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, SplObjectStorage $processedActions)
{
parent::__construct($dictionary, $processedActions);
if ($dictionary->URI === null) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('URI action dictionary entry is required');
}
}
/**
* Validate URI
*
* @param string $uri
* @return true
* @throws Zend_Pdf_Exception
*/
protected static function _validateUri($uri)
{
$scheme = parse_url((string)$uri, PHP_URL_SCHEME);
if ($scheme === false || $scheme === null) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid URI');
}
}
/**
* Create new Zend_Pdf_Action_URI object using specified uri
*
* @param string $uri The URI to resolve, encoded in 7-bit ASCII
* @param boolean $isMap A flag specifying whether to track the mouse position when the URI is resolved
* @return Zend_Pdf_Action_URI
*/
public static function create($uri, $isMap = false)
{
self::_validateUri($uri);
$dictionary = new Zend_Pdf_Element_Dictionary();
$dictionary->Type = new Zend_Pdf_Element_Name('Action');
$dictionary->S = new Zend_Pdf_Element_Name('URI');
$dictionary->Next = null;
$dictionary->URI = new Zend_Pdf_Element_String($uri);
if ($isMap) {
$dictionary->IsMap = new Zend_Pdf_Element_Boolean(true);
}
return new Zend_Pdf_Action_URI($dictionary, new SplObjectStorage());
}
/**
* Set URI to resolve
*
* @param string $uri The uri to resolve, encoded in 7-bit ASCII.
* @return Zend_Pdf_Action_URI
*/
public function setUri($uri)
{
$this->_validateUri($uri);
$this->_actionDictionary->touch();
$this->_actionDictionary->URI = new Zend_Pdf_Element_String($uri);
return $this;
}
/**
* Get URI to resolve
*
* @return string
*/
public function getUri()
{
return $this->_actionDictionary->URI->value;
}
/**
* Set IsMap property
*
* If the IsMap flag is true and the user has triggered the URI action by clicking
* an annotation, the coordinates of the mouse position at the time the action is
* performed should be transformed from device space to user space and then offset
* relative to the upper-left corner of the annotation rectangle.
*
* @param boolean $isMap A flag specifying whether to track the mouse position when the URI is resolved
* @return Zend_Pdf_Action_URI
*/
public function setIsMap($isMap)
{
$this->_actionDictionary->touch();
if ($isMap) {
$this->_actionDictionary->IsMap = new Zend_Pdf_Element_Boolean(true);
} else {
$this->_actionDictionary->IsMap = null;
}
return $this;
}
/**
* Get IsMap property
*
* If the IsMap flag is true and the user has triggered the URI action by clicking
* an annotation, the coordinates of the mouse position at the time the action is
* performed should be transformed from device space to user space and then offset
* relative to the upper-left corner of the annotation rectangle.
*
* @return boolean
*/
public function getIsMap()
{
return $this->_actionDictionary->IsMap !== null &&
$this->_actionDictionary->IsMap->value;
}
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Unknown.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Action */
// require_once 'Zend/Pdf/Action.php';
/**
* Unrecognized PDF action
*
* @package Zend_Pdf
* @subpackage Actions
* @copyright Copyright (c) 2005-2012 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
{
}

View File

@ -0,0 +1,230 @@
<?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 Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Annotation.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
/**
* Abstract PDF annotation representation class
*
* An annotation associates an object such as a note, sound, or movie with a location
* on a page of a PDF document, or provides a way to interact with the user by
* means of the mouse and keyboard.
*
* @package Zend_Pdf
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Annotation
{
/**
* Annotation dictionary
*
* @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
*/
protected $_annotationDictionary;
/**
* Get annotation dictionary
*
* @internal
* @return Zend_Pdf_Element
*/
public function getResource()
{
return $this->_annotationDictionary;
}
/**
* Set bottom edge of the annotation rectangle.
*
* @param float $bottom
* @return Zend_Pdf_Annotation
*/
public function setBottom($bottom) {
$this->_annotationDictionary->Rect->items[1]->touch();
$this->_annotationDictionary->Rect->items[1]->value = $bottom;
return $this;
}
/**
* Get bottom edge of the annotation rectangle.
*
* @return float
*/
public function getBottom() {
return $this->_annotationDictionary->Rect->items[1]->value;
}
/**
* Set top edge of the annotation rectangle.
*
* @param float $top
* @return Zend_Pdf_Annotation
*/
public function setTop($top) {
$this->_annotationDictionary->Rect->items[3]->touch();
$this->_annotationDictionary->Rect->items[3]->value = $top;
return $this;
}
/**
* Get top edge of the annotation rectangle.
*
* @return float
*/
public function getTop() {
return $this->_annotationDictionary->Rect->items[3]->value;
}
/**
* Set right edge of the annotation rectangle.
*
* @param float $right
* @return Zend_Pdf_Annotation
*/
public function setRight($right) {
$this->_annotationDictionary->Rect->items[2]->touch();
$this->_annotationDictionary->Rect->items[2]->value = $right;
return $this;
}
/**
* Get right edge of the annotation rectangle.
*
* @return float
*/
public function getRight() {
return $this->_annotationDictionary->Rect->items[2]->value;
}
/**
* Set left edge of the annotation rectangle.
*
* @param float $left
* @return Zend_Pdf_Annotation
*/
public function setLeft($left) {
$this->_annotationDictionary->Rect->items[0]->touch();
$this->_annotationDictionary->Rect->items[0]->value = $left;
return $this;
}
/**
* Get left edge of the annotation rectangle.
*
* @return float
*/
public function getLeft() {
return $this->_annotationDictionary->Rect->items[0]->value;
}
/**
* Return text to be displayed for the annotation or, if this type of annotation
* does not display text, an alternate description of the annotations contents
* in human-readable form.
*
* @return string
*/
public function getText() {
if ($this->_annotationDictionary->Contents === null) {
return '';
}
return $this->_annotationDictionary->Contents->value;
}
/**
* Set text to be displayed for the annotation or, if this type of annotation
* does not display text, an alternate description of the annotations contents
* in human-readable form.
*
* @param string $text
* @return Zend_Pdf_Annotation
*/
public function setText($text) {
// require_once 'Zend/Pdf/Element/String.php';
if ($this->_annotationDictionary->Contents === null) {
$this->_annotationDictionary->touch();
$this->_annotationDictionary->Contents = new Zend_Pdf_Element_String($text);
} else {
$this->_annotationDictionary->Contents->touch();
$this->_annotationDictionary->Contents->value = new Zend_Pdf_Element_String($text);
}
return $this;
}
/**
* Annotation object constructor
*
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $annotationDictionary)
{
if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
}
$this->_annotationDictionary = $annotationDictionary;
if ($this->_annotationDictionary->Type !== null &&
$this->_annotationDictionary->Type->value != 'Annot') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong resource type. \'Annot\' expected.');
}
if ($this->_annotationDictionary->Rect === null) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('\'Rect\' dictionary entry is required.');
}
if (count($this->_annotationDictionary->Rect->items) != 4 ||
$this->_annotationDictionary->Rect->items[0]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
$this->_annotationDictionary->Rect->items[1]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
$this->_annotationDictionary->Rect->items[2]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ||
$this->_annotationDictionary->Rect->items[3]->getType() != Zend_Pdf_Element::TYPE_NUMERIC ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('\'Rect\' dictionary entry must be an array of four numeric elements.');
}
}
/**
* Load Annotation object from a specified resource
*
* @internal
* @param Zend_Pdf_Element $resource
* @return Zend_Pdf_Annotation
*/
public static function load(Zend_Pdf_Element $resource)
{
/** @todo implementation */
}
}

View File

@ -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 Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FileAttachment.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
// require_once 'Zend/Pdf/Element/String.php';
/** Zend_Pdf_Annotation */
// require_once 'Zend/Pdf/Annotation.php';
/**
* A file attachment annotation contains a reference to a file,
* which typically is embedded in the PDF file.
*
* @package Zend_Pdf
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Annotation_FileAttachment extends Zend_Pdf_Annotation
{
/**
* Annotation object constructor
*
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $annotationDictionary)
{
if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
}
if ($annotationDictionary->Subtype === null ||
$annotationDictionary->Subtype->getType() != Zend_Pdf_Element::TYPE_NAME ||
$annotationDictionary->Subtype->value != 'FileAttachment') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Subtype => FileAttachment entry is requires');
}
parent::__construct($annotationDictionary);
}
/**
* Create link annotation object
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param string $fileSpecification
* @return Zend_Pdf_Annotation_FileAttachment
*/
public static function create($x1, $y1, $x2, $y2, $fileSpecification)
{
$annotationDictionary = new Zend_Pdf_Element_Dictionary();
$annotationDictionary->Type = new Zend_Pdf_Element_Name('Annot');
$annotationDictionary->Subtype = new Zend_Pdf_Element_Name('FileAttachment');
$rectangle = new Zend_Pdf_Element_Array();
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x2);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y2);
$annotationDictionary->Rect = $rectangle;
$fsDictionary = new Zend_Pdf_Element_Dictionary();
$fsDictionary->Type = new Zend_Pdf_Element_Name('Filespec');
$fsDictionary->F = new Zend_Pdf_Element_String($fileSpecification);
$annotationDictionary->FS = $fsDictionary;
return new Zend_Pdf_Annotation_FileAttachment($annotationDictionary);
}
}

View File

@ -0,0 +1,162 @@
<?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 Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Link.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Annotation */
// require_once 'Zend/Pdf/Annotation.php';
/**
* A link annotation represents either a hypertext link to a destination elsewhere in
* the document or an action to be performed.
*
* Only destinations are used now since only GoTo action can be created by user
* in current implementation.
*
* @package Zend_Pdf
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Annotation_Link extends Zend_Pdf_Annotation
{
/**
* Annotation object constructor
*
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $annotationDictionary)
{
if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
}
if ($annotationDictionary->Subtype === null ||
$annotationDictionary->Subtype->getType() != Zend_Pdf_Element::TYPE_NAME ||
$annotationDictionary->Subtype->value != 'Link') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Subtype => Link entry is requires');
}
parent::__construct($annotationDictionary);
}
/**
* Create link annotation object
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param Zend_Pdf_Target|string $target
* @return Zend_Pdf_Annotation_Link
*/
public static function create($x1, $y1, $x2, $y2, $target)
{
if (is_string($target)) {
// require_once 'Zend/Pdf/Destination/Named.php';
$destination = Zend_Pdf_Destination_Named::create($target);
}
if (!$target instanceof Zend_Pdf_Target) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('$target parameter must be a Zend_Pdf_Target object or a string.');
}
$annotationDictionary = new Zend_Pdf_Element_Dictionary();
$annotationDictionary->Type = new Zend_Pdf_Element_Name('Annot');
$annotationDictionary->Subtype = new Zend_Pdf_Element_Name('Link');
$rectangle = new Zend_Pdf_Element_Array();
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x2);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y2);
$annotationDictionary->Rect = $rectangle;
if ($target instanceof Zend_Pdf_Destination) {
$annotationDictionary->Dest = $target->getResource();
} else {
$annotationDictionary->A = $target->getResource();
}
return new Zend_Pdf_Annotation_Link($annotationDictionary);
}
/**
* Set link annotation destination
*
* @param Zend_Pdf_Target|string $target
* @return Zend_Pdf_Annotation_Link
*/
public function setDestination($target)
{
if (is_string($target)) {
// require_once 'Zend/Pdf/Destination/Named.php';
$destination = Zend_Pdf_Destination_Named::create($target);
}
if (!$target instanceof Zend_Pdf_Target) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('$target parameter must be a Zend_Pdf_Target object or a string.');
}
$this->_annotationDictionary->touch();
$this->_annotationDictionary->Dest = $destination->getResource();
if ($target instanceof Zend_Pdf_Destination) {
$this->_annotationDictionary->Dest = $target->getResource();
$this->_annotationDictionary->A = null;
} else {
$this->_annotationDictionary->Dest = null;
$this->_annotationDictionary->A = $target->getResource();
}
return $this;
}
/**
* Get link annotation destination
*
* @return Zend_Pdf_Target|null
*/
public function getDestination()
{
if ($this->_annotationDictionary->Dest === null &&
$this->_annotationDictionary->A === null) {
return null;
}
if ($this->_annotationDictionary->Dest !== null) {
// require_once 'Zend/Pdf/Destination.php';
return Zend_Pdf_Destination::load($this->_annotationDictionary->Dest);
} else {
// require_once 'Zend/Pdf/Action.php';
return Zend_Pdf_Action::load($this->_annotationDictionary->A);
}
}
}

View File

@ -0,0 +1,142 @@
<?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 Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Markup.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
// require_once 'Zend/Pdf/Element/String.php';
/** Zend_Pdf_Annotation */
// require_once 'Zend/Pdf/Annotation.php';
/**
* A markup annotation
*
* @package Zend_Pdf
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Annotation_Markup extends Zend_Pdf_Annotation
{
/**
* Annotation subtypes
*/
const SUBTYPE_HIGHLIGHT = 'Highlight';
const SUBTYPE_UNDERLINE = 'Underline';
const SUBTYPE_SQUIGGLY = 'Squiggly';
const SUBTYPE_STRIKEOUT = 'StrikeOut';
/**
* Annotation object constructor
*
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $annotationDictionary)
{
if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
}
if ($annotationDictionary->Subtype === null ||
$annotationDictionary->Subtype->getType() != Zend_Pdf_Element::TYPE_NAME ||
!in_array( $annotationDictionary->Subtype->value,
array(self::SUBTYPE_HIGHLIGHT,
self::SUBTYPE_UNDERLINE,
self::SUBTYPE_SQUIGGLY,
self::SUBTYPE_STRIKEOUT) )) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Subtype => Markup entry is omitted or has wrong value.');
}
parent::__construct($annotationDictionary);
}
/**
* Create markup annotation object
*
* Text markup annotations appear as highlights, underlines, strikeouts or
* jagged ("squiggly") underlines in the text of a document. When opened,
* they display a pop-up window containing the text of the associated note.
*
* $subType parameter may contain
* Zend_Pdf_Annotation_Markup::SUBTYPE_HIGHLIGHT
* Zend_Pdf_Annotation_Markup::SUBTYPE_UNDERLINE
* Zend_Pdf_Annotation_Markup::SUBTYPE_SQUIGGLY
* Zend_Pdf_Annotation_Markup::SUBTYPE_STRIKEOUT
* for for a highlight, underline, squiggly-underline, or strikeout annotation,
* respectively.
*
* $quadPoints is an array of 8xN numbers specifying the coordinates of
* N quadrilaterals default user space. Each quadrilateral encompasses a word or
* group of contiguous words in the text underlying the annotation.
* The coordinates for each quadrilateral are given in the order
* x1 y1 x2 y2 x3 y3 x4 y4
* specifying the quadrilaterals four vertices in counterclockwise order
* starting from left bottom corner.
* The text is oriented with respect to the edge connecting points
* (x1, y1) and (x2, y2).
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param string $text
* @param string $subType
* @param array $quadPoints [x1 y1 x2 y2 x3 y3 x4 y4]
* @return Zend_Pdf_Annotation_Markup
* @throws Zend_Pdf_Exception
*/
public static function create($x1, $y1, $x2, $y2, $text, $subType, $quadPoints)
{
$annotationDictionary = new Zend_Pdf_Element_Dictionary();
$annotationDictionary->Type = new Zend_Pdf_Element_Name('Annot');
$annotationDictionary->Subtype = new Zend_Pdf_Element_Name($subType);
$rectangle = new Zend_Pdf_Element_Array();
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x2);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y2);
$annotationDictionary->Rect = $rectangle;
$annotationDictionary->Contents = new Zend_Pdf_Element_String($text);
if (!is_array($quadPoints) || count($quadPoints) == 0 || count($quadPoints) % 8 != 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('$quadPoints parameter must be an array of 8xN numbers');
}
$points = new Zend_Pdf_Element_Array();
foreach ($quadPoints as $quadPoint) {
$points->items[] = new Zend_Pdf_Element_Numeric($quadPoint);
}
$annotationDictionary->QuadPoints = $points;
return new Zend_Pdf_Annotation_Markup($annotationDictionary);
}
}

View File

@ -0,0 +1,95 @@
<?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 Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Text.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
// require_once 'Zend/Pdf/Element/String.php';
/** Zend_Pdf_Annotation */
// require_once 'Zend/Pdf/Annotation.php';
/**
* A text annotation represents a "sticky note" attached to a point in the PDF document.
*
* @package Zend_Pdf
* @subpackage Annotation
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Annotation_Text extends Zend_Pdf_Annotation
{
/**
* Annotation object constructor
*
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $annotationDictionary)
{
if ($annotationDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Annotation dictionary resource has to be a dictionary.');
}
if ($annotationDictionary->Subtype === null ||
$annotationDictionary->Subtype->getType() != Zend_Pdf_Element::TYPE_NAME ||
$annotationDictionary->Subtype->value != 'Text') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Subtype => Text entry is requires');
}
parent::__construct($annotationDictionary);
}
/**
* Create link annotation object
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param string $text
* @return Zend_Pdf_Annotation_Text
*/
public static function create($x1, $y1, $x2, $y2, $text)
{
$annotationDictionary = new Zend_Pdf_Element_Dictionary();
$annotationDictionary->Type = new Zend_Pdf_Element_Name('Annot');
$annotationDictionary->Subtype = new Zend_Pdf_Element_Name('Text');
$rectangle = new Zend_Pdf_Element_Array();
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y1);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($x2);
$rectangle->items[] = new Zend_Pdf_Element_Numeric($y2);
$annotationDictionary->Rect = $rectangle;
$annotationDictionary->Contents = new Zend_Pdf_Element_String($text);
return new Zend_Pdf_Annotation_Text($annotationDictionary);
}
}

182
library/Zend/Pdf/Canvas.php Normal file
View File

@ -0,0 +1,182 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Style.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
// require_once 'Zend/Pdf/Canvas/Abstract.php';
/**
* Canvas is an abstract rectangle drawing area which can be dropped into
* page object at specified place.
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Canvas extends Zend_Pdf_Canvas_Abstract
{
/**
* Canvas procedure sets.
*
* Allowed values: 'PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'.
*
* @var array
*/
protected $_procSet = array();
/**
* Canvas width expressed in default user space units (1/72 inch)
*
* @var float
*/
protected $_width;
/**
* Canvas height expressed in default user space units (1/72 inch)
*
* @var float
*/
protected $_height;
protected $_resources = array('Font' => array(),
'XObject' => array(),
'ExtGState' => array());
/**
* Object constructor
*
* @param float $width
* @param float $height
*/
public function __construct($width, $height)
{
$this->_width = $width;
$this->_height = $height;
}
/**
* Add procedure set to the canvas description
*
* @param string $procSetName
*/
protected function _addProcSet($procSetName)
{
$this->_procset[$procSetName] = 1;
}
/**
* Attach resource to the canvas
*
* Method returns a name of the resource which can be used
* as a resource reference within drawing instructions stream
* Allowed types: 'ExtGState', 'ColorSpace', 'Pattern', 'Shading',
* 'XObject', 'Font', 'Properties'
*
* @param string $type
* @param Zend_Pdf_Resource $resource
* @return string
*/
protected function _attachResource($type, Zend_Pdf_Resource $resource)
{
// Check, that resource is already attached to resource set.
$resObject = $resource->getResource();
foreach ($this->_resources[$type] as $resName => $collectedResObject) {
if ($collectedResObject === $resObject) {
return $resName;
}
}
$idCounter = 1;
do {
$newResName = $type[0] . $idCounter++;
} while (isset($this->_resources[$type][$newResName]));
$this->_resources[$type][$newResName] = $resObject;
return $newResName;
}
/**
* 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
*/
public function getHeight()
{
return $this->_height;
}
/**
* Return the width of this page in points.
*
* @return float
*/
public function getWidth()
{
return $this->_width;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,493 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Style.php 20096 2010-01-06 02:05:09Z bkarwin $
*/
/**
* Canvas is an abstract rectangle drawing area which can be dropped into
* page object at specified place.
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
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.
*
* @return float
*/
public function getHeight();
/**
* Return canvas width.
*
* @return float
*/
public function getWidth();
/**
* Draw a canvas at the specified location
*
* If upper right corner is not specified then canvas heght and width
* are used.
*
* @param Zend_Pdf_Canvas_Interface $canvas
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @return Zend_Pdf_Canvas_Interface
*/
public function drawCanvas(Zend_Pdf_Canvas_Interface $canvas, $x1, $y1, $x2 = null, $y2 = null);
/**
* Set fill color.
*
* @param Zend_Pdf_Color $color
* @return Zend_Pdf_Canvas_Interface
*/
public function setFillColor(Zend_Pdf_Color $color);
/**
* Set line color.
*
* @param Zend_Pdf_Color $color
* @return Zend_Pdf_Canvas_Interface
*/
public function setLineColor(Zend_Pdf_Color $color);
/**
* Set line width.
*
* @param float $width
* @return Zend_Pdf_Canvas_Interface
*/
public function setLineWidth($width);
/**
* Set line dashing pattern
*
* Pattern is an array of floats: array(on_length, off_length, on_length, off_length, ...)
* or Zend_Pdf_Page::LINE_DASHING_SOLID constant
* Phase is shift from the beginning of line.
*
* @param mixed $pattern
* @param array $phase
* @return Zend_Pdf_Canvas_Interface
*/
public function setLineDashingPattern($pattern, $phase = 0);
/**
* Set current font.
*
* @param Zend_Pdf_Resource_Font $font
* @param float $fontSize
* @return Zend_Pdf_Canvas_Interface
*/
public function setFont(Zend_Pdf_Resource_Font $font, $fontSize);
/**
* Set the style to use for future drawing operations on this page
*
* @param Zend_Pdf_Style $style
* @return Zend_Pdf_Canvas_Interface
*/
public function setStyle(Zend_Pdf_Style $style);
/**
* Get current font.
*
* @return Zend_Pdf_Resource_Font $font
*/
public function getFont();
/**
* Get current font size
*
* @return float $fontSize
*/
public function getFontSize();
/**
* Return the style, applied to the page.
*
* @return Zend_Pdf_Style|null
*/
public function getStyle();
/**
* Save the graphics state of this page.
* This takes a snapshot of the currently applied style, position, clipping area and
* any rotation/translation/scaling that has been applied.
*
* @throws Zend_Pdf_Exception - if a save is performed with an open path
* @return Zend_Pdf_Page
*/
public function saveGS();
/**
* Set the transparancy
*
* $alpha == 0 - transparent
* $alpha == 1 - opaque
*
* Transparency modes, supported by PDF:
* Normal (default), Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight,
* SoftLight, Difference, Exclusion
*
* @param float $alpha
* @param string $mode
* @throws Zend_Pdf_Exception
* @return Zend_Pdf_Canvas_Interface
*/
public function setAlpha($alpha, $mode = 'Normal');
/**
* Intersect current clipping area with a circle.
*
* @param float $x
* @param float $y
* @param float $radius
* @param float $startAngle
* @param float $endAngle
* @return Zend_Pdf_Canvas_Interface
*/
public function clipCircle($x, $y, $radius, $startAngle = null, $endAngle = null);
/**
* Intersect current clipping area with a polygon.
*
* Method signatures:
* drawEllipse($x1, $y1, $x2, $y2);
* drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
*
* @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param float $startAngle
* @param float $endAngle
* @return Zend_Pdf_Canvas_Interface
*/
public function clipEllipse($x1, $y1, $x2, $y2, $startAngle = null, $endAngle = null);
/**
* Intersect current clipping area with a polygon.
*
* @param array $x - array of float (the X co-ordinates of the vertices)
* @param array $y - array of float (the Y co-ordinates of the vertices)
* @param integer $fillMethod
* @return Zend_Pdf_Canvas_Interface
*/
public function clipPolygon($x, $y, $fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING);
/**
* Intersect current clipping area with a rectangle.
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @return Zend_Pdf_Canvas_Interface
*/
public function clipRectangle($x1, $y1, $x2, $y2);
/**
* Draw a circle centered on x, y with a radius of radius.
*
* Method signatures:
* drawCircle($x, $y, $radius);
* drawCircle($x, $y, $radius, $fillType);
* drawCircle($x, $y, $radius, $startAngle, $endAngle);
* drawCircle($x, $y, $radius, $startAngle, $endAngle, $fillType);
*
*
* It's not a really circle, because PDF supports only cubic Bezier curves.
* But _very_ good approximation.
* It differs from a real circle on a maximum 0.00026 radiuses
* (at PI/8, 3*PI/8, 5*PI/8, 7*PI/8, 9*PI/8, 11*PI/8, 13*PI/8 and 15*PI/8 angles).
* At 0, PI/4, PI/2, 3*PI/4, PI, 5*PI/4, 3*PI/2 and 7*PI/4 it's exactly a tangent to a circle.
*
* @param float $x
* @param float $y
* @param float $radius
* @param mixed $param4
* @param mixed $param5
* @param mixed $param6
* @return Zend_Pdf_Canvas_Interface
*/
public function drawCircle($x, $y, $radius, $param4 = null, $param5 = null, $param6 = null);
/**
* Draw an ellipse inside the specified rectangle.
*
* Method signatures:
* drawEllipse($x1, $y1, $x2, $y2);
* drawEllipse($x1, $y1, $x2, $y2, $fillType);
* drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle);
* drawEllipse($x1, $y1, $x2, $y2, $startAngle, $endAngle, $fillType);
*
* @todo process special cases with $x2-$x1 == 0 or $y2-$y1 == 0
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param mixed $param5
* @param mixed $param6
* @param mixed $param7
* @return Zend_Pdf_Canvas_Interface
*/
public function drawEllipse($x1, $y1, $x2, $y2, $param5 = null, $param6 = null, $param7 = null);
/**
* Draw an image at the specified position on the page.
*
* @param Zend_Pdf_Image $image
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @return Zend_Pdf_Canvas_Interface
*/
public function drawImage(Zend_Pdf_Resource_Image $image, $x1, $y1, $x2, $y2);
/**
* Draw a LayoutBox at the specified position on the page.
*
* @internal (not implemented now)
*
* @param Zend_Pdf_Element_LayoutBox $box
* @param float $x
* @param float $y
* @return Zend_Pdf_Canvas_Interface
*/
public function drawLayoutBox($box, $x, $y);
/**
* Draw a line from x1,y1 to x2,y2.
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @return Zend_Pdf_Canvas_Interface
*/
public function drawLine($x1, $y1, $x2, $y2);
/**
* Draw a polygon.
*
* If $fillType is Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE or
* Zend_Pdf_Page::SHAPE_DRAW_FILL, then polygon is automatically closed.
* See detailed description of these methods in a PDF documentation
* (section 4.4.2 Path painting Operators, Filling)
*
* @param array $x - array of float (the X co-ordinates of the vertices)
* @param array $y - array of float (the Y co-ordinates of the vertices)
* @param integer $fillType
* @param integer $fillMethod
* @return Zend_Pdf_Canvas_Interface
*/
public function drawPolygon($x, $y,
$fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE,
$fillMethod = Zend_Pdf_Page::FILL_METHOD_NON_ZERO_WINDING);
/**
* Draw a rectangle.
*
* Fill types:
* Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default)
* Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle
* Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param integer $fillType
* @return Zend_Pdf_Canvas_Interface
*/
public function drawRectangle($x1, $y1, $x2, $y2, $fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE);
/**
* Draw a rounded rectangle.
*
* Fill types:
* Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE - fill rectangle and stroke (default)
* Zend_Pdf_Page::SHAPE_DRAW_STROKE - stroke rectangle
* Zend_Pdf_Page::SHAPE_DRAW_FILL - fill rectangle
*
* radius is an integer representing radius of the four corners, or an array
* of four integers representing the radius starting at top left, going
* clockwise
*
* @param float $x1
* @param float $y1
* @param float $x2
* @param float $y2
* @param integer|array $radius
* @param integer $fillType
* @return Zend_Pdf_Canvas_Interface
*/
public function drawRoundedRectangle($x1, $y1, $x2, $y2, $radius,
$fillType = Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE);
/**
* Draw a line of text at the specified position.
*
* @param string $text
* @param float $x
* @param float $y
* @param string $charEncoding (optional) Character encoding of source text.
* Defaults to current locale.
* @throws Zend_Pdf_Exception
* @return Zend_Pdf_Canvas_Interface
*/
public function drawText($text, $x, $y, $charEncoding = '');
/**
* Close the path by drawing a straight line back to it's beginning.
*
* @internal (needs implementation)
*
* @throws Zend_Pdf_Exception - if a path hasn't been started with pathMove()
* @return Zend_Pdf_Canvas_Interface
*/
public function pathClose();
/**
* Continue the open path in a straight line to the specified position.
*
* @internal (needs implementation)
*
* @param float $x - the X co-ordinate to move to
* @param float $y - the Y co-ordinate to move to
* @return Zend_Pdf_Canvas_Interface
*/
public function pathLine($x, $y);
/**
* Start a new path at the specified position. If a path has already been started,
* move the cursor without drawing a line.
*
* @internal (needs implementation)
*
* @param float $x - the X co-ordinate to move to
* @param float $y - the Y co-ordinate to move to
* @return Zend_Pdf_Canvas_Interface
*/
public function pathMove($x, $y);
/**
* Rotate the page.
*
* @param float $x - the X co-ordinate of rotation point
* @param float $y - the Y co-ordinate of rotation point
* @param float $angle - rotation angle
* @return Zend_Pdf_Canvas_Interface
*/
public function rotate($x, $y, $angle);
/**
* Scale coordination system.
*
* @param float $xScale - X dimention scale factor
* @param float $yScale - Y dimention scale factor
* @return Zend_Pdf_Canvas_Interface
*/
public function scale($xScale, $yScale);
/**
* Translate coordination system.
*
* @param float $xShift - X coordinate shift
* @param float $yShift - Y coordinate shift
* @return Zend_Pdf_Canvas_Interface
*/
public function translate($xShift, $yShift);
/**
* Translate coordination system.
*
* @param float $x - the X co-ordinate of axis skew point
* @param float $y - the Y co-ordinate of axis skew point
* @param float $xAngle - X axis skew angle
* @param float $yAngle - Y axis skew angle
* @return Zend_Pdf_Canvas_Interface
*/
public function skew($x, $y, $xAngle, $yAngle);
/**
* Writes the raw data to the page's content stream.
*
* Be sure to consult the PDF reference to ensure your syntax is correct. No
* attempt is made to ensure the validity of the stream data.
*
* @param string $data
* @param string $procSet (optional) Name of ProcSet to add.
* @return Zend_Pdf_Canvas_Interface
*/
public function rawWrite($data, $procSet = null);
}

336
library/Zend/Pdf/Cmap.php Normal file
View File

@ -0,0 +1,336 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Cmap.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Abstract helper class for {@link Zend_Pdf_Resource_Font} which manages font
* character maps.
*
* Defines the public interface for concrete subclasses which are responsible
* for mapping Unicode characters to the font's glyph numbers. Also provides
* shared utility methods.
*
* Cmap objects should ordinarily be obtained through the factory method
* {@link cmapWithTypeData()}.
*
* The supported character map types are those found in the OpenType spec. For
* additional detail on the internal binary format of these tables, see:
* <ul>
* <li>{@link http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6cmap.html}
* <li>{@link http://www.microsoft.com/OpenType/OTSpec/cmap.htm}
* <li>{@link http://partners.adobe.com/public/developer/opentype/index_cmap.html}
* </ul>
*
* @todo Write code for Zend_Pdf_FontCmap_HighByteMapping class.
* @todo Write code for Zend_Pdf_FontCmap_MixedCoverage class.
* @todo Write code for Zend_Pdf_FontCmap_TrimmedArray class.
* @todo Write code for Zend_Pdf_FontCmap_SegmentedCoverage class.
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Cmap
{
/**** Class Constants ****/
/* Cmap Table Types */
/**
* Byte Encoding character map table type.
*/
const TYPE_BYTE_ENCODING = 0x00;
/**
* High Byte Mapping character map table type.
*/
const TYPE_HIGH_BYTE_MAPPING = 0x02;
/**
* Segment Value to Delta Mapping character map table type.
*/
const TYPE_SEGMENT_TO_DELTA = 0x04;
/**
* Trimmed Table character map table type.
*/
const TYPE_TRIMMED_TABLE = 0x06;
/**
* Mixed Coverage character map table type.
*/
const TYPE_MIXED_COVERAGE = 0x08;
/**
* Trimmed Array character map table type.
*/
const TYPE_TRIMMED_ARRAY = 0x0a;
/**
* Segmented Coverage character map table type.
*/
const TYPE_SEGMENTED_COVERAGE = 0x0c;
/**
* Static Byte Encoding character map table type. Variant of
* {@link TYPE_BYTEENCODING}.
*/
const TYPE_BYTE_ENCODING_STATIC = 0xf1;
/**
* Unknown character map table type.
*/
const TYPE_UNKNOWN = 0xff;
/* Special Glyph Names */
/**
* Glyph representing missing characters.
*/
const MISSING_CHARACTER_GLYPH = 0x00;
/**** Public Interface ****/
/* Factory Methods */
/**
* Instantiates the appropriate concrete subclass based on the type of cmap
* table and returns the instance.
*
* The cmap type must be one of the following values:
* <ul>
* <li>{@link Zend_Pdf_Cmap::TYPE_BYTE_ENCODING}
* <li>{@link Zend_Pdf_Cmap::TYPE_BYTE_ENCODING_STATIC}
* <li>{@link Zend_Pdf_Cmap::TYPE_HIGH_BYTE_MAPPING}
* <li>{@link Zend_Pdf_Cmap::TYPE_SEGMENT_TO_DELTA}
* <li>{@link Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE}
* <li>{@link Zend_Pdf_Cmap::TYPE_MIXED_COVERAGE}
* <li>{@link Zend_Pdf_Cmap::TYPE_TRIMMED_ARRAY}
* <li>{@link Zend_Pdf_Cmap::TYPE_SEGMENTED_COVERAGE}
* </ul>
*
* Throws an exception if the table type is invalid or the cmap table data
* cannot be validated.
*
* @param integer $cmapType Type of cmap.
* @param mixed $cmapData Cmap table data. Usually a string or array.
* @return Zend_Pdf_Cmap
* @throws Zend_Pdf_Exception
*/
public static function cmapWithTypeData($cmapType, $cmapData)
{
switch ($cmapType) {
case Zend_Pdf_Cmap::TYPE_BYTE_ENCODING:
// require_once 'Zend/Pdf/Cmap/ByteEncoding.php';
return new Zend_Pdf_Cmap_ByteEncoding($cmapData);
case Zend_Pdf_Cmap::TYPE_BYTE_ENCODING_STATIC:
// require_once 'Zend/Pdf/Cmap/ByteEncoding/Static.php';
return new Zend_Pdf_Cmap_ByteEncoding_Static($cmapData);
case Zend_Pdf_Cmap::TYPE_HIGH_BYTE_MAPPING:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('High byte mapping cmap currently unsupported',
Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
case Zend_Pdf_Cmap::TYPE_SEGMENT_TO_DELTA:
// require_once 'Zend/Pdf/Cmap/SegmentToDelta.php';
return new Zend_Pdf_Cmap_SegmentToDelta($cmapData);
case Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE:
// require_once 'Zend/Pdf/Cmap/TrimmedTable.php';
return new Zend_Pdf_Cmap_TrimmedTable($cmapData);
case Zend_Pdf_Cmap::TYPE_MIXED_COVERAGE:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Mixed coverage cmap currently unsupported',
Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
case Zend_Pdf_Cmap::TYPE_TRIMMED_ARRAY:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Trimmed array cmap currently unsupported',
Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
case Zend_Pdf_Cmap::TYPE_SEGMENTED_COVERAGE:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Segmented coverage cmap currently unsupported',
Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Unknown cmap type: $cmapType",
Zend_Pdf_Exception::CMAP_UNKNOWN_TYPE);
}
}
/* Abstract Methods */
/**
* Object constructor
*
* Parses the raw binary table data. Throws an exception if the table is
* malformed.
*
* @param string $cmapData Raw binary cmap table data.
* @throws Zend_Pdf_Exception
*/
abstract public function __construct($cmapData);
/**
* Returns an array of glyph numbers corresponding to the Unicode characters.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumberForCharacter()}.
*
* @param array $characterCodes Array of Unicode character codes (code points).
* @return array Array of glyph numbers.
*/
abstract public function glyphNumbersForCharacters($characterCodes);
/**
* Returns the glyph number corresponding to the Unicode character.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumbersForCharacters()} which is optimized for bulk
* operations.
*
* @param integer $characterCode Unicode character code (code point).
* @return integer Glyph number.
*/
abstract public function glyphNumberForCharacter($characterCode);
/**
* Returns an array containing the Unicode characters that have entries in
* this character map.
*
* @return array Unicode character codes.
*/
abstract public function getCoveredCharacters();
/**
* Returns an array containing the glyphs numbers that have entries in this character map.
* Keys are Unicode character codes (integers)
*
* This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
* call, but this method do it in more effective way (prepare complete list instead of searching
* glyph for each character code).
*
* @internal
* @return array Array representing <Unicode character code> => <glyph number> pairs.
*/
abstract public function getCoveredCharactersGlyphs();
/**** Internal Methods ****/
/* Internal Utility Methods */
/**
* Extracts a signed 2-byte integer from a string.
*
* Integers are always big-endian. Throws an exception if the index is out
* of range.
*
* @param string &$data
* @param integer $index Position in string of integer.
* @return integer
* @throws Zend_Pdf_Exception
*/
protected function _extractInt2(&$data, $index)
{
if (($index < 0) | (($index + 1) > strlen($data))) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Index out of range: $index",
Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
}
$number = ord($data[$index]);
if (($number & 0x80) == 0x80) { // negative
$number = ~((((~ $number) & 0xff) << 8) | ((~ ord($data[++$index])) & 0xff));
} else {
$number = ($number << 8) | ord($data[++$index]);
}
return $number;
}
/**
* Extracts an unsigned 2-byte integer from a string.
*
* Integers are always big-endian. Throws an exception if the index is out
* of range.
*
* @param string &$data
* @param integer $index Position in string of integer.
* @return integer
* @throws Zend_Pdf_Exception
*/
protected function _extractUInt2(&$data, $index)
{
if (($index < 0) | (($index + 1) > strlen($data))) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Index out of range: $index",
Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
}
$number = (ord($data[$index]) << 8) | ord($data[++$index]);
return $number;
}
/**
* Extracts an unsigned 4-byte integer from a string.
*
* Integers are always big-endian. Throws an exception if the index is out
* of range.
*
* NOTE: If you ask for a 4-byte unsigned integer on a 32-bit machine, the
* resulting value WILL BE SIGNED because PHP uses signed integers internally
* for everything. To guarantee portability, be sure to use bitwise or
* similar operators on large integers!
*
* @param string &$data
* @param integer $index Position in string of integer.
* @return integer
* @throws Zend_Pdf_Exception
*/
protected function _extractUInt4(&$data, $index)
{
if (($index < 0) | (($index + 3) > strlen($data))) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Index out of range: $index",
Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
}
$number = (ord($data[$index]) << 24) | (ord($data[++$index]) << 16) |
(ord($data[++$index]) << 8) | ord($data[++$index]);
return $number;
}
}

View File

@ -0,0 +1,447 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ByteEncoding.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Cmap */
// require_once 'Zend/Pdf/Cmap.php';
/**
* Implements the "byte encoding" character map (type 0).
*
* This is the (legacy) Apple standard encoding mechanism and provides coverage
* for characters in the Mac Roman character set only. Consequently, this cmap
* type should be used only as a last resort.
*
* The mapping from Mac Roman to Unicode can be found at
* {@link http://www.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ROMAN.TXT}.
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Cmap_ByteEncoding extends Zend_Pdf_Cmap
{
/**** Instance Variables ****/
/**
* Glyph index array. Stores the actual glyph numbers. The array keys are
* the translated Unicode code points.
* @var array
*/
protected $_glyphIndexArray = array();
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Returns an array of glyph numbers corresponding to the Unicode characters.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumberForCharacter()}.
*
* @param array $characterCodes Array of Unicode character codes (code points).
* @return array Array of glyph numbers.
*/
public function glyphNumbersForCharacters($characterCodes)
{
$glyphNumbers = array();
foreach ($characterCodes as $key => $characterCode) {
if (! isset($this->_glyphIndexArray[$characterCode])) {
$glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
continue;
}
$glyphNumbers[$key] = $this->_glyphIndexArray[$characterCode];
}
return $glyphNumbers;
}
/**
* Returns the glyph number corresponding to the Unicode character.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumbersForCharacters()} which is optimized for bulk
* operations.
*
* @param integer $characterCode Unicode character code (code point).
* @return integer Glyph number.
*/
public function glyphNumberForCharacter($characterCode)
{
if (! isset($this->_glyphIndexArray[$characterCode])) {
return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
}
return $this->_glyphIndexArray[$characterCode];
}
/**
* Returns an array containing the Unicode characters that have entries in
* this character map.
*
* @return array Unicode character codes.
*/
public function getCoveredCharacters()
{
return array_keys($this->_glyphIndexArray);
}
/**
* Returns an array containing the glyphs numbers that have entries in this character map.
* Keys are Unicode character codes (integers)
*
* This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
* call, but this method do it in more effective way (prepare complete list instead of searching
* glyph for each character code).
*
* @internal
* @return array Array representing <Unicode character code> => <glyph number> pairs.
*/
public function getCoveredCharactersGlyphs()
{
return $this->_glyphIndexArray;
}
/* Object Lifecycle */
/**
* Object constructor
*
* Parses the raw binary table data. Throws an exception if the table is
* malformed.
*
* @param string $cmapData Raw binary cmap table data.
* @throws Zend_Pdf_Exception
*/
public function __construct($cmapData)
{
/* Sanity check: This table must be exactly 262 bytes long.
*/
$actualLength = strlen($cmapData);
if ($actualLength != 262) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Insufficient table data',
Zend_Pdf_Exception::CMAP_TABLE_DATA_TOO_SMALL);
}
/* Sanity check: Make sure this is right data for this table type.
*/
$type = $this->_extractUInt2($cmapData, 0);
if ($type != Zend_Pdf_Cmap::TYPE_BYTE_ENCODING) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong cmap table type',
Zend_Pdf_Exception::CMAP_WRONG_TABLE_TYPE);
}
$length = $this->_extractUInt2($cmapData, 2);
if ($length != $actualLength) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Table length ($length) does not match actual length ($actualLength)",
Zend_Pdf_Exception::CMAP_WRONG_TABLE_LENGTH);
}
/* Mapping tables should be language-independent. The font may not work
* as expected if they are not. Unfortunately, many font files in the
* wild incorrectly record a language ID in this field, so we can't
* call this a failure.
*/
$language = $this->_extractUInt2($cmapData, 4);
if ($language != 0) {
// Record a warning here somehow?
}
/* The mapping between the Mac Roman and Unicode characters is static.
* For simplicity, just put all 256 glyph indices into one array keyed
* off the corresponding Unicode character.
*/
$i = 6;
$this->_glyphIndexArray[0x00] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x01] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x03] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x04] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x05] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x06] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x07] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x08] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x09] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x10] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x11] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x12] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x13] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x14] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x15] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x16] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x17] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x18] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x19] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x1f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x20] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x21] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x22] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x23] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x24] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x25] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x26] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x27] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x28] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x29] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x30] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x31] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x32] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x33] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x34] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x35] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x36] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x37] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x38] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x39] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x3f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x40] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x41] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x42] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x43] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x44] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x45] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x46] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x47] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x48] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x49] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x4f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x50] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x51] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x52] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x53] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x54] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x55] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x56] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x57] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x58] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x59] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x5f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x60] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x61] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x62] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x63] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x64] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x65] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x66] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x67] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x68] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x69] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x6f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x70] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x71] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x72] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x73] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x74] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x75] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x76] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x77] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x78] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x79] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x7f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc4] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc7] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xdc] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe0] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe2] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe4] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe3] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe7] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xea] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xeb] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xed] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xec] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xee] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xef] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf3] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf2] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf4] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xfa] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xfb] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xfc] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2020] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb0] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa2] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa3] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa7] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2022] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xdf] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xae] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2122] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb4] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2260] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x221e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2264] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2265] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2202] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2211] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x220f] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x03c0] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x222b] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xaa] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xba] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x03a9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xe6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xbf] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xac] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x221a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0192] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2248] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2206] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xab] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xbb] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2026] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xa0] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc0] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc3] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd5] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0152] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0153] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2013] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2014] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x201c] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x201d] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2018] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2019] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf7] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x25ca] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xff] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0178] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2044] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x20ac] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2039] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x203a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xfb01] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xfb02] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2021] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb7] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x201a] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x201e] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x2030] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc2] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xca] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc1] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xcb] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xc8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xcd] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xce] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xcf] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xcc] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd3] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd4] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xf8ff] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd2] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xda] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xdb] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xd9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x0131] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02c6] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02dc] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xaf] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02d8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02d9] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02da] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0xb8] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02dd] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02db] = ord($cmapData[$i++]);
$this->_glyphIndexArray[0x02c7] = ord($cmapData[$i]);
}
}

View File

@ -0,0 +1,62 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Static.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Cmap_ByteEncoding */
// require_once 'Zend/Pdf/Cmap/ByteEncoding.php';
/**
* Custom cmap type used for the Adobe Standard 14 PDF fonts.
*
* Just like {@link Zend_Pdf_Cmap_ByteEncoding} except that the constructor
* takes a predefined array of glyph numbers and can cover any Unicode character.
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Cmap_ByteEncoding_Static extends Zend_Pdf_Cmap_ByteEncoding
{
/**** Public Interface ****/
/* Object Lifecycle */
/**
* Object constructor
*
* @param array $cmapData Array whose keys are Unicode character codes and
* values are glyph numbers.
* @throws Zend_Pdf_Exception
*/
public function __construct($cmapData)
{
if (! is_array($cmapData)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Constructor parameter must be an array',
Zend_Pdf_Exception::BAD_PARAMETER_TYPE);
}
$this->_glyphIndexArray = $cmapData;
}
}

View File

@ -0,0 +1,407 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: SegmentToDelta.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Cmap */
// require_once 'Zend/Pdf/Cmap.php';
/**
* Implements the "segment mapping to delta values" character map (type 4).
*
* This is the Microsoft standard mapping table type for OpenType fonts. It
* provides the ability to cover multiple contiguous ranges of the Unicode
* character set, with the exception of Unicode Surrogates (U+D800 - U+DFFF).
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Cmap_SegmentToDelta extends Zend_Pdf_Cmap
{
/**** Instance Variables ****/
/**
* The number of segments in the table.
* @var integer
*/
protected $_segmentCount = 0;
/**
* The size of the binary search range for segments.
* @var integer
*/
protected $_searchRange = 0;
/**
* The number of binary search steps required to cover the entire search
* range.
* @var integer
*/
protected $_searchIterations = 0;
/**
* Array of ending character codes for each segment.
* @var array
*/
protected $_segmentTableEndCodes = array();
/**
* The ending character code for the segment at the end of the low search
* range.
* @var integer
*/
protected $_searchRangeEndCode = 0;
/**
* Array of starting character codes for each segment.
* @var array
*/
protected $_segmentTableStartCodes = array();
/**
* Array of character code to glyph delta values for each segment.
* @var array
*/
protected $_segmentTableIdDeltas = array();
/**
* Array of offsets into the glyph index array for each segment.
* @var array
*/
protected $_segmentTableIdRangeOffsets = array();
/**
* Glyph index array. Stores glyph numbers, used with range offset.
* @var array
*/
protected $_glyphIndexArray = array();
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Returns an array of glyph numbers corresponding to the Unicode characters.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumberForCharacter()}.
*
* @param array $characterCodes Array of Unicode character codes (code points).
* @return array Array of glyph numbers.
*/
public function glyphNumbersForCharacters($characterCodes)
{
$glyphNumbers = array();
foreach ($characterCodes as $key => $characterCode) {
/* These tables only cover the 16-bit character range.
*/
if ($characterCode > 0xffff) {
$glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
continue;
}
/* Determine where to start the binary search. The segments are
* ordered from lowest-to-highest. We are looking for the first
* segment whose end code is greater than or equal to our character
* code.
*
* If the end code at the top of the search range is larger, then
* our target is probably below it.
*
* If it is smaller, our target is probably above it, so move the
* search range to the end of the segment list.
*/
if ($this->_searchRangeEndCode >= $characterCode) {
$searchIndex = $this->_searchRange;
} else {
$searchIndex = $this->_segmentCount;
}
/* Now do a binary search to find the first segment whose end code
* is greater or equal to our character code. No matter the number
* of segments (there may be hundreds in a large font), we will only
* need to perform $this->_searchIterations.
*/
for ($i = 1; $i <= $this->_searchIterations; $i++) {
if ($this->_segmentTableEndCodes[$searchIndex] >= $characterCode) {
$subtableIndex = $searchIndex;
$searchIndex -= $this->_searchRange >> $i;
} else {
$searchIndex += $this->_searchRange >> $i;
}
}
/* If the segment's start code is greater than our character code,
* that character is not represented in this font. Move on.
*/
if ($this->_segmentTableStartCodes[$subtableIndex] > $characterCode) {
$glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
continue;
}
if ($this->_segmentTableIdRangeOffsets[$subtableIndex] == 0) {
/* This segment uses a simple mapping from character code to
* glyph number.
*/
$glyphNumbers[$key] = ($characterCode + $this->_segmentTableIdDeltas[$subtableIndex]) % 65536;
} else {
/* This segment relies on the glyph index array to determine the
* glyph number. The calculation below determines the correct
* index into that array. It's a little odd because the range
* offset in the font file is designed to quickly provide an
* address of the index in the raw binary data instead of the
* index itself. Since we've parsed the data into arrays, we
* must process it a bit differently.
*/
$glyphIndex = ($characterCode - $this->_segmentTableStartCodes[$subtableIndex] +
$this->_segmentTableIdRangeOffsets[$subtableIndex] - $this->_segmentCount +
$subtableIndex - 1);
$glyphNumbers[$key] = $this->_glyphIndexArray[$glyphIndex];
}
}
return $glyphNumbers;
}
/**
* Returns the glyph number corresponding to the Unicode character.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumbersForCharacters()} which is optimized for bulk
* operations.
*
* @param integer $characterCode Unicode character code (code point).
* @return integer Glyph number.
*/
public function glyphNumberForCharacter($characterCode)
{
/* This code is pretty much a copy of glyphNumbersForCharacters().
* See that method for inline documentation.
*/
if ($characterCode > 0xffff) {
return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
}
if ($this->_searchRangeEndCode >= $characterCode) {
$searchIndex = $this->_searchRange;
} else {
$searchIndex = $this->_segmentCount;
}
for ($i = 1; $i <= $this->_searchIterations; $i++) {
if ($this->_segmentTableEndCodes[$searchIndex] >= $characterCode) {
$subtableIndex = $searchIndex;
$searchIndex -= $this->_searchRange >> $i;
} else {
$searchIndex += $this->_searchRange >> $i;
}
}
if ($this->_segmentTableStartCodes[$subtableIndex] > $characterCode) {
return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
}
if ($this->_segmentTableIdRangeOffsets[$subtableIndex] == 0) {
$glyphNumber = ($characterCode + $this->_segmentTableIdDeltas[$subtableIndex]) % 65536;
} else {
$glyphIndex = ($characterCode - $this->_segmentTableStartCodes[$subtableIndex] +
$this->_segmentTableIdRangeOffsets[$subtableIndex] - $this->_segmentCount +
$subtableIndex - 1);
$glyphNumber = $this->_glyphIndexArray[$glyphIndex];
}
return $glyphNumber;
}
/**
* Returns an array containing the Unicode characters that have entries in
* this character map.
*
* @return array Unicode character codes.
*/
public function getCoveredCharacters()
{
$characterCodes = array();
for ($i = 1; $i <= $this->_segmentCount; $i++) {
for ($code = $this->_segmentTableStartCodes[$i]; $code <= $this->_segmentTableEndCodes[$i]; $code++) {
$characterCodes[] = $code;
}
}
return $characterCodes;
}
/**
* Returns an array containing the glyphs numbers that have entries in this character map.
* Keys are Unicode character codes (integers)
*
* This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
* call, but this method do it in more effective way (prepare complete list instead of searching
* glyph for each character code).
*
* @internal
* @return array Array representing <Unicode character code> => <glyph number> pairs.
*/
public function getCoveredCharactersGlyphs()
{
$glyphNumbers = array();
for ($segmentNum = 1; $segmentNum <= $this->_segmentCount; $segmentNum++) {
if ($this->_segmentTableIdRangeOffsets[$segmentNum] == 0) {
$delta = $this->_segmentTableIdDeltas[$segmentNum];
for ($code = $this->_segmentTableStartCodes[$segmentNum];
$code <= $this->_segmentTableEndCodes[$segmentNum];
$code++) {
$glyphNumbers[$code] = ($code + $delta) % 65536;
}
} else {
$code = $this->_segmentTableStartCodes[$segmentNum];
$glyphIndex = $this->_segmentTableIdRangeOffsets[$segmentNum] - ($this->_segmentCount - $segmentNum) - 1;
while ($code <= $this->_segmentTableEndCodes[$segmentNum]) {
$glyphNumbers[$code] = $this->_glyphIndexArray[$glyphIndex];
$code++;
$glyphIndex++;
}
}
}
return $glyphNumbers;
}
/* Object Lifecycle */
/**
* Object constructor
*
* Parses the raw binary table data. Throws an exception if the table is
* malformed.
*
* @param string $cmapData Raw binary cmap table data.
* @throws Zend_Pdf_Exception
*/
public function __construct($cmapData)
{
/* Sanity check: The table should be at least 23 bytes in size.
*/
$actualLength = strlen($cmapData);
if ($actualLength < 23) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Insufficient table data',
Zend_Pdf_Exception::CMAP_TABLE_DATA_TOO_SMALL);
}
/* Sanity check: Make sure this is right data for this table type.
*/
$type = $this->_extractUInt2($cmapData, 0);
if ($type != Zend_Pdf_Cmap::TYPE_SEGMENT_TO_DELTA) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong cmap table type',
Zend_Pdf_Exception::CMAP_WRONG_TABLE_TYPE);
}
$length = $this->_extractUInt2($cmapData, 2);
if ($length != $actualLength) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Table length ($length) does not match actual length ($actualLength)",
Zend_Pdf_Exception::CMAP_WRONG_TABLE_LENGTH);
}
/* Mapping tables should be language-independent. The font may not work
* as expected if they are not. Unfortunately, many font files in the
* wild incorrectly record a language ID in this field, so we can't
* call this a failure.
*/
$language = $this->_extractUInt2($cmapData, 4);
if ($language != 0) {
// Record a warning here somehow?
}
/* These two values are stored premultiplied by two which is convienent
* when using the binary data directly, but we're parsing it out to
* native PHP data types, so divide by two.
*/
$this->_segmentCount = $this->_extractUInt2($cmapData, 6) >> 1;
$this->_searchRange = $this->_extractUInt2($cmapData, 8) >> 1;
$this->_searchIterations = $this->_extractUInt2($cmapData, 10) + 1;
$offset = 14;
for ($i = 1; $i <= $this->_segmentCount; $i++, $offset += 2) {
$this->_segmentTableEndCodes[$i] = $this->_extractUInt2($cmapData, $offset);
}
$this->_searchRangeEndCode = $this->_segmentTableEndCodes[$this->_searchRange];
$offset += 2; // reserved bytes
for ($i = 1; $i <= $this->_segmentCount; $i++, $offset += 2) {
$this->_segmentTableStartCodes[$i] = $this->_extractUInt2($cmapData, $offset);
}
for ($i = 1; $i <= $this->_segmentCount; $i++, $offset += 2) {
$this->_segmentTableIdDeltas[$i] = $this->_extractInt2($cmapData, $offset); // signed
}
/* The range offset helps determine the index into the glyph index array.
* Like the segment count and search range above, it's stored as a byte
* multiple in the font, so divide by two as we extract the values.
*/
for ($i = 1; $i <= $this->_segmentCount; $i++, $offset += 2) {
$this->_segmentTableIdRangeOffsets[$i] = $this->_extractUInt2($cmapData, $offset) >> 1;
}
/* The size of the glyph index array varies by font and depends on the
* extent of the usage of range offsets versus deltas. Some fonts may
* not have any entries in this array.
*/
for (; $offset < $length; $offset += 2) {
$this->_glyphIndexArray[] = $this->_extractUInt2($cmapData, $offset);
}
/* Sanity check: After reading all of the data, we should be at the end
* of the table.
*/
if ($offset != $length) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Ending offset ($offset) does not match length ($length)",
Zend_Pdf_Exception::CMAP_FINAL_OFFSET_NOT_LENGTH);
}
}
}

View File

@ -0,0 +1,231 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: TrimmedTable.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Cmap */
// require_once 'Zend/Pdf/Cmap.php';
/**
* Implements the "trimmed table mapping" character map (type 6).
*
* This table type is preferred over the {@link Zend_Pdf_Cmap_SegmentToDelta}
* table when the Unicode characters covered by the font fall into a single
* contiguous range.
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Cmap_TrimmedTable extends Zend_Pdf_Cmap
{
/**** Instance Variables ****/
/**
* The starting character code covered by this table.
* @var integer
*/
protected $_startCode = 0;
/**
* The ending character code covered by this table.
* @var integer
*/
protected $_endCode = 0;
/**
* Glyph index array. Stores the actual glyph numbers.
* @var array
*/
protected $_glyphIndexArray = array();
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Returns an array of glyph numbers corresponding to the Unicode characters.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumberForCharacter()}.
*
* @param array $characterCodes Array of Unicode character codes (code points).
* @return array Array of glyph numbers.
*/
public function glyphNumbersForCharacters($characterCodes)
{
$glyphNumbers = array();
foreach ($characterCodes as $key => $characterCode) {
if (($characterCode < $this->_startCode) || ($characterCode > $this->_endCode)) {
$glyphNumbers[$key] = Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
continue;
}
$glyphIndex = $characterCode - $this->_startCode;
$glyphNumbers[$key] = $this->_glyphIndexArray[$glyphIndex];
}
return $glyphNumbers;
}
/**
* Returns the glyph number corresponding to the Unicode character.
*
* If a particular character doesn't exist in this font, the special 'missing
* character glyph' will be substituted.
*
* See also {@link glyphNumbersForCharacters()} which is optimized for bulk
* operations.
*
* @param integer $characterCode Unicode character code (code point).
* @return integer Glyph number.
*/
public function glyphNumberForCharacter($characterCode)
{
if (($characterCode < $this->_startCode) || ($characterCode > $this->_endCode)) {
return Zend_Pdf_Cmap::MISSING_CHARACTER_GLYPH;
}
$glyphIndex = $characterCode - $this->_startCode;
return $this->_glyphIndexArray[$glyphIndex];
}
/**
* Returns an array containing the Unicode characters that have entries in
* this character map.
*
* @return array Unicode character codes.
*/
public function getCoveredCharacters()
{
$characterCodes = array();
for ($code = $this->_startCode; $code <= $this->_endCode; $code++) {
$characterCodes[] = $code;
}
return $characterCodes;
}
/**
* Returns an array containing the glyphs numbers that have entries in this character map.
* Keys are Unicode character codes (integers)
*
* This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
* call, but this method do it in more effective way (prepare complete list instead of searching
* glyph for each character code).
*
* @internal
* @return array Array representing <Unicode character code> => <glyph number> pairs.
*/
public function getCoveredCharactersGlyphs()
{
$glyphNumbers = array();
for ($code = $this->_startCode; $code <= $this->_endCode; $code++) {
$glyphNumbers[$code] = $this->_glyphIndexArray[$code - $this->_startCode];
}
return $glyphNumbers;
}
/* Object Lifecycle */
/**
* Object constructor
*
* Parses the raw binary table data. Throws an exception if the table is
* malformed.
*
* @param string $cmapData Raw binary cmap table data.
* @throws Zend_Pdf_Exception
*/
public function __construct($cmapData)
{
/* Sanity check: The table should be at least 9 bytes in size.
*/
$actualLength = strlen($cmapData);
if ($actualLength < 9) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Insufficient table data',
Zend_Pdf_Exception::CMAP_TABLE_DATA_TOO_SMALL);
}
/* Sanity check: Make sure this is right data for this table type.
*/
$type = $this->_extractUInt2($cmapData, 0);
if ($type != Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong cmap table type',
Zend_Pdf_Exception::CMAP_WRONG_TABLE_TYPE);
}
$length = $this->_extractUInt2($cmapData, 2);
if ($length != $actualLength) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Table length ($length) does not match actual length ($actualLength)",
Zend_Pdf_Exception::CMAP_WRONG_TABLE_LENGTH);
}
/* Mapping tables should be language-independent. The font may not work
* as expected if they are not. Unfortunately, many font files in the
* wild incorrectly record a language ID in this field, so we can't
* call this a failure.
*/
$language = $this->_extractUInt2($cmapData, 4);
if ($language != 0) {
// Record a warning here somehow?
}
$this->_startCode = $this->_extractUInt2($cmapData, 6);
$entryCount = $this->_extractUInt2($cmapData, 8);
$expectedCount = ($length - 10) >> 1;
if ($entryCount != $expectedCount) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Entry count is wrong; expected: $expectedCount; actual: $entryCount",
Zend_Pdf_Exception::CMAP_WRONG_ENTRY_COUNT);
}
$this->_endCode = $this->_startCode + $entryCount - 1;
$offset = 10;
for ($i = 0; $i < $entryCount; $i++, $offset += 2) {
$this->_glyphIndexArray[] = $this->_extractUInt2($cmapData, $offset);
}
/* Sanity check: After reading all of the data, we should be at the end
* of the table.
*/
if ($offset != $length) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Ending offset ($offset) does not match length ($length)",
Zend_Pdf_Exception::CMAP_FINAL_OFFSET_NOT_LENGTH);
}
}
}

View File

@ -0,0 +1,53 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Color.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF provides a powerfull facilities for specifying the colors of graphics objects.
* This class encapsulates color behaviour.
*
* Some colors interact with PDF document (create additional objects in a PDF),
* others don't do it. That is defined in a subclasses.
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Color
{
/**
* Instructions, which can be directly inserted into content stream
* to switch color.
* Color set instructions differ for stroking and nonstroking operations.
*
* @param boolean $stroking
* @return string
*/
abstract public function instructions($stroking);
/**
* Get color components (color space dependent)
*
* @return array
*/
abstract public function getComponents();
}

View File

@ -0,0 +1,126 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Cmyk.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Color */
// require_once 'Zend/Pdf/Color.php';
/**
* CMYK color implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Color_Cmyk extends Zend_Pdf_Color
{
/**
* Cyan level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_c;
/**
* Magenta level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_m;
/**
* Yellow level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_y;
/**
* Key (BlacK) level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_k;
/**
* Object constructor
*
* @param float $c
* @param float $m
* @param float $y
* @param float $k
*/
public function __construct($c, $m, $y, $k)
{
if ($c < 0) { $c = 0; }
if ($c > 1) { $c = 1; }
if ($m < 0) { $m = 0; }
if ($m > 1) { $m = 1; }
if ($y < 0) { $y = 0; }
if ($y > 1) { $y = 1; }
if ($k < 0) { $k = 0; }
if ($k > 1) { $k = 1; }
$this->_c = new Zend_Pdf_Element_Numeric($c);
$this->_m = new Zend_Pdf_Element_Numeric($m);
$this->_y = new Zend_Pdf_Element_Numeric($y);
$this->_k = new Zend_Pdf_Element_Numeric($k);
}
/**
* Instructions, which can be directly inserted into content stream
* to switch color.
* Color set instructions differ for stroking and nonstroking operations.
*
* @param boolean $stroking
* @return string
*/
public function instructions($stroking)
{
return $this->_c->toString() . ' '
. $this->_m->toString() . ' '
. $this->_y->toString() . ' '
. $this->_k->toString() . ($stroking? " K\n" : " k\n");
}
/**
* Get color components (color space dependent)
*
* @return array
*/
public function getComponents()
{
return array($this->_c->value, $this->_m->value, $this->_y->value, $this->_k->value);
}
}

View File

@ -0,0 +1,84 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GrayScale.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Color */
// require_once 'Zend/Pdf/Color.php';
/**
* GrayScale color implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Color_GrayScale extends Zend_Pdf_Color
{
/**
* GrayLevel.
* 0.0 (black) - 1.0 (white)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_grayLevel;
/**
* Object constructor
*
* @param float $grayLevel
*/
public function __construct($grayLevel)
{
if ($grayLevel < 0) { $grayLevel = 0; }
if ($grayLevel > 1) { $grayLevel = 1; }
$this->_grayLevel = new Zend_Pdf_Element_Numeric($grayLevel);
}
/**
* Instructions, which can be directly inserted into content stream
* to switch color.
* Color set instructions differ for stroking and nonstroking operations.
*
* @param boolean $stroking
* @return string
*/
public function instructions($stroking)
{
return $this->_grayLevel->toString() . ($stroking? " G\n" : " g\n");
}
/**
* Get color components (color space dependent)
*
* @return array
*/
public function getComponents()
{
return array($this->_grayLevel->value);
}
}

View File

@ -0,0 +1,412 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Html.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Color */
// require_once 'Zend/Pdf/Color.php';
/**
* HTML color implementation
*
* Factory class which vends Zend_Pdf_Color objects from typical HTML
* representations.
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Color_Html extends Zend_Pdf_Color
{
/**
* Color
*
* @var Zend_Pdf_Color
*/
private $_color;
/**
* Class constructor.
*
* @param mixed $color
* @throws Zend_Pdf_Exception
*/
public function __construct($color)
{
$this->_color = self::color($color);
}
/**
* Instructions, which can be directly inserted into content stream
* to switch color.
* Color set instructions differ for stroking and nonstroking operations.
*
* @param boolean $stroking
* @return string
*/
public function instructions($stroking)
{
return $this->_color->instructions($stroking);
}
/**
* Get color components (color space dependent)
*
* @return array
*/
public function getComponents()
{
return $this->_color->getComponents();
}
/**
* Creates a Zend_Pdf_Color object from the HTML representation.
*
* @param string $color May either be a hexidecimal number of the form
* #rrggbb or one of the 140 well-known names (black, white, blue, etc.)
* @return Zend_Pdf_Color
*/
public static function color($color)
{
$pattern = '/^#([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$/';
if (preg_match($pattern, $color, $matches)) {
$r = round((hexdec($matches[1]) / 255), 3);
$g = round((hexdec($matches[2]) / 255), 3);
$b = round((hexdec($matches[3]) / 255), 3);
if (($r == $g) && ($g == $b)) {
// require_once 'Zend/Pdf/Color/GrayScale.php';
return new Zend_Pdf_Color_GrayScale($r);
} else {
// require_once 'Zend/Pdf/Color/Rgb.php';
return new Zend_Pdf_Color_Rgb($r, $g, $b);
}
} else {
return Zend_Pdf_Color_Html::namedColor($color);
}
}
/**
* Creates a Zend_Pdf_Color object from the named color.
*
* @param string $color One of the 140 well-known color names (black, white,
* blue, etc.)
* @return Zend_Pdf_Color
*/
public static function namedColor($color)
{
switch (strtolower($color)) {
case 'aqua':
$r = 0.0; $g = 1.0; $b = 1.0; break;
case 'black':
$r = 0.0; $g = 0.0; $b = 0.0; break;
case 'blue':
$r = 0.0; $g = 0.0; $b = 1.0; break;
case 'fuchsia':
$r = 1.0; $g = 0.0; $b = 1.0; break;
case 'gray':
$r = 0.502; $g = 0.502; $b = 0.502; break;
case 'green':
$r = 0.0; $g = 0.502; $b = 0.0; break;
case 'lime':
$r = 0.0; $g = 1.0; $b = 0.0; break;
case 'maroon':
$r = 0.502; $g = 0.0; $b = 0.0; break;
case 'navy':
$r = 0.0; $g = 0.0; $b = 0.502; break;
case 'olive':
$r = 0.502; $g = 0.502; $b = 0.0; break;
case 'purple':
$r = 0.502; $g = 0.0; $b = 0.502; break;
case 'red':
$r = 1.0; $g = 0.0; $b = 0.0; break;
case 'silver':
$r = 0.753; $g = 0.753; $b = 0.753; break;
case 'teal':
$r = 0.0; $g = 0.502; $b = 0.502; break;
case 'white':
$r = 1.0; $g = 1.0; $b = 1.0; break;
case 'yellow':
$r = 1.0; $g = 1.0; $b = 0.0; break;
case 'aliceblue':
$r = 0.941; $g = 0.973; $b = 1.0; break;
case 'antiquewhite':
$r = 0.980; $g = 0.922; $b = 0.843; break;
case 'aquamarine':
$r = 0.498; $g = 1.0; $b = 0.831; break;
case 'azure':
$r = 0.941; $g = 1.0; $b = 1.0; break;
case 'beige':
$r = 0.961; $g = 0.961; $b = 0.863; break;
case 'bisque':
$r = 1.0; $g = 0.894; $b = 0.769; break;
case 'blanchedalmond':
$r = 1.0; $g = 1.0; $b = 0.804; break;
case 'blueviolet':
$r = 0.541; $g = 0.169; $b = 0.886; break;
case 'brown':
$r = 0.647; $g = 0.165; $b = 0.165; break;
case 'burlywood':
$r = 0.871; $g = 0.722; $b = 0.529; break;
case 'cadetblue':
$r = 0.373; $g = 0.620; $b = 0.627; break;
case 'chartreuse':
$r = 0.498; $g = 1.0; $b = 0.0; break;
case 'chocolate':
$r = 0.824; $g = 0.412; $b = 0.118; break;
case 'coral':
$r = 1.0; $g = 0.498; $b = 0.314; break;
case 'cornflowerblue':
$r = 0.392; $g = 0.584; $b = 0.929; break;
case 'cornsilk':
$r = 1.0; $g = 0.973; $b = 0.863; break;
case 'crimson':
$r = 0.863; $g = 0.078; $b = 0.235; break;
case 'cyan':
$r = 0.0; $g = 1.0; $b = 1.0; break;
case 'darkblue':
$r = 0.0; $g = 0.0; $b = 0.545; break;
case 'darkcyan':
$r = 0.0; $g = 0.545; $b = 0.545; break;
case 'darkgoldenrod':
$r = 0.722; $g = 0.525; $b = 0.043; break;
case 'darkgray':
$r = 0.663; $g = 0.663; $b = 0.663; break;
case 'darkgreen':
$r = 0.0; $g = 0.392; $b = 0.0; break;
case 'darkkhaki':
$r = 0.741; $g = 0.718; $b = 0.420; break;
case 'darkmagenta':
$r = 0.545; $g = 0.0; $b = 0.545; break;
case 'darkolivegreen':
$r = 0.333; $g = 0.420; $b = 0.184; break;
case 'darkorange':
$r = 1.0; $g = 0.549; $b = 0.0; break;
case 'darkorchid':
$r = 0.6; $g = 0.196; $b = 0.8; break;
case 'darkred':
$r = 0.545; $g = 0.0; $b = 0.0; break;
case 'darksalmon':
$r = 0.914; $g = 0.588; $b = 0.478; break;
case 'darkseagreen':
$r = 0.561; $g = 0.737; $b = 0.561; break;
case 'darkslateblue':
$r = 0.282; $g = 0.239; $b = 0.545; break;
case 'darkslategray':
$r = 0.184; $g = 0.310; $b = 0.310; break;
case 'darkturquoise':
$r = 0.0; $g = 0.808; $b = 0.820; break;
case 'darkviolet':
$r = 0.580; $g = 0.0; $b = 0.827; break;
case 'deeppink':
$r = 1.0; $g = 0.078; $b = 0.576; break;
case 'deepskyblue':
$r = 0.0; $g = 0.749; $b = 1.0; break;
case 'dimgray':
$r = 0.412; $g = 0.412; $b = 0.412; break;
case 'dodgerblue':
$r = 0.118; $g = 0.565; $b = 1.0; break;
case 'firebrick':
$r = 0.698; $g = 0.133; $b = 0.133; break;
case 'floralwhite':
$r = 1.0; $g = 0.980; $b = 0.941; break;
case 'forestgreen':
$r = 0.133; $g = 0.545; $b = 0.133; break;
case 'gainsboro':
$r = 0.863; $g = 0.863; $b = 0.863; break;
case 'ghostwhite':
$r = 0.973; $g = 0.973; $b = 1.0; break;
case 'gold':
$r = 1.0; $g = 0.843; $b = 0.0; break;
case 'goldenrod':
$r = 0.855; $g = 0.647; $b = 0.125; break;
case 'greenyellow':
$r = 0.678; $g = 1.0; $b = 0.184; break;
case 'honeydew':
$r = 0.941; $g = 1.0; $b = 0.941; break;
case 'hotpink':
$r = 1.0; $g = 0.412; $b = 0.706; break;
case 'indianred':
$r = 0.804; $g = 0.361; $b = 0.361; break;
case 'indigo':
$r = 0.294; $g = 0.0; $b = 0.510; break;
case 'ivory':
$r = 1.0; $g = 0.941; $b = 0.941; break;
case 'khaki':
$r = 0.941; $g = 0.902; $b = 0.549; break;
case 'lavender':
$r = 0.902; $g = 0.902; $b = 0.980; break;
case 'lavenderblush':
$r = 1.0; $g = 0.941; $b = 0.961; break;
case 'lawngreen':
$r = 0.486; $g = 0.988; $b = 0.0; break;
case 'lemonchiffon':
$r = 1.0; $g = 0.980; $b = 0.804; break;
case 'lightblue':
$r = 0.678; $g = 0.847; $b = 0.902; break;
case 'lightcoral':
$r = 0.941; $g = 0.502; $b = 0.502; break;
case 'lightcyan':
$r = 0.878; $g = 1.0; $b = 1.0; break;
case 'lightgoldenrodyellow':
$r = 0.980; $g = 0.980; $b = 0.824; break;
case 'lightgreen':
$r = 0.565; $g = 0.933; $b = 0.565; break;
case 'lightgrey':
$r = 0.827; $g = 0.827; $b = 0.827; break;
case 'lightpink':
$r = 1.0; $g = 0.714; $b = 0.757; break;
case 'lightsalmon':
$r = 1.0; $g = 0.627; $b = 0.478; break;
case 'lightseagreen':
$r = 0.125; $g = 0.698; $b = 0.667; break;
case 'lightskyblue':
$r = 0.529; $g = 0.808; $b = 0.980; break;
case 'lightslategray':
$r = 0.467; $g = 0.533; $b = 0.6; break;
case 'lightsteelblue':
$r = 0.690; $g = 0.769; $b = 0.871; break;
case 'lightyellow':
$r = 1.0; $g = 1.0; $b = 0.878; break;
case 'limegreen':
$r = 0.196; $g = 0.804; $b = 0.196; break;
case 'linen':
$r = 0.980; $g = 0.941; $b = 0.902; break;
case 'magenta':
$r = 1.0; $g = 0.0; $b = 1.0; break;
case 'mediumaquamarine':
$r = 0.4; $g = 0.804; $b = 0.667; break;
case 'mediumblue':
$r = 0.0; $g = 0.0; $b = 0.804; break;
case 'mediumorchid':
$r = 0.729; $g = 0.333; $b = 0.827; break;
case 'mediumpurple':
$r = 0.576; $g = 0.439; $b = 0.859; break;
case 'mediumseagreen':
$r = 0.235; $g = 0.702; $b = 0.443; break;
case 'mediumslateblue':
$r = 0.482; $g = 0.408; $b = 0.933; break;
case 'mediumspringgreen':
$r = 0.0; $g = 0.980; $b = 0.604; break;
case 'mediumturquoise':
$r = 0.282; $g = 0.820; $b = 0.8; break;
case 'mediumvioletred':
$r = 0.780; $g = 0.082; $b = 0.522; break;
case 'midnightblue':
$r = 0.098; $g = 0.098; $b = 0.439; break;
case 'mintcream':
$r = 0.961; $g = 1.0; $b = 0.980; break;
case 'mistyrose':
$r = 1.0; $g = 0.894; $b = 0.882; break;
case 'moccasin':
$r = 1.0; $g = 0.894; $b = 0.710; break;
case 'navajowhite':
$r = 1.0; $g = 0.871; $b = 0.678; break;
case 'oldlace':
$r = 0.992; $g = 0.961; $b = 0.902; break;
case 'olivedrab':
$r = 0.420; $g = 0.557; $b = 0.137; break;
case 'orange':
$r = 1.0; $g = 0.647; $b = 0.0; break;
case 'orangered':
$r = 1.0; $g = 0.271; $b = 0.0; break;
case 'orchid':
$r = 0.855; $g = 0.439; $b = 0.839; break;
case 'palegoldenrod':
$r = 0.933; $g = 0.910; $b = 0.667; break;
case 'palegreen':
$r = 0.596; $g = 0.984; $b = 0.596; break;
case 'paleturquoise':
$r = 0.686; $g = 0.933; $b = 0.933; break;
case 'palevioletred':
$r = 0.859; $g = 0.439; $b = 0.576; break;
case 'papayawhip':
$r = 1.0; $g = 0.937; $b = 0.835; break;
case 'peachpuff':
$r = 1.0; $g = 0.937; $b = 0.835; break;
case 'peru':
$r = 0.804; $g = 0.522; $b = 0.247; break;
case 'pink':
$r = 1.0; $g = 0.753; $b = 0.796; break;
case 'plum':
$r = 0.867; $g = 0.627; $b = 0.867; break;
case 'powderblue':
$r = 0.690; $g = 0.878; $b = 0.902; break;
case 'rosybrown':
$r = 0.737; $g = 0.561; $b = 0.561; break;
case 'royalblue':
$r = 0.255; $g = 0.412; $b = 0.882; break;
case 'saddlebrown':
$r = 0.545; $g = 0.271; $b = 0.075; break;
case 'salmon':
$r = 0.980; $g = 0.502; $b = 0.447; break;
case 'sandybrown':
$r = 0.957; $g = 0.643; $b = 0.376; break;
case 'seagreen':
$r = 0.180; $g = 0.545; $b = 0.341; break;
case 'seashell':
$r = 1.0; $g = 0.961; $b = 0.933; break;
case 'sienna':
$r = 0.627; $g = 0.322; $b = 0.176; break;
case 'skyblue':
$r = 0.529; $g = 0.808; $b = 0.922; break;
case 'slateblue':
$r = 0.416; $g = 0.353; $b = 0.804; break;
case 'slategray':
$r = 0.439; $g = 0.502; $b = 0.565; break;
case 'snow':
$r = 1.0; $g = 0.980; $b = 0.980; break;
case 'springgreen':
$r = 0.0; $g = 1.0; $b = 0.498; break;
case 'steelblue':
$r = 0.275; $g = 0.510; $b = 0.706; break;
case 'tan':
$r = 0.824; $g = 0.706; $b = 0.549; break;
case 'thistle':
$r = 0.847; $g = 0.749; $b = 0.847; break;
case 'tomato':
$r = 0.992; $g = 0.388; $b = 0.278; break;
case 'turquoise':
$r = 0.251; $g = 0.878; $b = 0.816; break;
case 'violet':
$r = 0.933; $g = 0.510; $b = 0.933; break;
case 'wheat':
$r = 0.961; $g = 0.871; $b = 0.702; break;
case 'whitesmoke':
$r = 0.961; $g = 0.961; $b = 0.961; break;
case 'yellowgreen':
$r = 0.604; $g = 0.804; $b = 0.196; break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown color name: ' . $color);
}
if (($r == $g) && ($g == $b)) {
// require_once 'Zend/Pdf/Color/GrayScale.php';
return new Zend_Pdf_Color_GrayScale($r);
} else {
// require_once 'Zend/Pdf/Color/Rgb.php';
return new Zend_Pdf_Color_Rgb($r, $g, $b);
}
}
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rgb.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Color */
// require_once 'Zend/Pdf/Color.php';
/**
* RGB color implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Color_Rgb extends Zend_Pdf_Color
{
/**
* Red level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_r;
/**
* Green level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_g;
/**
* Blue level.
* 0.0 (zero concentration) - 1.0 (maximum concentration)
*
* @var Zend_Pdf_Element_Numeric
*/
private $_b;
/**
* Object constructor
*
* @param float $r
* @param float $g
* @param float $b
*/
public function __construct($r, $g, $b)
{
/** Clamp values to legal limits. */
if ($r < 0) { $r = 0; }
if ($r > 1) { $r = 1; }
if ($g < 0) { $g = 0; }
if ($g > 1) { $g = 1; }
if ($b < 0) { $b = 0; }
if ($b > 1) { $b = 1; }
$this->_r = new Zend_Pdf_Element_Numeric($r);
$this->_g = new Zend_Pdf_Element_Numeric($g);
$this->_b = new Zend_Pdf_Element_Numeric($b);
}
/**
* Instructions, which can be directly inserted into content stream
* to switch color.
* Color set instructions differ for stroking and nonstroking operations.
*
* @param boolean $stroking
* @return string
*/
public function instructions($stroking)
{
return $this->_r->toString() . ' '
. $this->_g->toString() . ' '
. $this->_b->toString() . ($stroking? " RG\n" : " rg\n");
}
/**
* Get color components (color space dependent)
*
* @return array
*/
public function getComponents()
{
return array($this->_r->value, $this->_g->value, $this->_b->value);
}
}

View File

@ -0,0 +1,113 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Destination.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
/** Zend_Pdf_Target */
// require_once 'Zend/Pdf/Target.php';
/**
* Abstract PDF destination representation class
*
* @package Zend_Pdf
* @subpackage Destination
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Destination extends Zend_Pdf_Target
{
/**
* Load Destination object from a specified resource
*
* @internal
* @param Zend_Pdf_Element $resource
* @return Zend_Pdf_Destination
*/
public static function load(Zend_Pdf_Element $resource)
{
// require_once 'Zend/Pdf/Element.php';
if ($resource->getType() == Zend_Pdf_Element::TYPE_NAME || $resource->getType() == Zend_Pdf_Element::TYPE_STRING) {
// require_once 'Zend/Pdf/Destination/Named.php';
return new Zend_Pdf_Destination_Named($resource);
}
if ($resource->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('An explicit destination must be a direct or an indirect array object.');
}
if (count($resource->items) < 2) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('An explicit destination array must contain at least two elements.');
}
switch ($resource->items[1]->value) {
case 'XYZ':
// require_once 'Zend/Pdf/Destination/Zoom.php';
return new Zend_Pdf_Destination_Zoom($resource);
break;
case 'Fit':
// require_once 'Zend/Pdf/Destination/Fit.php';
return new Zend_Pdf_Destination_Fit($resource);
break;
case 'FitH':
// require_once 'Zend/Pdf/Destination/FitHorizontally.php';
return new Zend_Pdf_Destination_FitHorizontally($resource);
break;
case 'FitV':
// require_once 'Zend/Pdf/Destination/FitVertically.php';
return new Zend_Pdf_Destination_FitVertically($resource);
break;
case 'FitR':
// require_once 'Zend/Pdf/Destination/FitRectangle.php';
return new Zend_Pdf_Destination_FitRectangle($resource);
break;
case 'FitB':
// require_once 'Zend/Pdf/Destination/FitBoundingBox.php';
return new Zend_Pdf_Destination_FitBoundingBox($resource);
break;
case 'FitBH':
// require_once 'Zend/Pdf/Destination/FitBoundingBoxHorizontally.php';
return new Zend_Pdf_Destination_FitBoundingBoxHorizontally($resource);
break;
case 'FitBV':
// require_once 'Zend/Pdf/Destination/FitBoundingBoxVertically.php';
return new Zend_Pdf_Destination_FitBoundingBoxVertically($resource);
break;
default:
// require_once 'Zend/Pdf/Destination/Unknown.php';
return new Zend_Pdf_Destination_Unknown($resource);
break;
}
}
}

View File

@ -0,0 +1,122 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Explicit.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
/** Zend_Pdf_Destination */
// require_once 'Zend/Pdf/Destination.php';
/**
* Abstract PDF explicit destination representation class
*
* @package Zend_Pdf
* @subpackage Destination
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Destination_Explicit extends Zend_Pdf_Destination
{
/**
* Destination description array
*
* @var Zend_Pdf_Element_Array
*/
protected $_destinationArray;
/**
* True if it's a remote destination
*
* @var boolean
*/
protected $_isRemote;
/**
* Explicit 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('Explicit destination resource Array must be a direct or an indirect array object.');
}
$this->_destinationArray = $destinationArray;
switch (count($this->_destinationArray->items)) {
case 0:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Destination array must contain a page reference.');
break;
case 1:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Destination array must contain a destination type name.');
break;
default:
// Do nothing
break;
}
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;
}
}
/**
* Returns true if it's a remote destination
*
* @return boolean
*/
public function isRemote()
{
return $this->_isRemote;
}
/**
* Get resource
*
* @internal
* @return Zend_Pdf_Element
*/
public function getResource()
{
return $this->_destinationArray;
}
}

View File

@ -0,0 +1,75 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Fit.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_Fit explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$destinationArray->items[] = new Zend_Pdf_Element_Name('Fit');
return new Zend_Pdf_Destination_Fit($destinationArray);
}
}

View File

@ -0,0 +1,75 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitBoundingBox.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitBoundingBox explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$destinationArray->items[] = new Zend_Pdf_Element_Name('FitB');
return new Zend_Pdf_Destination_FitBoundingBox($destinationArray);
}
}

View File

@ -0,0 +1,98 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitBoundingBoxHorizontally.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitBoundingBoxHorizontally explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$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;
}
}

View File

@ -0,0 +1,98 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitBoundingBoxVertically.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitBoundingBoxVertically explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$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;
}
}

View File

@ -0,0 +1,98 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitHorizontally.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitHorizontally explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$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;
}
}

View File

@ -0,0 +1,171 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitRectangle.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitRectangle explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$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;
}
}

View File

@ -0,0 +1,98 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FitVertically.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_FitVertically explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or page number.');
}
$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;
}
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Named.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/String.php';
/** 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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Destination_Named extends Zend_Pdf_Destination
{
/**
* Destination name
*
* @var Zend_Pdf_Element_Name|Zend_Pdf_Element_String
*/
protected $_nameElement;
/**
* Named destination object constructor
*
* @param Zend_Pdf_Element $resource
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $resource)
{
if ($resource->getType() != Zend_Pdf_Element::TYPE_NAME && $resource->getType() != Zend_Pdf_Element::TYPE_STRING) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Named destination resource must be a PDF name or a PDF string.');
}
$this->_nameElement = $resource;
}
/**
* Create named destination object
*
* @param string $name
* @return Zend_Pdf_Destination_Named
*/
public static function create($name)
{
return new Zend_Pdf_Destination_Named(new Zend_Pdf_Element_String($name));
}
/**
* Get name
*
* @return Zend_Pdf_Element
*/
public function getName()
{
return $this->_nameElement->value;
}
/**
* Get resource
*
* @internal
* @return Zend_Pdf_Element
*/
public function getResource()
{
return $this->_nameElement;
}
}

View File

@ -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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Unknown.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Unrecognized explicit destination representation class
*
* @package Zend_Pdf
* @subpackage Destination
* @copyright Copyright (c) 2005-2012 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_Explicit
{
}

View File

@ -0,0 +1,177 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Zoom.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Name.php';
// require_once 'Zend/Pdf/Element/Null.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Destination_Explicit */
// require_once 'Zend/Pdf/Destination/Explicit.php';
/**
* Zend_Pdf_Destination_Zoom explicit detination
*
* 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-2012 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_Explicit
{
/**
* Create destination object
*
* @param Zend_Pdf_Page|integer $page Page object or page number
* @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_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 or a page number.');
}
$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;
}
}

View File

@ -0,0 +1,176 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Element.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF file element implementation
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Element
{
const TYPE_BOOL = 1;
const TYPE_NUMERIC = 2;
const TYPE_STRING = 3;
const TYPE_NAME = 4;
const TYPE_ARRAY = 5;
const TYPE_DICTIONARY = 6;
const TYPE_STREAM = 7;
const TYPE_NULL = 11;
/**
* Reference to the top level indirect object, which contains this element.
*
* @var Zend_Pdf_Element_Object
*/
private $_parentObject = null;
/**
* Return type of the element.
* See ZPdfPDFConst for possible values
*
* @return integer
*/
abstract public function getType();
/**
* Convert element to a string, which can be directly
* written to a PDF file.
*
* $factory parameter defines operation context.
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
abstract public function toString($factory = null);
const CLONE_MODE_SKIP_PAGES = 1; // Do not follow pages during deep copy process
const CLONE_MODE_FORCE_CLONING = 2; // Force top level object cloning even it's already processed
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @todo It's nevessry to check if SplObjectStorage class works faster
* (Needs PHP 5.3.x to attach object _with_ additional data to storage)
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
return clone $this;
}
/**
* Set top level parent indirect object.
*
* @param Zend_Pdf_Element_Object $parent
*/
public function setParentObject(Zend_Pdf_Element_Object $parent)
{
$this->_parentObject = $parent;
}
/**
* Get top level parent indirect object.
*
* @return Zend_Pdf_Element_Object
*/
public function getParentObject()
{
return $this->_parentObject;
}
/**
* Mark object as modified, to include it into new PDF file segment.
*
* We don't automate this action to keep control on PDF update process.
* All new objects are treated as "modified" automatically.
*/
public function touch()
{
if ($this->_parentObject !== null) {
$this->_parentObject->touch();
}
}
/**
* Clean up resources, used by object
*/
public function cleanUp()
{
// Do nothing
}
/**
* Convert PDF element to PHP type.
*
* @return mixed
*/
public function toPhp()
{
return $this->value;
}
/**
* Convert PHP value into PDF element.
*
* @param mixed $input
* @return Zend_Pdf_Element
*/
public static function phpToPdf($input)
{
if (is_numeric($input)) {
// require_once 'Zend/Pdf/Element/Numeric.php';
return new Zend_Pdf_Element_Numeric($input);
} else if (is_bool($input)) {
// require_once 'Zend/Pdf/Element/Boolean.php';
return new Zend_Pdf_Element_Boolean($input);
} else if (is_array($input)) {
$pdfElementsArray = array();
$isDictionary = false;
foreach ($input as $key => $value) {
if (is_string($key)) {
$isDictionary = true;
}
$pdfElementsArray[$key] = Zend_Pdf_Element::phpToPdf($value);
}
if ($isDictionary) {
// require_once 'Zend/Pdf/Element/Dictionary.php';
return new Zend_Pdf_Element_Dictionary($pdfElementsArray);
} else {
// require_once 'Zend/Pdf/Element/Array.php';
return new Zend_Pdf_Element_Array($pdfElementsArray);
}
} else {
// require_once 'Zend/Pdf/Element/String.php';
return new Zend_Pdf_Element_String((string)$input);
}
}
}

View File

@ -0,0 +1,181 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Array.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'array' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Array extends Zend_Pdf_Element
{
/**
* Array element items
*
* Array of Zend_Pdf_Element objects
*
* @var array
*/
public $items;
/**
* Object constructor
*
* @param array $val - array of Zend_Pdf_Element objects
* @throws Zend_Pdf_Exception
*/
public function __construct($val = null)
{
$this->items = new ArrayObject();
if ($val !== null && is_array($val)) {
foreach ($val as $element) {
if (!$element instanceof Zend_Pdf_Element) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Array elements must be Zend_Pdf_Element objects');
}
$this->items[] = $element;
}
} else if ($val !== null){
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Argument must be an array');
}
}
/**
* Getter
*
* @param string $property
* @throws Zend_Pdf_Exception
*/
public function __get($property) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Undefined property: Zend_Pdf_Element_Array::$' . $property);
}
/**
* Setter
*
* @param mixed $offset
* @param mixed $value
* @throws Zend_Pdf_Exception
*/
public function __set($property, $value) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Undefined property: Zend_Pdf_Element_Array::$' . $property);
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_ARRAY;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
$outStr = '[';
$lastNL = 0;
foreach ($this->items as $element) {
if (strlen($outStr) - $lastNL > 128) {
$outStr .= "\n";
$lastNL = strlen($outStr);
}
$outStr .= $element->toString($factory) . ' ';
}
$outStr .= ']';
return $outStr;
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
$newArray = new self();
foreach ($this->items as $key => $value) {
$newArray->items[$key] = $value->makeClone($factory, $processed, $mode);
}
return $newArray;
}
/**
* Set top level parent indirect object.
*
* @param Zend_Pdf_Element_Object $parent
*/
public function setParentObject(Zend_Pdf_Element_Object $parent)
{
parent::setParentObject($parent);
foreach ($this->items as $item) {
$item->setParentObject($parent);
}
}
/**
* Convert PDF element to PHP type.
*
* Dictionary is returned as an associative array
*
* @return mixed
*/
public function toPhp()
{
$phpArray = array();
foreach ($this->items as $item) {
$phpArray[] = $item->toPhp();
}
return $phpArray;
}
}

View File

@ -0,0 +1,83 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Boolean.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'boolean' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Boolean extends Zend_Pdf_Element
{
/**
* Object value
*
* @var boolean
*/
public $value;
/**
* Object constructor
*
* @param boolean $val
* @throws Zend_Pdf_Exception
*/
public function __construct($val)
{
if (! is_bool($val)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Argument must be boolean.');
}
$this->value = $val;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_BOOL;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return $this->value ? 'true' : 'false';
}
}

View File

@ -0,0 +1,236 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Dictionary.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Name.php';
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'dictionary' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Dictionary extends Zend_Pdf_Element
{
/**
* Dictionary elements
* Array of Zend_Pdf_Element objects ('name' => Zend_Pdf_Element)
*
* @var array
*/
private $_items = array();
/**
* Object constructor
*
* @param array $val - array of Zend_Pdf_Element objects
* @throws Zend_Pdf_Exception
*/
public function __construct($val = null)
{
if ($val === null) {
return;
} else if (!is_array($val)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Argument must be an array');
}
foreach ($val as $name => $element) {
if (!$element instanceof Zend_Pdf_Element) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Array elements must be Zend_Pdf_Element objects');
}
if (!is_string($name)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Array keys must be strings');
}
$this->_items[$name] = $element;
}
}
/**
* Add element to an array
*
* @name Zend_Pdf_Element_Name $name
* @param Zend_Pdf_Element $val - Zend_Pdf_Element object
* @throws Zend_Pdf_Exception
*/
public function add(Zend_Pdf_Element_Name $name, Zend_Pdf_Element $val)
{
$this->_items[$name->value] = $val;
}
/**
* Return dictionary keys
*
* @return array
*/
public function getKeys()
{
return array_keys($this->_items);
}
/**
* Get handler
*
* @param string $property
* @return Zend_Pdf_Element | null
*/
public function __get($item)
{
$element = isset($this->_items[$item]) ? $this->_items[$item]
: null;
return $element;
}
/**
* Set handler
*
* @param string $property
* @param mixed $value
*/
public function __set($item, $value)
{
if ($value === null) {
unset($this->_items[$item]);
} else {
$this->_items[$item] = $value;
}
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_DICTIONARY;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
$outStr = '<<';
$lastNL = 0;
foreach ($this->_items as $name => $element) {
if (!is_object($element)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong data');
}
if (strlen($outStr) - $lastNL > 128) {
$outStr .= "\n";
$lastNL = strlen($outStr);
}
$nameObj = new Zend_Pdf_Element_Name($name);
$outStr .= $nameObj->toString($factory) . ' ' . $element->toString($factory) . ' ';
}
$outStr .= '>>';
return $outStr;
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
* @throws Zend_Pdf_Exception
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
if (isset($this->_items['Type'])) {
if ($this->_items['Type']->value == 'Pages') {
// It's a page tree node
// skip it and its children
return new Zend_Pdf_Element_Null();
}
if ($this->_items['Type']->value == 'Page' &&
$mode == Zend_Pdf_Element::CLONE_MODE_SKIP_PAGES
) {
// It's a page node, skip it
return new Zend_Pdf_Element_Null();
}
}
$newDictionary = new self();
foreach ($this->_items as $key => $value) {
$newDictionary->_items[$key] = $value->makeClone($factory, $processed, $mode);
}
return $newDictionary;
}
/**
* Set top level parent indirect object.
*
* @param Zend_Pdf_Element_Object $parent
*/
public function setParentObject(Zend_Pdf_Element_Object $parent)
{
parent::setParentObject($parent);
foreach ($this->_items as $item) {
$item->setParentObject($parent);
}
}
/**
* Convert PDF element to PHP type.
*
* Dictionary is returned as an associative array
*
* @return mixed
*/
public function toPhp()
{
$phpArray = array();
foreach ($this->_items as $itemName => $item) {
$phpArray[$itemName] = $item->toPhp();
}
return $phpArray;
}
}

View File

@ -0,0 +1,161 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Name.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'name' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Name extends Zend_Pdf_Element
{
/**
* Object value
*
* @var string
*/
public $value;
/**
* Object constructor
*
* @param string $val
* @throws Zend_Pdf_Exception
*/
public function __construct($val)
{
settype($val, 'string');
if (strpos($val,"\x00") !== false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Null character is not allowed in PDF Names');
}
$this->value = (string)$val;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_NAME;
}
/**
* Escape string according to the PDF rules
*
* @param string $inStr
* @return string
*/
public static function escape($inStr)
{
$outStr = '';
for ($count = 0; $count < strlen($inStr); $count++) {
$nextCode = ord($inStr[$count]);
switch ($inStr[$count]) {
case '(':
// fall through to next case
case ')':
// fall through to next case
case '<':
// fall through to next case
case '>':
// fall through to next case
case '[':
// fall through to next case
case ']':
// fall through to next case
case '{':
// fall through to next case
case '}':
// fall through to next case
case '/':
// fall through to next case
case '%':
// fall through to next case
case '\\':
// fall through to next case
case '#':
$outStr .= sprintf('#%02X', $nextCode);
break;
default:
if ($nextCode >= 33 && $nextCode <= 126 ) {
// Visible ASCII symbol
$outStr .= $inStr[$count];
} else {
$outStr .= sprintf('#%02X', $nextCode);
}
}
}
return $outStr;
}
/**
* Unescape string according to the PDF rules
*
* @param string $inStr
* @return string
*/
public static function unescape($inStr)
{
$outStr = '';
for ($count = 0; $count < strlen($inStr); $count++) {
if ($inStr[$count] != '#' ) {
$outStr .= $inStr[$count];
} else {
// Escape sequence
$outStr .= chr(base_convert(substr($inStr, $count+1, 2), 16, 10 ));
$count +=2;
}
}
return $outStr;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return '/' . self::escape((string)$this->value);
}
}

View File

@ -0,0 +1,75 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Null.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'null' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Null extends Zend_Pdf_Element
{
/**
* Object value. Always null.
*
* @var mixed
*/
public $value;
/**
* Object constructor
*/
public function __construct()
{
$this->value = null;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_NULL;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return 'null';
}
}

View File

@ -0,0 +1,95 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Numeric.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'numeric' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Numeric extends Zend_Pdf_Element
{
/**
* Object value
*
* @var numeric
*/
public $value;
/**
* Object constructor
*
* @param numeric $val
* @throws Zend_Pdf_Exception
*/
public function __construct($val)
{
if ( !is_numeric($val) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Argument must be numeric');
}
$this->value = $val;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_NUMERIC;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
if (is_integer($this->value)) {
return (string)$this->value;
}
/**
* PDF doesn't support exponental format.
* Fixed point format must be used instead
*/
$prec = 0; $v = $this->value;
while (abs( floor($v) - $v ) > 1e-10) {
$prec++; $v *= 10;
}
return sprintf("%.{$prec}F", $this->value);
}
}

View File

@ -0,0 +1,284 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Object.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'indirect object' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Object extends Zend_Pdf_Element
{
/**
* Object value
*
* @var Zend_Pdf_Element
*/
protected $_value;
/**
* Object number within PDF file
*
* @var integer
*/
protected $_objNum;
/**
* Generation number
*
* @var integer
*/
protected $_genNum;
/**
* Reference to the factory.
*
* @var Zend_Pdf_ElementFactory
*/
protected $_factory;
/**
* Object constructor
*
* @param Zend_Pdf_Element $val
* @param integer $objNum
* @param integer $genNum
* @param Zend_Pdf_ElementFactory $factory
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_Element $val, $objNum, $genNum, Zend_Pdf_ElementFactory $factory)
{
if ($val instanceof self) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object number must not be an instance of Zend_Pdf_Element_Object.');
}
if ( !(is_integer($objNum) && $objNum > 0) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object number must be positive integer.');
}
if ( !(is_integer($genNum) && $genNum >= 0) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Generation number must be non-negative integer.');
}
$this->_value = $val;
$this->_objNum = $objNum;
$this->_genNum = $genNum;
$this->_factory = $factory;
$this->setParentObject($this);
$factory->registerObject($this, $objNum . ' ' . $genNum);
}
/**
* Check, that object is generated by specified factory
*
* @return Zend_Pdf_ElementFactory
*/
public function getFactory()
{
return $this->_factory;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return $this->_value->getType();
}
/**
* Get object number
*
* @return integer
*/
public function getObjNum()
{
return $this->_objNum;
}
/**
* Get generation number
*
* @return integer
*/
public function getGenNum()
{
return $this->_genNum;
}
/**
* Return reference to the object
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
if ($factory === null) {
$shift = 0;
} else {
$shift = $factory->getEnumerationShift($this->_factory);
}
return $this->_objNum + $shift . ' ' . $this->_genNum . ' R';
}
/**
* Dump object to a string to save within PDF file.
*
* $factory parameter defines operation context.
*
* @param Zend_Pdf_ElementFactory $factory
* @return string
*/
public function dump(Zend_Pdf_ElementFactory $factory)
{
$shift = $factory->getEnumerationShift($this->_factory);
return $this->_objNum + $shift . " " . $this->_genNum . " obj \n"
. $this->_value->toString($factory) . "\n"
. "endobj\n";
}
/**
* Get handler
*
* @param string $property
* @return mixed
*/
public function __get($property)
{
return $this->_value->$property;
}
/**
* Set handler
*
* @param string $property
* @param mixed $value
*/
public function __set($property, $value)
{
$this->_value->$property = $value;
}
/**
* Call handler
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
return call_user_func_array(array($this->_value, $method), $args);
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
$id = spl_object_hash($this);
if (isset($processed[$id])) {
// Do nothing if object is already processed
// return it
return $processed[$id];
}
// Create obect with null value and register it in $processed container
$processed[$id] = $clonedObject = $factory->newObject(new Zend_Pdf_Element_Null());
// Pecursively process actual data
$clonedObject->_value = $this->_value->makeClone($factory, $processed, $mode);
if ($clonedObject->_value instanceof Zend_Pdf_Element_Null) {
// Do not store null objects within $processed container since it may be filtered
// by $mode parameter but used in some future pass
unset($processed[$id]);
// Return direct null object
return $clonedObject->_value;
}
return $clonedObject;
}
/**
* Mark object as modified, to include it into new PDF file segment
*/
public function touch()
{
$this->_factory->markAsModified($this);
}
/**
* Return object, which can be used to identify object and its references identity
*
* @return Zend_Pdf_Element_Object
*/
public function getObject()
{
return $this;
}
/**
* Clean up resources, used by object
*/
public function cleanUp()
{
$this->_value = null;
}
/**
* Convert PDF element to PHP type.
*
* @return mixed
*/
public function toPhp()
{
return $this->_value->toPhp();
}
}

View File

@ -0,0 +1,453 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Stream.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Stream.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_Element_Object */
// require_once 'Zend/Pdf/Element/Object.php';
/**
* PDF file 'stream object' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Object_Stream extends Zend_Pdf_Element_Object
{
/**
* StreamObject dictionary
* Required enries:
* Length
*
* @var Zend_Pdf_Element_Dictionary
*/
private $_dictionary;
/**
* Flag which signals, that stream is decoded
*
* @var boolean
*/
private $_streamDecoded;
/**
* Stored original stream object dictionary.
* Used to decode stream at access time.
*
* The only properties affecting decoding are sored here.
*
* @var array|null
*/
private $_initialDictionaryData = null;
/**
* Object constructor
*
* @param mixed $val
* @param integer $objNum
* @param integer $genNum
* @param Zend_Pdf_ElementFactory $factory
* @param Zend_Pdf_Element_Dictionary|null $dictionary
* @throws Zend_Pdf_Exception
*/
public function __construct($val, $objNum, $genNum, Zend_Pdf_ElementFactory $factory, $dictionary = null)
{
parent::__construct(new Zend_Pdf_Element_Stream($val), $objNum, $genNum, $factory);
if ($dictionary === null) {
$this->_dictionary = new Zend_Pdf_Element_Dictionary();
$this->_dictionary->Length = new Zend_Pdf_Element_Numeric(strlen( $val ));
$this->_streamDecoded = true;
} else {
$this->_dictionary = $dictionary;
$this->_streamDecoded = false;
}
}
/**
* Extract dictionary data which are used to store information and to normalize filters
* information before defiltering.
*
* @return array
*/
private function _extractDictionaryData()
{
$dictionaryArray = array();
$dictionaryArray['Filter'] = array();
$dictionaryArray['DecodeParms'] = array();
if ($this->_dictionary->Filter === null) {
// Do nothing.
} else if ($this->_dictionary->Filter->getType() == Zend_Pdf_Element::TYPE_ARRAY) {
foreach ($this->_dictionary->Filter->items as $id => $filter) {
$dictionaryArray['Filter'][$id] = $filter->value;
$dictionaryArray['DecodeParms'][$id] = array();
if ($this->_dictionary->DecodeParms !== null ) {
if ($this->_dictionary->DecodeParms->items[$id] !== null &&
$this->_dictionary->DecodeParms->items[$id]->value !== null ) {
foreach ($this->_dictionary->DecodeParms->items[$id]->getKeys() as $paramKey) {
$dictionaryArray['DecodeParms'][$id][$paramKey] =
$this->_dictionary->DecodeParms->items[$id]->$paramKey->value;
}
}
}
}
} else if ($this->_dictionary->Filter->getType() != Zend_Pdf_Element::TYPE_NULL) {
$dictionaryArray['Filter'][0] = $this->_dictionary->Filter->value;
$dictionaryArray['DecodeParms'][0] = array();
if ($this->_dictionary->DecodeParms !== null ) {
foreach ($this->_dictionary->DecodeParms->getKeys() as $paramKey) {
$dictionaryArray['DecodeParms'][0][$paramKey] =
$this->_dictionary->DecodeParms->$paramKey->value;
}
}
}
if ($this->_dictionary->F !== null) {
$dictionaryArray['F'] = $this->_dictionary->F->value;
}
$dictionaryArray['FFilter'] = array();
$dictionaryArray['FDecodeParms'] = array();
if ($this->_dictionary->FFilter === null) {
// Do nothing.
} else if ($this->_dictionary->FFilter->getType() == Zend_Pdf_Element::TYPE_ARRAY) {
foreach ($this->_dictionary->FFilter->items as $id => $filter) {
$dictionaryArray['FFilter'][$id] = $filter->value;
$dictionaryArray['FDecodeParms'][$id] = array();
if ($this->_dictionary->FDecodeParms !== null ) {
if ($this->_dictionary->FDecodeParms->items[$id] !== null &&
$this->_dictionary->FDecodeParms->items[$id]->value !== null) {
foreach ($this->_dictionary->FDecodeParms->items[$id]->getKeys() as $paramKey) {
$dictionaryArray['FDecodeParms'][$id][$paramKey] =
$this->_dictionary->FDecodeParms->items[$id]->items[$paramKey]->value;
}
}
}
}
} else {
$dictionaryArray['FFilter'][0] = $this->_dictionary->FFilter->value;
$dictionaryArray['FDecodeParms'][0] = array();
if ($this->_dictionary->FDecodeParms !== null ) {
foreach ($this->_dictionary->FDecodeParms->getKeys() as $paramKey) {
$dictionaryArray['FDecodeParms'][0][$paramKey] =
$this->_dictionary->FDecodeParms->items[$paramKey]->value;
}
}
}
return $dictionaryArray;
}
/**
* Decode stream
*
* @throws Zend_Pdf_Exception
*/
private function _decodeStream()
{
if ($this->_initialDictionaryData === null) {
$this->_initialDictionaryData = $this->_extractDictionaryData();
}
/**
* All applied stream filters must be processed to decode stream.
* If we don't recognize any of applied filetrs an exception should be thrown here
*/
if (isset($this->_initialDictionaryData['F'])) {
/** @todo Check, how external files can be processed. */
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('External filters are not supported now.');
}
foreach ($this->_initialDictionaryData['Filter'] as $id => $filterName ) {
$valueRef = &$this->_value->value->getRef();
$this->_value->value->touch();
switch ($filterName) {
case 'ASCIIHexDecode':
// require_once 'Zend/Pdf/Filter/AsciiHex.php';
$valueRef = Zend_Pdf_Filter_AsciiHex::decode($valueRef);
break;
case 'ASCII85Decode':
// require_once 'Zend/Pdf/Filter/Ascii85.php';
$valueRef = Zend_Pdf_Filter_Ascii85::decode($valueRef);
break;
case 'FlateDecode':
// require_once 'Zend/Pdf/Filter/Compression/Flate.php';
$valueRef = Zend_Pdf_Filter_Compression_Flate::decode($valueRef,
$this->_initialDictionaryData['DecodeParms'][$id]);
break;
case 'LZWDecode':
// require_once 'Zend/Pdf/Filter/Compression/Lzw.php';
$valueRef = Zend_Pdf_Filter_Compression_Lzw::decode($valueRef,
$this->_initialDictionaryData['DecodeParms'][$id]);
break;
case 'RunLengthDecode':
// require_once 'Zend/Pdf/Filter/RunLength.php';
$valueRef = Zend_Pdf_Filter_RunLength::decode($valueRef);
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.');
}
}
$this->_streamDecoded = true;
}
/**
* Encode stream
*
* @throws Zend_Pdf_Exception
*/
private function _encodeStream()
{
/**
* All applied stream filters must be processed to encode stream.
* If we don't recognize any of applied filetrs an exception should be thrown here
*/
if (isset($this->_initialDictionaryData['F'])) {
/** @todo Check, how external files can be processed. */
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('External filters are not supported now.');
}
$filters = array_reverse($this->_initialDictionaryData['Filter'], true);
foreach ($filters as $id => $filterName ) {
$valueRef = &$this->_value->value->getRef();
$this->_value->value->touch();
switch ($filterName) {
case 'ASCIIHexDecode':
// require_once 'Zend/Pdf/Filter/AsciiHex.php';
$valueRef = Zend_Pdf_Filter_AsciiHex::encode($valueRef);
break;
case 'ASCII85Decode':
// require_once 'Zend/Pdf/Filter/Ascii85.php';
$valueRef = Zend_Pdf_Filter_Ascii85::encode($valueRef);
break;
case 'FlateDecode':
// require_once 'Zend/Pdf/Filter/Compression/Flate.php';
$valueRef = Zend_Pdf_Filter_Compression_Flate::encode($valueRef,
$this->_initialDictionaryData['DecodeParms'][$id]);
break;
case 'LZWDecode':
// require_once 'Zend/Pdf/Filter/Compression/Lzw.php';
$valueRef = Zend_Pdf_Filter_Compression_Lzw::encode($valueRef,
$this->_initialDictionaryData['DecodeParms'][$id]);
break;
case 'RunLengthDecode':
// require_once 'Zend/Pdf/Filter/RunLength.php';
$valueRef = Zend_Pdf_Filter_RunLength::encode($valueRef);
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown stream filter: \'' . $filterName . '\'.');
}
}
$this->_streamDecoded = false;
}
/**
* Get handler
*
* @param string $property
* @return mixed
* @throws Zend_Pdf_Exception
*/
public function __get($property)
{
if ($property == 'dictionary') {
/**
* 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();
}
return $this->_dictionary;
}
if ($property == 'value') {
if (!$this->_streamDecoded) {
$this->_decodeStream();
}
return $this->_value->value->getRef();
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown stream object property requested.');
}
/**
* Set handler
*
* @param string $property
* @param mixed $value
*/
public function __set($property, $value)
{
if ($property == 'value') {
$valueRef = &$this->_value->value->getRef();
$valueRef = $value;
$this->_value->value->touch();
$this->_streamDecoded = true;
return;
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown stream object property: \'' . $property . '\'.');
}
/**
* Treat stream data as already encoded
*/
public function skipFilters()
{
$this->_streamDecoded = false;
}
/**
* Call handler
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
if (!$this->_streamDecoded) {
$this->_decodeStream();
}
switch (count($args)) {
case 0:
return $this->_value->$method();
case 1:
return $this->_value->$method($args[0]);
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unsupported number of arguments');
}
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
$id = spl_object_hash($this);
if (isset($processed[$id])) {
// Do nothing if object is already processed
// return it
return $processed[$id];
}
$streamValue = $this->_value;
$streamDictionary = $this->_dictionary->makeClone($factory, $processed, $mode);
// Make new empty instance of stream object and register it in $processed container
$processed[$id] = $clonedObject = $factory->newStreamObject('');
// Copy current object data and state
$clonedObject->_dictionary = $this->_dictionary->makeClone($factory, $processed, $mode);
$clonedObject->_value = $this->_value->makeClone($factory, $processed, $mode);
$clonedObject->_initialDictionaryData = $this->_initialDictionaryData;
$clonedObject->_streamDecoded = $this->_streamDecoded;
return $clonedObject;
}
/**
* Dump object to a string to save within PDF file
*
* $factory parameter defines operation context.
*
* @param Zend_Pdf_ElementFactory $factory
* @return string
*/
public function dump(Zend_Pdf_ElementFactory $factory)
{
$shift = $factory->getEnumerationShift($this->_factory);
if ($this->_streamDecoded) {
$this->_initialDictionaryData = $this->_extractDictionaryData();
$this->_encodeStream();
} else if ($this->_initialDictionaryData != null) {
$newDictionary = $this->_extractDictionaryData();
if ($this->_initialDictionaryData !== $newDictionary) {
$this->_decodeStream();
$this->_initialDictionaryData = $newDictionary;
$this->_encodeStream();
}
}
// Update stream length
$this->dictionary->Length->value = $this->_value->length();
return $this->_objNum + $shift . " " . $this->_genNum . " obj \n"
. $this->dictionary->toString($factory) . "\n"
. $this->_value->toString($factory) . "\n"
. "endobj\n";
}
/**
* Clean up resources, used by object
*/
public function cleanUp()
{
$this->_dictionary = null;
$this->_value = null;
}
}

View File

@ -0,0 +1,303 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Reference.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Null.php';
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'reference' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Reference extends Zend_Pdf_Element
{
/**
* Object value
* The reference to the object
*
* @var mixed
*/
private $_ref;
/**
* Object number within PDF file
*
* @var integer
*/
private $_objNum;
/**
* Generation number
*
* @var integer
*/
private $_genNum;
/**
* Reference context
*
* @var Zend_Pdf_Element_Reference_Context
*/
private $_context;
/**
* Reference to the factory.
*
* It's the same as referenced object factory, but we save it here to avoid
* unnecessary dereferencing, whech can produce cascade dereferencing and parsing.
* The same for duplication of getFactory() function. It can be processed by __call()
* method, but we catch it here.
*
* @var Zend_Pdf_ElementFactory
*/
private $_factory;
/**
* Object constructor:
*
* @param integer $objNum
* @param integer $genNum
* @param Zend_Pdf_Element_Reference_Context $context
* @param Zend_Pdf_ElementFactory $factory
* @throws Zend_Pdf_Exception
*/
public function __construct($objNum, $genNum = 0, Zend_Pdf_Element_Reference_Context $context, Zend_Pdf_ElementFactory $factory)
{
if ( !(is_integer($objNum) && $objNum > 0) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object number must be positive integer');
}
if ( !(is_integer($genNum) && $genNum >= 0) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Generation number must be non-negative integer');
}
$this->_objNum = $objNum;
$this->_genNum = $genNum;
$this->_ref = null;
$this->_context = $context;
$this->_factory = $factory;
}
/**
* Check, that object is generated by specified factory
*
* @return Zend_Pdf_ElementFactory
*/
public function getFactory()
{
return $this->_factory;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
if ($this->_ref === null) {
$this->_dereference();
}
return $this->_ref->getType();
}
/**
* Return reference to the object
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
if ($factory === null) {
$shift = 0;
} else {
$shift = $factory->getEnumerationShift($this->_factory);
}
return $this->_objNum + $shift . ' ' . $this->_genNum . ' R';
}
/**
* Dereference.
* Take inderect object, take $value member of this object (must be Zend_Pdf_Element),
* take reference to the $value member of this object and assign it to
* $value member of current PDF Reference object
* $obj can be null
*
* @throws Zend_Pdf_Exception
*/
private function _dereference()
{
if (($obj = $this->_factory->fetchObject($this->_objNum . ' ' . $this->_genNum)) === null) {
$obj = $this->_context->getParser()->getObject(
$this->_context->getRefTable()->getOffset($this->_objNum . ' ' . $this->_genNum . ' R'),
$this->_context
);
}
if ($obj === null ) {
$this->_ref = new Zend_Pdf_Element_Null();
return;
}
if ($obj->toString() != $this->_objNum . ' ' . $this->_genNum . ' R') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Incorrect reference to the object');
}
$this->_ref = $obj;
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
if ($this->_ref === null) {
$this->_dereference();
}
// This code duplicates code in Zend_Pdf_Element_Object class,
// but allows to avoid unnecessary method call in most cases
$id = spl_object_hash($this->_ref);
if (isset($processed[$id])) {
// Do nothing if object is already processed
// return it
return $processed[$id];
}
return $this->_ref->makeClone($factory, $processed, $mode);
}
/**
* Mark object as modified, to include it into new PDF file segment.
*/
public function touch()
{
if ($this->_ref === null) {
$this->_dereference();
}
$this->_ref->touch();
}
/**
* Return object, which can be used to identify object and its references identity
*
* @return Zend_Pdf_Element_Object
*/
public function getObject()
{
if ($this->_ref === null) {
$this->_dereference();
}
return $this->_ref;
}
/**
* Get handler
*
* @param string $property
* @return mixed
*/
public function __get($property)
{
if ($this->_ref === null) {
$this->_dereference();
}
return $this->_ref->$property;
}
/**
* Set handler
*
* @param string $property
* @param mixed $value
*/
public function __set($property, $value)
{
if ($this->_ref === null) {
$this->_dereference();
}
$this->_ref->$property = $value;
}
/**
* Call handler
*
* @param string $method
* @param array $args
* @return mixed
*/
public function __call($method, $args)
{
if ($this->_ref === null) {
$this->_dereference();
}
return call_user_func_array(array($this->_ref, $method), $args);
}
/**
* Clean up resources
*/
public function cleanUp()
{
$this->_ref = null;
}
/**
* Convert PDF element to PHP type.
*
* @return mixed
*/
public function toPhp()
{
if ($this->_ref === null) {
$this->_dereference();
}
return $this->_ref->toPhp();
}
}

View File

@ -0,0 +1,83 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Context.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF reference object context
* Reference context is defined by PDF parser and PDF Refernce table
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Reference_Context
{
/**
* PDF parser object.
*
* @var Zend_Pdf_StringParser
*/
private $_stringParser;
/**
* Reference table
*
* @var Zend_Pdf_Element_Reference_Table
*/
private $_refTable;
/**
* Object constructor
*
* @param Zend_Pdf_StringParser $parser
* @param Zend_Pdf_Element_Reference_Table $refTable
*/
public function __construct(Zend_Pdf_StringParser $parser,
Zend_Pdf_Element_Reference_Table $refTable)
{
$this->_stringParser = $parser;
$this->_refTable = $refTable;
}
/**
* Context parser
*
* @return Zend_Pdf_StringParser
*/
public function getParser()
{
return $this->_stringParser;
}
/**
* Context reference table
*
* @return Zend_Pdf_Element_Reference_Table
*/
public function getRefTable()
{
return $this->_refTable;
}
}

View File

@ -0,0 +1,198 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Table.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF file reference table
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Reference_Table
{
/**
* Parent reference table
*
* @var Zend_Pdf_Element_Reference_Table
*/
private $_parent;
/**
* Free entries
* 'reference' => next free object number
*
* @var array
*/
private $_free;
/**
* Generation numbers for free objects.
* Array: objNum => nextGeneration
*
* @var array
*/
private $_generations;
/**
* In use entries
* 'reference' => offset
*
* @var array
*/
private $_inuse;
/**
* Generation numbers for free objects.
* Array: objNum => objGeneration
*
* @var array
*/
private $_usedObjects;
/**
* Object constructor
*/
public function __construct()
{
$this->_parent = null;
$this->_free = array(); $this->_generations = array();
$this->_inuse = array(); $this->_usedObjects = array();
}
/**
* Add reference to the reference table
*
* @param string $ref
* @param integer $offset
* @param boolean $inuse
*/
public function addReference($ref, $offset, $inuse = true)
{
$refElements = explode(' ', $ref);
if (!is_numeric($refElements[0]) || !is_numeric($refElements[1]) || $refElements[2] != 'R') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Incorrect reference: '$ref'");
}
$objNum = (int)$refElements[0];
$genNum = (int)$refElements[1];
if ($inuse) {
$this->_inuse[$ref] = $offset;
$this->_usedObjects[$objNum] = $objNum;
} else {
$this->_free[$ref] = $offset;
$this->_generations[$objNum] = $genNum;
}
}
/**
* Set parent reference table
*
* @param Zend_Pdf_Element_Reference_Table $parent
*/
public function setParent(self $parent)
{
$this->_parent = $parent;
}
/**
* Get object offset
*
* @param string $ref
* @return integer
*/
public function getOffset($ref)
{
if (isset($this->_inuse[$ref])) {
return $this->_inuse[$ref];
}
if (isset($this->_free[$ref])) {
return null;
}
if (isset($this->_parent)) {
return $this->_parent->getOffset($ref);
}
return null;
}
/**
* Get next object from a list of free objects.
*
* @param string $ref
* @return integer
* @throws Zend_Pdf_Exception
*/
public function getNextFree($ref)
{
if (isset($this->_inuse[$ref])) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not free');
}
if (isset($this->_free[$ref])) {
return $this->_free[$ref];
}
if (isset($this->_parent)) {
return $this->_parent->getNextFree($ref);
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object not found.');
}
/**
* Get next generation number for free object
*
* @param integer $objNum
* @return unknown
*/
public function getNewGeneration($objNum)
{
if (isset($this->_usedObjects[$objNum])) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not free');
}
if (isset($this->_generations[$objNum])) {
return $this->_generations[$objNum];
}
if (isset($this->_parent)) {
return $this->_parent->getNewGeneration($objNum);
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object not found.');
}
}

View File

@ -0,0 +1,130 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Stream.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf.php';
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'stream' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_Stream extends Zend_Pdf_Element
{
/**
* Object value
*
* @var Zend_Memory_Container
*/
public $value;
/**
* Object constructor
*
* @param string $val
*/
public function __construct($val)
{
$this->value = Zend_Pdf::getMemoryManager()->create($val);
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_STREAM;
}
/**
* Stream length.
* (Method is used to avoid string copying, which may occurs in some cases)
*
* @return integer
*/
public function length()
{
return strlen($this->value->getRef());
}
/**
* Clear stream
*
*/
public function clear()
{
$ref = &$this->value->getRef();
$ref = '';
$this->value->touch();
}
/**
* Append value to a stream
*
* @param mixed $val
*/
public function append($val)
{
$ref = &$this->value->getRef();
$ref .= (string)$val;
$this->value->touch();
}
/**
* Detach PDF object from the factory (if applicable), clone it and attach to new factory.
*
* @param Zend_Pdf_ElementFactory $factory The factory to attach
* @param array &$processed List of already processed indirect objects, used to avoid objects duplication
* @param integer $mode Cloning mode (defines filter for objects cloning)
* @returns Zend_Pdf_Element
*/
public function makeClone(Zend_Pdf_ElementFactory $factory, array &$processed, $mode)
{
return new self($this->value->getRef());
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return "stream\n" . $this->value->getRef() . "\nendstream";
}
}

View File

@ -0,0 +1,263 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: String.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF file 'string' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_String extends Zend_Pdf_Element
{
/**
* Object value
*
* @var string
*/
public $value;
/**
* Object constructor
*
* @param string $val
*/
public function __construct($val)
{
$this->value = (string)$val;
}
/**
* Return type of the element.
*
* @return integer
*/
public function getType()
{
return Zend_Pdf_Element::TYPE_STRING;
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return '(' . self::escape((string)$this->value) . ')';
}
/**
* Escape string according to the PDF rules
*
* @param string $str
* @return string
*/
public static function escape($str)
{
$outEntries = array();
foreach (str_split($str, 128) as $chunk) {
// Collect sequence of unescaped characters
$offset = strcspn($chunk, "\n\r\t\x08\x0C()\\");
$chunkOut = substr($chunk, 0, $offset);
while ($offset < strlen($chunk)) {
$nextCode = ord($chunk[$offset++]);
switch ($nextCode) {
// "\n" - line feed (LF)
case 10:
$chunkOut .= '\\n';
break;
// "\r" - carriage return (CR)
case 13:
$chunkOut .= '\\r';
break;
// "\t" - horizontal tab (HT)
case 9:
$chunkOut .= '\\t';
break;
// "\b" - backspace (BS)
case 8:
$chunkOut .= '\\b';
break;
// "\f" - form feed (FF)
case 12:
$chunkOut .= '\\f';
break;
// '(' - left paranthesis
case 40:
$chunkOut .= '\\(';
break;
// ')' - right paranthesis
case 41:
$chunkOut .= '\\)';
break;
// '\' - backslash
case 92:
$chunkOut .= '\\\\';
break;
default:
// This code is never executed extually
//
// Don't use non-ASCII characters escaping
// if ($nextCode >= 32 && $nextCode <= 126 ) {
// // Visible ASCII symbol
// $chunkEntries[] = chr($nextCode);
// } else {
// $chunkEntries[] = sprintf('\\%03o', $nextCode);
// }
break;
}
// Collect sequence of unescaped characters
$start = $offset;
$offset += strcspn($chunk, "\n\r\t\x08\x0C()\\", $offset);
$chunkOut .= substr($chunk, $start, $offset - $start);
}
$outEntries[] = $chunkOut;
}
return implode("\\\n", $outEntries);
}
/**
* Unescape string according to the PDF rules
*
* @param string $str
* @return string
*/
public static function unescape($str)
{
$outEntries = array();
$offset = 0;
while ($offset < strlen($str)) {
// Searche for the next escaped character/sequence
$escapeCharOffset = strpos($str, '\\', $offset);
if ($escapeCharOffset === false || $escapeCharOffset == strlen($str) - 1) {
// There are no escaped characters or '\' char has came at the end of string
$outEntries[] = substr($str, $offset);
break;
} else {
// Collect unescaped characters sequence
$outEntries[] = substr($str, $offset, $escapeCharOffset - $offset);
// Go to the escaped character
$offset = $escapeCharOffset + 1;
switch ($str[$offset]) {
// '\\n' - line feed (LF)
case 'n':
$outEntries[] = "\n";
break;
// '\\r' - carriage return (CR)
case 'r':
$outEntries[] = "\r";
break;
// '\\t' - horizontal tab (HT)
case 't':
$outEntries[] = "\t";
break;
// '\\b' - backspace (BS)
case 'b':
$outEntries[] = "\x08";
break;
// '\\f' - form feed (FF)
case 'f':
$outEntries[] = "\x0C";
break;
// '\\(' - left paranthesis
case '(':
$outEntries[] = '(';
break;
// '\\)' - right paranthesis
case ')':
$outEntries[] = ')';
break;
// '\\\\' - backslash
case '\\':
$outEntries[] = '\\';
break;
// "\\\n" or "\\\n\r"
case "\n":
// skip new line symbol
if ($str[$offset + 1] == "\r") {
$offset++;
}
break;
default:
if (strpos('0123456789', $str[$offset]) !== false) {
// Character in octal representation
// '\\xxx'
$nextCode = '0' . $str[$offset];
if (strpos('0123456789', $str[$offset + 1]) !== false) {
$nextCode .= $str[++$offset];
if (strpos('0123456789', $str[$offset + 1]) !== false) {
$nextCode .= $str[++$offset];
}
}
$outEntries[] = chr(octdec($nextCode));
} else {
$outEntries[] = $str[$offset];
}
break;
}
$offset++;
}
}
return implode($outEntries);
}
}

View File

@ -0,0 +1,98 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Binary.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Element_String */
// require_once 'Zend/Pdf/Element/String.php';
/**
* PDF file 'binary string' element implementation
*
* @category Zend
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Element_String_Binary extends Zend_Pdf_Element_String
{
/**
* Object value
*
* @var string
*/
public $value;
/**
* Escape string according to the PDF rules
*
* @param string $inStr
* @return string
*/
public static function escape($inStr)
{
return strtoupper(bin2hex($inStr));
}
/**
* Unescape string according to the PDF rules
*
* @param string $inStr
* @return string
*/
public static function unescape($inStr)
{
$chunks = array();
$offset = 0;
$length = 0;
while ($offset < strlen($inStr)) {
// Collect hexadecimal characters
$start = $offset;
$offset += strspn($inStr, "0123456789abcdefABCDEF", $offset);
$chunks[] = substr($inStr, $start, $offset - $start);
$length += strlen(end($chunks));
// Skip non-hexadecimal characters
$offset += strcspn($inStr, "0123456789abcdefABCDEF", $offset);
}
if ($length % 2 != 0) {
// We have odd number of digits.
// Final digit is assumed to be '0'
$chunks[] = '0';
}
return pack('H*' , implode($chunks));
}
/**
* Return object as string
*
* @param Zend_Pdf_Factory $factory
* @return string
*/
public function toString($factory = null)
{
return '<' . self::escape((string)$this->value) . '>';
}
}

View File

@ -0,0 +1,446 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: ElementFactory.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_ElementFactory_Interface */
// require_once 'Zend/Pdf/ElementFactory/Interface.php';
/**
* PDF element factory.
* Responsibility is to log PDF changes
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_ElementFactory implements Zend_Pdf_ElementFactory_Interface
{
/**
* List of the modified objects.
* Also contains new and removed objects
*
* Array: ojbectNumber => Zend_Pdf_Element_Object
*
* @var array
*/
private $_modifiedObjects = array();
/**
* List of the removed objects
*
* Array: ojbectNumber => Zend_Pdf_Element_Object
*
* @var SplObjectStorage
*/
private $_removedObjects;
/**
* List of registered objects.
* Used for resources clean up when factory is destroyed.
*
* Array of Zend_Pdf_Element objects
*
* @var array
*/
private $_registeredObjects = array();
/**
* PDF object counter.
* Actually it's an object number for new PDF object
*
* @var integer
*/
private $_objectCount;
/**
* List of the attached object factories.
* Array of Zend_Pdf_ElementFactory_Interface objects
*
* @var array
*/
private $_attachedFactories = array();
/**
* Factory internal id
*
* @var integer
*/
private $_factoryId;
/**
* Identity, used for factory id generation
*
* @var integer
*/
private static $_identity = 0;
/**
* Internal cache to save calculated shifts
*
* @var array
*/
private $_shiftCalculationCache = array();
/**
* Object constructor
*
* @param integer $objCount
*/
public function __construct($objCount)
{
$this->_objectCount = (int)$objCount;
$this->_factoryId = self::$_identity++;
$this->_removedObjects = new SplObjectStorage();
}
/**
* Get factory
*
* @return Zend_Pdf_ElementFactory_Interface
*/
public function getFactory()
{
return $this;
}
/**
* Factory generator
*
* @param integer $objCount
* @return Zend_Pdf_ElementFactory_Interface
*/
static public function createFactory($objCount)
{
// require_once 'Zend/Pdf/ElementFactory/Proxy.php';
return new Zend_Pdf_ElementFactory_Proxy(new Zend_Pdf_ElementFactory($objCount));
}
/**
* Close factory and clean-up resources
*
* @internal
*/
public function close()
{
$this->_modifiedObjects = null;
$this->_removedObjects = null;
$this->_attachedFactories = null;
foreach ($this->_registeredObjects as $obj) {
$obj->cleanUp();
}
$this->_registeredObjects = null;
}
/**
* Get source factory object
*
* @return Zend_Pdf_ElementFactory
*/
public function resolve()
{
return $this;
}
/**
* Get factory ID
*
* @return integer
*/
public function getId()
{
return $this->_factoryId;
}
/**
* Set object counter
*
* @param integer $objCount
*/
public function setObjectCount($objCount)
{
$this->_objectCount = (int)$objCount;
}
/**
* Get object counter
*
* @return integer
*/
public function getObjectCount()
{
$count = $this->_objectCount;
foreach ($this->_attachedFactories as $attached) {
$count += $attached->getObjectCount() - 1; // -1 as "0" object is a special case and shared between factories
}
return $count;
}
/**
* Attach factory to the current;
*
* @param Zend_Pdf_ElementFactory_Interface $factory
*/
public function attach(Zend_Pdf_ElementFactory_Interface $factory)
{
if ( $factory === $this || isset($this->_attachedFactories[$factory->getId()])) {
/**
* Don't attach factory twice.
* We do not check recusively because of nature of attach operation
* (Pages are always attached to the Documents, Fonts are always attached
* to the pages even if pages already use Document level object factory and so on)
*/
return;
}
$this->_attachedFactories[$factory->getId()] = $factory;
}
/**
* Calculate object enumeration shift.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
*/
public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory)
{
if ($factory === $this) {
return 0;
}
if (isset($this->_shiftCalculationCache[$factory->_factoryId])) {
return $this->_shiftCalculationCache[$factory->_factoryId];
}
$shift = $this->_objectCount - 1;
foreach ($this->_attachedFactories as $subFactory) {
$subFactoryShift = $subFactory->calculateShift($factory);
if ($subFactoryShift != -1) {
// context found
$this->_shiftCalculationCache[$factory->_factoryId] = $shift + $subFactoryShift;
return $shift + $subFactoryShift;
} else {
$shift += $subFactory->getObjectCount()-1;
}
}
$this->_shiftCalculationCache[$factory->_factoryId] = -1;
return -1;
}
/**
* Clean enumeration shift cache.
* Has to be used after PDF render operation to let followed updates be correct.
*/
public function cleanEnumerationShiftCache()
{
$this->_shiftCalculationCache = array();
foreach ($this->_attachedFactories as $attached) {
$attached->cleanEnumerationShiftCache();
}
}
/**
* Retrive object enumeration shift.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
* @throws Zend_Pdf_Exception
*/
public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory)
{
if (($shift = $this->calculateShift($factory)) == -1) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong object context');
}
return $shift;
}
/**
* Mark object as modified in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function markAsModified(Zend_Pdf_Element_Object $obj)
{
if ($obj->getFactory() !== $this) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not generated by this factory');
}
$this->_modifiedObjects[$obj->getObjNum()] = $obj;
}
/**
* Remove object in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function remove(Zend_Pdf_Element_Object $obj)
{
if (!$obj->compareFactory($this)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Object is not generated by this factory');
}
$this->_modifiedObjects[$obj->getObjNum()] = $obj;
$this->_removedObjects->attach($obj);
}
/**
* Generate new Zend_Pdf_Element_Object
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param Zend_Pdf_Element $objectValue
* @return Zend_Pdf_Element_Object
*/
public function newObject(Zend_Pdf_Element $objectValue)
{
// require_once 'Zend/Pdf/Element/Object.php';
$obj = new Zend_Pdf_Element_Object($objectValue, $this->_objectCount++, 0, $this);
$this->_modifiedObjects[$obj->getObjNum()] = $obj;
return $obj;
}
/**
* Generate new Zend_Pdf_Element_Object_Stream
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param mixed $objectValue
* @return Zend_Pdf_Element_Object_Stream
*/
public function newStreamObject($streamValue)
{
// require_once 'Zend/Pdf/Element/Object/Stream.php';
$obj = new Zend_Pdf_Element_Object_Stream($streamValue, $this->_objectCount++, 0, $this);
$this->_modifiedObjects[$obj->getObjNum()] = $obj;
return $obj;
}
/**
* Enumerate modified objects.
* Returns array of Zend_Pdf_UpdateInfoContainer
*
* @param Zend_Pdf_ElementFactory_Interface $rootFactory
* @return array
*/
public function listModifiedObjects($rootFactory = null)
{
if ($rootFactory == null) {
$rootFactory = $this;
$shift = 0;
} else {
$shift = $rootFactory->getEnumerationShift($this);
}
ksort($this->_modifiedObjects);
$result = array();
// require_once 'Zend/Pdf/UpdateInfoContainer.php';
foreach ($this->_modifiedObjects as $objNum => $obj) {
if ($this->_removedObjects->contains($obj)) {
$result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
$obj->getGenNum()+1,
true);
} else {
$result[$objNum+$shift] = new Zend_Pdf_UpdateInfoContainer($objNum + $shift,
$obj->getGenNum(),
false,
$obj->dump($rootFactory));
}
}
foreach ($this->_attachedFactories as $factory) {
$result += $factory->listModifiedObjects($rootFactory);
}
return $result;
}
/**
* Register object in the factory
*
* It's used to clear "parent object" referencies when factory is closed and clean up resources
*
* @param string $refString
* @param Zend_Pdf_Element_Object $obj
*/
public function registerObject(Zend_Pdf_Element_Object $obj, $refString)
{
$this->_registeredObjects[$refString] = $obj;
}
/**
* Fetch object specified by reference
*
* @param string $refString
* @return Zend_Pdf_Element_Object|null
*/
public function fetchObject($refString)
{
if (!isset($this->_registeredObjects[$refString])) {
return null;
}
return $this->_registeredObjects[$refString];
}
/**
* Check if PDF file was modified
*
* @return boolean
*/
public function isModified()
{
if (count($this->_modifiedObjects) != 0) {
return true;
}
foreach ($this->_attachedFactories as $subFactory) {
if ($subFactory->isModified()) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,158 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF element factory interface.
* Responsibility is to log PDF changes
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Pdf_ElementFactory_Interface
{
/**
* Get factory
*
* @return Zend_Pdf_ElementFactory_Interface
*/
public function getFactory();
/**
* Close factory and clean-up resources
*
* @internal
*/
public function close();
/**
* Get source factory object
*
* @return Zend_Pdf_ElementFactory
*/
public function resolve();
/**
* Get factory ID
*
* @return integer
*/
public function getId();
/**
* Set object counter
*
* @param integer $objCount
*/
public function setObjectCount($objCount);
/**
* Get object counter
*
* @return integer
*/
public function getObjectCount();
/**
* Attach factory to the current;
*
* @param Zend_Pdf_ElementFactory_Interface $factory
*/
public function attach(Zend_Pdf_ElementFactory_Interface $factory);
/**
* Calculate object enumeration shift.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
*/
public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory);
/**
* Clean enumeration shift cache.
* Has to be used after PDF render operation to let followed updates be correct.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
*/
public function cleanEnumerationShiftCache();
/**
* Retrive object enumeration shift.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
* @throws Zend_Pdf_Exception
*/
public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory);
/**
* Mark object as modified in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function markAsModified(Zend_Pdf_Element_Object $obj);
/**
* Remove object in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function remove(Zend_Pdf_Element_Object $obj);
/**
* Generate new Zend_Pdf_Element_Object
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param Zend_Pdf_Element $objectValue
* @return Zend_Pdf_Element_Object
*/
public function newObject(Zend_Pdf_Element $objectValue);
/**
* Generate new Zend_Pdf_Element_Object_Stream
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param mixed $objectValue
* @return Zend_Pdf_Element_Object_Stream
*/
public function newStreamObject($streamValue);
/**
* Enumerate modified objects.
* Returns array of Zend_Pdf_UpdateInfoContainer
*
* @param Zend_Pdf_ElementFactory $rootFactory
* @return array
*/
public function listModifiedObjects($rootFactory = null);
/**
* Check if PDF file was modified
*
* @return boolean
*/
public function isModified();
}

View File

@ -0,0 +1,234 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Proxy.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_ElementFactory_Interface */
// require_once 'Zend/Pdf/ElementFactory/Interface.php';
/**
* PDF element factory interface.
* Responsibility is to log PDF changes
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_ElementFactory_Proxy implements Zend_Pdf_ElementFactory_Interface
{
/**
* Factory object
*
* @var Zend_Pdf_ElementFactory_Interface
*/
private $_factory;
/**
* Object constructor
*
* @param Zend_Pdf_ElementFactory_Interface $factory
*/
public function __construct(Zend_Pdf_ElementFactory_Interface $factory)
{
$this->_factory = $factory;
}
public function __destruct()
{
$this->_factory->close();
$this->_factory = null;
}
/**
* Get factory
*
* @return Zend_Pdf_ElementFactory_Interface
*/
public function getFactory()
{
return $this->_factory->getFactory();
}
/**
* Close factory and clean-up resources
*
* @internal
*/
public function close()
{
// Do nothing
}
/**
* Get source factory object
*
* @return Zend_Pdf_ElementFactory
*/
public function resolve()
{
return $this->_factory->resolve();
}
/**
* Get factory ID
*
* @return integer
*/
public function getId()
{
return $this->_factory->getId();
}
/**
* Set object counter
*
* @param integer $objCount
*/
public function setObjectCount($objCount)
{
$this->_factory->setObjectCount($objCount);
}
/**
* Get object counter
*
* @return integer
*/
public function getObjectCount()
{
return $this->_factory->getObjectCount();
}
/**
* Attach factory to the current;
*
* @param Zend_Pdf_ElementFactory_Interface $factory
*/
public function attach(Zend_Pdf_ElementFactory_Interface $factory)
{
$this->_factory->attach($factory);
}
/**
* Calculate object enumeration shift.
*
* @internal
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
*/
public function calculateShift(Zend_Pdf_ElementFactory_Interface $factory)
{
return $this->_factory->calculateShift($factory);
}
/**
* Clean enumeration shift cache.
* Has to be used after PDF render operation to let followed updates be correct.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
*/
public function cleanEnumerationShiftCache()
{
return $this->_factory->cleanEnumerationShiftCache();
}
/**
* Retrive object enumeration shift.
*
* @param Zend_Pdf_ElementFactory_Interface $factory
* @return integer
* @throws Zend_Pdf_Exception
*/
public function getEnumerationShift(Zend_Pdf_ElementFactory_Interface $factory)
{
return $this->_factory->getEnumerationShift($factory);
}
/**
* Mark object as modified in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function markAsModified(Zend_Pdf_Element_Object $obj)
{
$this->_factory->markAsModified($obj);
}
/**
* Remove object in context of current factory.
*
* @param Zend_Pdf_Element_Object $obj
* @throws Zend_Pdf_Exception
*/
public function remove(Zend_Pdf_Element_Object $obj)
{
$this->_factory->remove($obj);
}
/**
* Generate new Zend_Pdf_Element_Object
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param Zend_Pdf_Element $objectValue
* @return Zend_Pdf_Element_Object
*/
public function newObject(Zend_Pdf_Element $objectValue)
{
return $this->_factory->newObject($objectValue);
}
/**
* Generate new Zend_Pdf_Element_Object_Stream
*
* @todo Reusage of the freed object. It's not a support of new feature, but only improvement.
*
* @param mixed $objectValue
* @return Zend_Pdf_Element_Object_Stream
*/
public function newStreamObject($streamValue)
{
return $this->_factory->newStreamObject($streamValue);
}
/**
* Enumerate modified objects.
* Returns array of Zend_Pdf_UpdateInfoContainer
*
* @param Zend_Pdf_ElementFactory $rootFactory
* @return array
*/
public function listModifiedObjects($rootFactory = null)
{
return $this->_factory->listModifiedObjects($rootFactory);
}
/**
* Check if PDF file was modified
*
* @return boolean
*/
public function isModified()
{
return $this->_factory->isModified();
}
}

View File

@ -0,0 +1,343 @@
<?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 Core
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Exception */
// require_once 'Zend/Exception.php';
/**
* Exception class for Zend_Pdf.
*
* If you expect a certain type of exception to be caught and handled by the
* caller, create a constant for it here and include it in the object being
* thrown. Example:
*
* throw new Zend_Pdf_Exception('foo() is not yet implemented',
* Zend_Pdf_Exception::NOT_IMPLEMENTED);
*
* This allows the caller to determine the specific type of exception that was
* thrown without resorting to parsing the descriptive text.
*
* IMPORTANT: Do not rely on numeric values of the constants! They are grouped
* sequentially below for organizational purposes only. The numbers may come to
* mean something in the future, but they are subject to renumbering at any
* time. ALWAYS use the symbolic constant names, which are guaranteed never to
* change, in logical checks! You have been warned.
*
* @package Zend_Pdf
* @subpackage Core
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Exception extends Zend_Exception
{
/**** Class Constants ****/
/* Generic Exceptions */
/**
* The feature or option is planned but has not yet been implemented. It
* should be available in a future revision of the framework.
*/
const NOT_IMPLEMENTED = 0x0001;
/**
* The feature or option has been deprecated and will be removed in a future
* revision of the framework. The descriptive text accompanying this
* exception should explain how to use the replacement features or options.
*/
const DEPRECATED = 0x0002;
/**
* Not enough paramaters were supplied to the method.
*/
const TOO_FEW_PARAMETERS = 0x0003;
/**
* A parameter was of the wrong data type.
*/
const BAD_PARAMETER_TYPE = 0x0004;
/**
* A parameter contained an unusable value.
*/
const BAD_PARAMETER_VALUE = 0x0005;
/**
* A parameter value was not within the expected range.
*/
const PARAMETER_VALUE_OUT_OF_RANGE = 0x0006;
/**
* The method that has multiple signatures could not understand the
* number and/or types of parameters.
*/
const BAD_METHOD_SIGNATURE = 0x0007;
/**
* An array or string index was out of range.
*/
const INDEX_OUT_OF_RANGE = 0x0008;
/* Filesystem I/O */
/**
* The file path was unusable or invalid.
*/
const BAD_FILE_PATH = 0x0101;
/**
* The file is not readable by the current user.
*/
const NOT_READABLE = 0x0102;
/**
* The file is not writeable by the current user.
*/
const NOT_WRITEABLE = 0x0103;
/**
* The file resource has been closed unexpectedly.
*/
const FILE_NOT_OPEN = 0x0104;
/**
* An error was encountered while attempting to open the file.
*/
const CANT_OPEN_FILE = 0x0105;
/**
* An error was encountered while attempting to obtain the current file
* position.
*/
const CANT_GET_FILE_POSITION = 0x0106;
/**
* An error was encountered while attempting to set a new file position.
*/
const CANT_SET_FILE_POSITION = 0x0107;
/**
* An attempt was made to move the current file position before the start
* of the file.
*/
const MOVE_BEFORE_START_OF_FILE = 0x0108;
/**
* An attempt was made to move the current file position beyond the end of
* the file.
*/
const MOVE_BEYOND_END_OF_FILE = 0x0109;
/**
* An error was encountered while attempting to obtain the file size.
*/
const CANT_GET_FILE_SIZE = 0x010a;
/**
* An error was encountered while attempting to read data from the file.
*/
const ERROR_DURING_READ = 0x010b;
/**
* An error was encountered while attempting to write data to the file.
*/
const ERROR_DURING_WRITE = 0x010c;
/**
* An incompatible page size was specified for a buffered read operation.
*/
const INVALID_PAGE_SIZE = 0x010d;
/**
* There is insufficient data to fulfill the read request.
*/
const INSUFFICIENT_DATA = 0x010e;
/* Zend_Pdf_FileParser */
/**
* The file parser data source object was invalid or improperly initialized.
*/
const BAD_DATA_SOURCE = 0x0201;
/**
* An unknown byte order was specified.
*/
const INVALID_BYTE_ORDER = 0x0202;
/**
* An invalid integer size was specified.
*/
const INVALID_INTEGER_SIZE = 0x0203;
/**
* An invalid fixed-point number size was specified.
*/
const BAD_FIXED_POINT_SIZE = 0x0204;
/**
* The string cannot be read.
*/
const CANT_READ_STRING = 0x0205;
/**
* This file type must be parsed in a specific order and a parsing method
* was called out-of-turn.
*/
const PARSED_OUT_OF_ORDER = 0x0206;
/* Zend_Pdf_FileParser_Font and Subclasses */
/**
* The font file type is incorrect.
*/
const WRONG_FONT_TYPE = 0x0301;
/**
* The number of tables contained in the font is outside the expected range.
*/
const BAD_TABLE_COUNT = 0x0302;
/**
* A required table was not present in the font.
*/
const REQUIRED_TABLE_NOT_FOUND = 0x0303;
/**
* The parser does not understand this version of this table in the font.
*/
const DONT_UNDERSTAND_TABLE_VERSION = 0x0303;
/**
* The magic number in the font file is incorrect.
*/
const BAD_MAGIC_NUMBER = 0x0304;
/**
* Could not locate a usable character map for this font.
*/
const CANT_FIND_GOOD_CMAP = 0x0305;
/* Zend_Pdf_Cmap and Subclasses */
/**
* The character map type is currently unsupported.
*/
const CMAP_TYPE_UNSUPPORTED = 0x0401;
/**
* The type of the character map is not understood.
*/
const CMAP_UNKNOWN_TYPE = 0x0402;
/**
* The character map table data is too small.
*/
const CMAP_TABLE_DATA_TOO_SMALL = 0x0403;
/**
* The character map table data is for a different type of table.
*/
const CMAP_WRONG_TABLE_TYPE = 0x0404;
/**
* The character map table data contains in incorrect length.
*/
const CMAP_WRONG_TABLE_LENGTH = 0x0405;
/**
* This character map table is language-dependent. Character maps must be
* language-independent.
*/
const CMAP_NOT_LANGUAGE_INDEPENDENT = 0x0406;
/**
* The final byte offset when reading the character map table data does not
* match the reported length of the table.
*/
const CMAP_FINAL_OFFSET_NOT_LENGTH = 0x0407;
/**
* The character map subtable entry count does not match the expected value.
*/
const CMAP_WRONG_ENTRY_COUNT = 0x0408;
/* Zend_Pdf_Resource_Font and Subclasses */
/**
* The specified glyph number is out of range for this font.
*/
const GLYPH_OUT_OF_RANGE = 0x0501;
/**
* This font program has copyright bits set which prevent it from being
* embedded in the PDF file. You must specify the no-embed option to use
* this font.
*/
const FONT_CANT_BE_EMBEDDED = 0x0502;
/* Zend_Pdf_Font */
/**
* The font name did not match any previously instantiated font and is not
* one of the standard 14 PDF fonts.
*/
const BAD_FONT_NAME = 0x0601;
/**
* The factory method could not determine the type of the font file.
*/
const CANT_DETERMINE_FONT_TYPE = 0x0602;
/* Text Layout System */
/**
* The specified attribute value for the text object cannot be used.
*/
const BAD_ATTRIBUTE_VALUE = 0x0701;
/* Zend_Pdf_Image and Subclasses */
const CANT_DETERMINE_IMAGE_TYPE = 0x0801;
const WRONG_IMAGE_TYPE = 0x0802;
const UNSUPPORTED_IMAGE_ENCODING_OPTIONS = 0x0803;
const IMAGE_FILE_CORRUPT = 0x0804;
}

View File

@ -0,0 +1,485 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FileParser.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Abstract utility class for parsing binary files.
*
* Provides a library of methods to quickly navigate and extract various data
* types (signed and unsigned integers, floating- and fixed-point numbers,
* strings, etc.) from the file.
*
* File access is managed via a {@link Zend_Pdf_FileParserDataSource} object.
* This allows the same parser code to work with many different data sources:
* in-memory objects, filesystem files, etc.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_FileParser
{
/**** Class Constants ****/
/**
* Little-endian byte order (0x04 0x03 0x02 0x01).
*/
const BYTE_ORDER_LITTLE_ENDIAN = 0;
/**
* Big-endian byte order (0x01 0x02 0x03 0x04).
*/
const BYTE_ORDER_BIG_ENDIAN = 1;
/**** Instance Variables ****/
/**
* Flag indicating that the file has passed a cursory validation check.
* @var boolean
*/
protected $_isScreened = false;
/**
* Flag indicating that the file has been sucessfully parsed.
* @var boolean
*/
protected $_isParsed = false;
/**
* Object representing the data source to be parsed.
* @var Zend_Pdf_FileParserDataSource
*/
protected $_dataSource = null;
/**** Public Interface ****/
/* Abstract Methods */
/**
* Performs a cursory check to verify that the binary file is in the expected
* format. Intended to quickly weed out obviously bogus files.
*
* Must set $this->_isScreened to true if successful.
*
* @throws Zend_Pdf_Exception
*/
abstract public function screen();
/**
* Reads and parses the complete binary file.
*
* Must set $this->_isParsed to true if successful.
*
* @throws Zend_Pdf_Exception
*/
abstract public function parse();
/* Object Lifecycle */
/**
* Object constructor.
*
* Verifies that the data source has been properly initialized.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_FileParserDataSource $dataSource)
{
if ($dataSource->getSize() == 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('The data source has not been properly initialized',
Zend_Pdf_Exception::BAD_DATA_SOURCE);
}
$this->_dataSource = $dataSource;
}
/**
* Object destructor.
*
* Discards the data source object.
*/
public function __destruct()
{
$this->_dataSource = null;
}
/* Accessors */
/**
* Returns true if the file has passed a cursory validation check.
*
* @return boolean
*/
public function isScreened()
{
return $this->_isScreened;
}
/**
* Returns true if the file has been successfully parsed.
*
* @return boolean
*/
public function isParsed()
{
return $this->_isParsed;
}
/**
* Returns the data source object representing the file being parsed.
*
* @return Zend_Pdf_FileParserDataSource
*/
public function getDataSource()
{
return $this->_dataSource;
}
/* Primitive Methods */
/**
* Convenience wrapper for the data source object's moveToOffset() method.
*
* @param integer $offset Destination byte offset.
* @throws Zend_Pdf_Exception
*/
public function moveToOffset($offset)
{
$this->_dataSource->moveToOffset($offset);
}
public function getOffset() {
return $this->_dataSource->getOffset();
}
public function getSize() {
return $this->_dataSource->getSize();
}
/**
* Convenience wrapper for the data source object's readBytes() method.
*
* @param integer $byteCount Number of bytes to read.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readBytes($byteCount)
{
return $this->_dataSource->readBytes($byteCount);
}
/**
* Convenience wrapper for the data source object's skipBytes() method.
*
* @param integer $byteCount Number of bytes to skip.
* @throws Zend_Pdf_Exception
*/
public function skipBytes($byteCount)
{
$this->_dataSource->skipBytes($byteCount);
}
/* Parser Methods */
/**
* Reads the signed integer value from the binary file at the current byte
* offset.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* @param integer $size Size of integer in bytes: 1-4
* @param integer $byteOrder (optional) Big- or little-endian byte order.
* Use the BYTE_ORDER_ constants defined in {@link Zend_Pdf_FileParser}.
* If omitted, uses big-endian.
* @return integer
* @throws Zend_Pdf_Exception
*/
public function readInt($size, $byteOrder = Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
{
if (($size < 1) || ($size > 4)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid signed integer size: $size",
Zend_Pdf_Exception::INVALID_INTEGER_SIZE);
}
$bytes = $this->_dataSource->readBytes($size);
/* unpack() will not work for this method because it always works in
* the host byte order for signed integers. It also does not allow for
* variable integer sizes.
*/
if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN) {
$number = ord($bytes[0]);
if (($number & 0x80) == 0x80) {
/* This number is negative. Extract the positive equivalent.
*/
$number = (~ $number) & 0xff;
for ($i = 1; $i < $size; $i++) {
$number = ($number << 8) | ((~ ord($bytes[$i])) & 0xff);
}
/* Now turn this back into a negative number by taking the
* two's complement (we didn't add one above so won't
* subtract it below). This works reliably on both 32- and
* 64-bit systems.
*/
$number = ~$number;
} else {
for ($i = 1; $i < $size; $i++) {
$number = ($number << 8) | ord($bytes[$i]);
}
}
} else if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_LITTLE_ENDIAN) {
$number = ord($bytes[$size - 1]);
if (($number & 0x80) == 0x80) {
/* Negative number. See discussion above.
*/
$number = 0;
for ($i = --$size; $i >= 0; $i--) {
$number |= ((~ ord($bytes[$i])) & 0xff) << ($i * 8);
}
$number = ~$number;
} else {
$number = 0;
for ($i = --$size; $i >= 0; $i--) {
$number |= ord($bytes[$i]) << ($i * 8);
}
}
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid byte order: $byteOrder",
Zend_Pdf_Exception::INVALID_BYTE_ORDER);
}
return $number;
}
/**
* Reads the unsigned integer value from the binary file at the current byte
* offset.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* NOTE: If you ask for a 4-byte unsigned integer on a 32-bit machine, the
* resulting value WILL BE SIGNED because PHP uses signed integers internally
* for everything. To guarantee portability, be sure to use bitwise operators
* operators on large unsigned integers!
*
* @param integer $size Size of integer in bytes: 1-4
* @param integer $byteOrder (optional) Big- or little-endian byte order.
* Use the BYTE_ORDER_ constants defined in {@link Zend_Pdf_FileParser}.
* If omitted, uses big-endian.
* @return integer
* @throws Zend_Pdf_Exception
*/
public function readUInt($size, $byteOrder = Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
{
if (($size < 1) || ($size > 4)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid unsigned integer size: $size",
Zend_Pdf_Exception::INVALID_INTEGER_SIZE);
}
$bytes = $this->_dataSource->readBytes($size);
/* unpack() is a bit heavyweight for this simple conversion. Just
* work the bytes directly.
*/
if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN) {
$number = ord($bytes[0]);
for ($i = 1; $i < $size; $i++) {
$number = ($number << 8) | ord($bytes[$i]);
}
} else if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_LITTLE_ENDIAN) {
$number = 0;
for ($i = --$size; $i >= 0; $i--) {
$number |= ord($bytes[$i]) << ($i * 8);
}
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid byte order: $byteOrder",
Zend_Pdf_Exception::INVALID_BYTE_ORDER);
}
return $number;
}
/**
* Returns true if the specified bit is set in the integer bitfield.
*
* @param integer $bit Bit number to test (i.e. - 0-31)
* @param integer $bitField
* @return boolean
*/
public function isBitSet($bit, $bitField)
{
$bitMask = 1 << $bit;
$isSet = (($bitField & $bitMask) == $bitMask);
return $isSet;
}
/**
* Reads the signed fixed-point number from the binary file at the current
* byte offset.
*
* Common fixed-point sizes are 2.14 and 16.16.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* @param integer $mantissaBits Number of bits in the mantissa
* @param integer $fractionBits Number of bits in the fraction
* @param integer $byteOrder (optional) Big- or little-endian byte order.
* Use the BYTE_ORDER_ constants defined in {@link Zend_Pdf_FileParser}.
* If omitted, uses big-endian.
* @return float
* @throws Zend_Pdf_Exception
*/
public function readFixed($mantissaBits, $fractionBits,
$byteOrder = Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN)
{
$bitsToRead = $mantissaBits + $fractionBits;
if (($bitsToRead % 8) !== 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Fixed-point numbers are whole bytes',
Zend_Pdf_Exception::BAD_FIXED_POINT_SIZE);
}
$number = $this->readInt(($bitsToRead >> 3), $byteOrder) / (1 << $fractionBits);
return $number;
}
/**
* Reads the Unicode UTF-16-encoded string from the binary file at the
* current byte offset.
*
* The byte order of the UTF-16 string must be specified. You must also
* supply the desired resulting character set.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* @todo Consider changing $byteCount to a character count. They are not
* always equivalent (in the case of surrogates).
* @todo Make $byteOrder optional if there is a byte-order mark (BOM) in the
* string being extracted.
*
* @param integer $byteCount Number of bytes (characters * 2) to return.
* @param integer $byteOrder (optional) Big- or little-endian byte order.
* Use the BYTE_ORDER_ constants defined in {@link Zend_Pdf_FileParser}.
* If omitted, uses big-endian.
* @param string $characterSet (optional) Desired resulting character set.
* You may use any character set supported by {@link iconv()}. If omitted,
* uses 'current locale'.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringUTF16($byteCount,
$byteOrder = Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN,
$characterSet = '')
{
if ($byteCount == 0) {
return '';
}
$bytes = $this->_dataSource->readBytes($byteCount);
if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN) {
if ($characterSet == 'UTF-16BE') {
return $bytes;
}
return iconv('UTF-16BE', $characterSet, $bytes);
} else if ($byteOrder == Zend_Pdf_FileParser::BYTE_ORDER_LITTLE_ENDIAN) {
if ($characterSet == 'UTF-16LE') {
return $bytes;
}
return iconv('UTF-16LE', $characterSet, $bytes);
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid byte order: $byteOrder",
Zend_Pdf_Exception::INVALID_BYTE_ORDER);
}
}
/**
* Reads the Mac Roman-encoded string from the binary file at the current
* byte offset.
*
* You must supply the desired resulting character set.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* @param integer $byteCount Number of bytes (characters) to return.
* @param string $characterSet (optional) Desired resulting character set.
* You may use any character set supported by {@link iconv()}. If omitted,
* uses 'current locale'.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringMacRoman($byteCount, $characterSet = '')
{
if ($byteCount == 0) {
return '';
}
$bytes = $this->_dataSource->readBytes($byteCount);
if ($characterSet == 'MacRoman') {
return $bytes;
}
return iconv('MacRoman', $characterSet, $bytes);
}
/**
* Reads the Pascal string from the binary file at the current byte offset.
*
* The length of the Pascal string is determined by reading the length bytes
* which preceed the character data. You must supply the desired resulting
* character set.
*
* Advances the offset by the number of bytes read. Throws an exception if
* an error occurs.
*
* @param string $characterSet (optional) Desired resulting character set.
* You may use any character set supported by {@link iconv()}. If omitted,
* uses 'current locale'.
* @param integer $lengthBytes (optional) Number of bytes that make up the
* length. Default is 1.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringPascal($characterSet = '', $lengthBytes = 1)
{
$byteCount = $this->readUInt($lengthBytes);
if ($byteCount == 0) {
return '';
}
$bytes = $this->_dataSource->readBytes($byteCount);
if ($characterSet == 'ASCII') {
return $bytes;
}
return iconv('ASCII', $characterSet, $bytes);
}
}

View File

@ -0,0 +1,217 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Font.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Font.php';
/** Zend_Pdf_FileParser */
// require_once 'Zend/Pdf/FileParser.php';
/**
* Abstract helper class for {@link Zend_Pdf_Font} that parses font files.
*
* Defines the public interface for concrete subclasses which are responsible
* for parsing the raw binary data from the font file on disk. Also provides
* a debug logging interface and a couple of shared utility methods.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_FileParser_Font extends Zend_Pdf_FileParser
{
/**** Instance Variables ****/
/**
* Array of parsed font properties. Used with {@link __get()} and
* {@link __set()}.
* @var array
*/
private $_fontProperties = array();
/**
* Flag indicating whether or not debug logging is active.
* @var boolean
*/
private $_debug = false;
/**** Public Interface ****/
/* Object Lifecycle */
/**
* Object constructor.
*
* Validates the data source and enables debug logging if so configured.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_FileParserDataSource $dataSource)
{
parent::__construct($dataSource);
$this->fontType = Zend_Pdf_Font::TYPE_UNKNOWN;
}
/* Accessors */
/**
* Get handler
*
* @param string $property
* @return mixed
*/
public function __get($property)
{
if (isset($this->_fontProperties[$property])) {
return $this->_fontProperties[$property];
} else {
return null;
}
}
/* NOTE: The set handler is defined below in the internal methods group. */
/* Parser Methods */
/**
* Reads the Unicode UTF-16-encoded string from the binary file at the
* current offset location. Overridden to fix return character set at UTF-16BE.
*
* @todo Deal with to-dos in the parent method.
*
* @param integer $byteCount Number of bytes (characters * 2) to return.
* @param integer $byteOrder (optional) Big- or little-endian byte order.
* Use the BYTE_ORDER_ constants defined in {@link Zend_Pdf_FileParser}. If
* omitted, uses big-endian.
* @param string $characterSet (optional) --Ignored--
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringUTF16($byteCount,
$byteOrder = Zend_Pdf_FileParser::BYTE_ORDER_BIG_ENDIAN,
$characterSet = '')
{
return parent::readStringUTF16($byteCount, $byteOrder, 'UTF-16BE');
}
/**
* Reads the Mac Roman-encoded string from the binary file at the current
* offset location. Overridden to fix return character set at UTF-16BE.
*
* @param integer $byteCount Number of bytes (characters) to return.
* @param string $characterSet (optional) --Ignored--
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringMacRoman($byteCount, $characterSet = '')
{
return parent::readStringMacRoman($byteCount, 'UTF-16BE');
}
/**
* Reads the Pascal string from the binary file at the current offset
* location. Overridden to fix return character set at UTF-16BE.
*
* @param string $characterSet (optional) --Ignored--
* @param integer $lengthBytes (optional) Number of bytes that make up the
* length. Default is 1.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readStringPascal($characterSet = '', $lengthBytes = 1)
{
return parent::readStringPascal('UTF-16BE');
}
/* Utility Methods */
/**
* Writes the entire font properties array to STDOUT. Used only for debugging.
*/
public function writeDebug()
{
print_r($this->_fontProperties);
}
/**** Internal Methods ****/
/* Internal Accessors */
/**
* Set handler
*
* NOTE: This method is protected. Other classes may freely interrogate
* the font properties, but only this and its subclasses may set them.
*
* @param string $property
* @param mixed $value
*/
public function __set($property, $value)
{
if ($value === null) {
unset($this->_fontProperties[$property]);
} else {
$this->_fontProperties[$property] = $value;
}
}
/* Internal Utility Methods */
/**
* If debug logging is enabled, writes the log message.
*
* The log message is a sprintf() style string and any number of arguments
* may accompany it as additional parameters.
*
* @param string $message
* @param mixed (optional, multiple) Additional arguments
*/
protected function _debugLog($message)
{
if (! $this->_debug) {
return;
}
if (func_num_args() > 1) {
$args = func_get_args();
$message = array_shift($args);
$message = vsprintf($message, $args);
}
// require_once 'Zend/Log.php';
$logger = new Zend_Log();
$logger->log($message, Zend_Log::DEBUG);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: TrueType.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_FileParser_Font_OpenType */
// require_once 'Zend/Pdf/FileParser/Font/OpenType.php';
/**
* Parses an OpenType font file containing TrueType outlines.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_FileParser_Font_OpenType_TrueType extends Zend_Pdf_FileParser_Font_OpenType
{
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Verifies that the font file actually contains TrueType outlines.
*
* @throws Zend_Pdf_Exception
*/
public function screen()
{
if ($this->_isScreened) {
return;
}
parent::screen();
switch ($this->_readScalerType()) {
case 0x00010000: // version 1.0 - Windows TrueType signature
break;
case 0x74727565: // 'true' - Macintosh TrueType signature
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not a TrueType font file',
Zend_Pdf_Exception::WRONG_FONT_TYPE);
}
$this->fontType = Zend_Pdf_Font::TYPE_TRUETYPE;
$this->_isScreened = true;
}
/**
* Reads and parses the TrueType font data from the file on disk.
*
* @throws Zend_Pdf_Exception
*/
public function parse()
{
if ($this->_isParsed) {
return;
}
parent::parse();
/* There is nothing additional to parse for TrueType fonts at this time.
*/
$this->_isParsed = true;
}
}

View File

@ -0,0 +1,63 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Image.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
/** Zend_Pdf_Image */
// require_once 'Zend/Pdf/Image.php';
/** Zend_Pdf_FileParser */
// require_once 'Zend/Pdf/FileParser.php';
/**
* FileParser for Zend_Pdf_Image subclasses.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_FileParser_Image extends Zend_Pdf_FileParser
{
/**
* Image Type
*
* @var integer
*/
protected $imageType;
/**
* Object constructor.
*
* Validates the data source and enables debug logging if so configured.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @throws Zend_Pdf_Exception
*/
public function __construct(Zend_Pdf_FileParserDataSource $dataSource)
{
parent::__construct($dataSource);
$this->imageType = Zend_Pdf_Image::TYPE_UNKNOWN;
}
}

View File

@ -0,0 +1,329 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Png.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** @see Zend_Pdf_FileParser_Image */
// require_once 'Zend/Pdf/FileParser/Image.php';
/**
* Abstract base class for Image file parsers.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_FileParser_Image_Png extends Zend_Pdf_FileParser_Image
{
protected $_isPNG;
protected $_width;
protected $_height;
protected $_bits;
protected $_color;
protected $_compression;
protected $_preFilter;
protected $_interlacing;
protected $_imageData;
protected $_paletteData;
protected $_transparencyData;
/**** Public Interface ****/
public function getWidth() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_width;
}
public function getHeight() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_width;
}
public function getBitDepth() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_bits;
}
public function getColorSpace() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_color;
}
public function getCompressionStrategy() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_compression;
}
public function getPaethFilter() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_preFilter;
}
public function getInterlacingMode() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_interlacing;
}
public function getRawImageData() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_imageData;
}
public function getRawPaletteData() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_paletteData;
}
public function getRawTransparencyData() {
if(!$this->_isParsed) {
$this->parse();
}
return $this->_transparencyData;
}
/* Semi-Concrete Class Implementation */
/**
* Verifies that the image file is in the expected format.
*
* @throws Zend_Pdf_Exception
*/
public function screen()
{
if ($this->_isScreened) {
return;
}
return $this->_checkSignature();
}
/**
* Reads and parses the image data from the file on disk.
*
* @throws Zend_Pdf_Exception
*/
public function parse()
{
if ($this->_isParsed) {
return;
}
/* Screen the font file first, if it hasn't been done yet.
*/
$this->screen();
$this->_parseIHDRChunk();
$this->_parseChunks();
}
protected function _parseSignature() {
$this->moveToOffset(1); //Skip the first byte (%)
if('PNG' != $this->readBytes(3)) {
$this->_isPNG = false;
} else {
$this->_isPNG = true;
}
}
protected function _checkSignature() {
if(!isset($this->_isPNG)) {
$this->_parseSignature();
}
return $this->_isPNG;
}
protected function _parseChunks() {
$this->moveToOffset(33); //Variable chunks start at the end of IHDR
//Start processing chunks. If there are no more bytes to read parsing is complete.
$size = $this->getSize();
while($size - $this->getOffset() >= 8) {
$chunkLength = $this->readUInt(4);
if($chunkLength < 0 || ($chunkLength + $this->getOffset() + 4) > $size) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("PNG Corrupt: Invalid Chunk Size In File.");
}
$chunkType = $this->readBytes(4);
$offset = $this->getOffset();
//If we know how to process the chunk, do it here, else ignore the chunk and move on to the next
switch($chunkType) {
case 'IDAT': // This chunk may appear more than once. It contains the actual image data.
$this->_parseIDATChunk($offset, $chunkLength);
break;
case 'PLTE': // This chunk contains the image palette.
$this->_parsePLTEChunk($offset, $chunkLength);
break;
case 'tRNS': // This chunk contains non-alpha channel transparency data
$this->_parseTRNSChunk($offset, $chunkLength);
break;
case 'IEND':
break 2; //End the loop too
//@TODO Implement the rest of the PNG chunks. (There are many not implemented here)
}
if($offset + $chunkLength + 4 < $size) {
$this->moveToOffset($offset + $chunkLength + 4); //Skip past the data finalizer. (Don't rely on the parse to leave the offsets correct)
}
}
if(empty($this->_imageData)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception ( "This PNG is corrupt. All png must contain IDAT chunks." );
}
}
protected function _parseIHDRChunk() {
$this->moveToOffset(12); //IHDR must always start at offset 12 and run for 17 bytes
if(!$this->readBytes(4) == 'IHDR') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "This PNG is corrupt. The first chunk in a PNG file must be IHDR." );
}
$this->_width = $this->readUInt(4);
$this->_height = $this->readUInt(4);
$this->_bits = $this->readInt(1);
$this->_color = $this->readInt(1);
$this->_compression = $this->readInt(1);
$this->_preFilter = $this->readInt(1);
$this->_interlacing = $this->readInt(1);
if($this->_interlacing != Zend_Pdf_Image::PNG_INTERLACING_DISABLED) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Only non-interlaced images are currently supported." );
}
}
protected function _parseIDATChunk($chunkOffset, $chunkLength) {
$this->moveToOffset($chunkOffset);
if(!isset($this->_imageData)) {
$this->_imageData = $this->readBytes($chunkLength);
} else {
$this->_imageData .= $this->readBytes($chunkLength);
}
}
protected function _parsePLTEChunk($chunkOffset, $chunkLength) {
$this->moveToOffset($chunkOffset);
$this->_paletteData = $this->readBytes($chunkLength);
}
protected function _parseTRNSChunk($chunkOffset, $chunkLength) {
$this->moveToOffset($chunkOffset);
//Processing of tRNS data varies dependending on the color depth
switch($this->_color) {
case Zend_Pdf_Image::PNG_CHANNEL_GRAY:
$baseColor = $this->readInt(1);
$this->_transparencyData = array($baseColor, $baseColor);
break;
case Zend_Pdf_Image::PNG_CHANNEL_RGB:
//@TODO Fix this hack.
//This parser cheats and only uses the lsb's (and only works with < 16 bit depth images)
/*
From the standard:
For color type 2 (truecolor), the tRNS chunk contains a single RGB color value, stored in the format:
Red: 2 bytes, range 0 .. (2^bitdepth)-1
Green: 2 bytes, range 0 .. (2^bitdepth)-1
Blue: 2 bytes, range 0 .. (2^bitdepth)-1
(If the image bit depth is less than 16, the least significant bits are used and the others are 0.)
Pixels of the specified color value are to be treated as transparent (equivalent to alpha value 0);
all other pixels are to be treated as fully opaque (alpha value 2bitdepth-1).
*/
$red = $this->readInt(1);
$this->skipBytes(1);
$green = $this->readInt(1);
$this->skipBytes(1);
$blue = $this->readInt(1);
$this->_transparencyData = array($red, $red, $green, $green, $blue, $blue);
break;
case Zend_Pdf_Image::PNG_CHANNEL_INDEXED:
//@TODO Fix this hack.
//This parser cheats too. It only masks the first color in the palette.
/*
From the standard:
For color type 3 (indexed color), the tRNS chunk contains a series of one-byte alpha values, corresponding to entries in the PLTE chunk:
Alpha for palette index 0: 1 byte
Alpha for palette index 1: 1 byte
...etc...
Each entry indicates that pixels of the corresponding palette index must be treated as having the specified alpha value.
Alpha values have the same interpretation as in an 8-bit full alpha channel: 0 is fully transparent, 255 is fully opaque,
regardless of image bit depth. The tRNS chunk must not contain more alpha values than there are palette entries,
but tRNS can contain fewer values than there are palette entries. In this case, the alpha value for all remaining palette
entries is assumed to be 255. In the common case in which only palette index 0 need be made transparent, only a one-byte
tRNS chunk is needed.
*/
$tmpData = $this->readBytes($chunkLength);
if(($trnsIdx = strpos($tmpData, "\0")) !== false) {
$this->_transparencyData = array($trnsIdx, $trnsIdx);
}
break;
case Zend_Pdf_Image::PNG_CHANNEL_GRAY_ALPHA:
//Fall through to the next case
case Zend_Pdf_Image::PNG_CHANNEL_RGB_ALPHA:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "tRNS chunk illegal for Alpha Channel Images" );
break;
}
}
}

View File

@ -0,0 +1,189 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: FileParserDataSource.php 24806 2012-05-15 11:32:11Z adamlundrigan $
*/
/**
* Abstract helper class for {@link Zend_Pdf_FileParser} that provides the
* data source for parsing.
*
* Concrete subclasses allow for parsing of in-memory, filesystem, and other
* sources through a common API. These subclasses also take care of error
* handling and other mundane tasks.
*
* Subclasses must implement at minimum {@link __construct()},
* {@link __destruct()}, {@link readBytes()}, and {@link readAllBytes()}.
* Subclasses should also override {@link moveToOffset()} and
* {@link __toString()} as appropriate.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_FileParserDataSource
{
/**** Instance Variables ****/
/**
* Total size in bytes of the data source.
* @var integer
*/
protected $_size = 0;
/**
* Byte offset of the current read position within the data source.
* @var integer
*/
protected $_offset = 0;
/**** Public Interface ****/
/* Abstract Methods */
/**
* Object destructor. Closes the data source.
*
* May also perform cleanup tasks such as deleting temporary files.
*/
abstract public function __destruct();
/**
* Returns the specified number of raw bytes from the data source at the
* byte offset of the current read position.
*
* Must advance the read position by the number of bytes read by updating
* $this->_offset.
*
* Throws an exception if there is insufficient data to completely fulfill
* the request or if an error occurs.
*
* @param integer $byteCount Number of bytes to read.
* @return string
* @throws Zend_Pdf_Exception
*/
abstract public function readBytes($byteCount);
/**
* Returns the entire contents of the data source as a string.
*
* This method may be called at any time and so must preserve the byte
* offset of the read position, both through $this->_offset and whatever
* other additional pointers (such as the seek position of a file pointer)
* that might be used.
*
* @return string
*/
abstract public function readAllBytes();
/* Object Magic Methods */
/**
* Returns a description of the object for debugging purposes.
*
* Subclasses should override this method to provide a more specific
* description of the actual object being represented.
*
* @return string
*/
public function __toString()
{
return get_class($this);
}
/* Accessors */
/**
* Returns the byte offset of the current read position within the data
* source.
*
* @return integer
*/
public function getOffset()
{
return $this->_offset;
}
/**
* Returns the total size in bytes of the data source.
*
* @return integer
*/
public function getSize()
{
return $this->_size;
}
/* Primitive Methods */
/**
* Moves the current read position to the specified byte offset.
*
* Throws an exception you attempt to move before the beginning or beyond
* the end of the data source.
*
* If a subclass needs to perform additional tasks (such as performing a
* fseek() on a filesystem source), it should do so after calling this
* parent method.
*
* @param integer $offset Destination byte offset.
* @throws Zend_Pdf_Exception
*/
public function moveToOffset($offset)
{
if ($this->_offset == $offset) {
return; // Not moving; do nothing.
}
if ($offset < 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Attempt to move before start of data source',
Zend_Pdf_Exception::MOVE_BEFORE_START_OF_FILE);
}
if ($offset >= $this->_size) { // Offsets are zero-based.
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Attempt to move beyond end of data source',
Zend_Pdf_Exception::MOVE_BEYOND_END_OF_FILE);
}
$this->_offset = $offset;
}
/**
* Shifts the current read position within the data source by the specified
* number of bytes.
*
* You may move forward (positive numbers) or backward (negative numbers).
* Throws an exception you attempt to move before the beginning or beyond
* the end of the data source.
*
* @param integer $byteCount Number of bytes to skip.
* @throws Zend_Pdf_Exception
*/
public function skipBytes($byteCount)
{
$this->moveToOffset($this->_offset + $byteCount);
}
}

View File

@ -0,0 +1,198 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: File.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_FileParserDataSource */
// require_once 'Zend/Pdf/FileParserDataSource.php';
/**
* Concrete subclass of {@link Zend_Pdf_FileParserDataSource} that provides an
* interface to filesystem objects.
*
* Note that this class cannot be used for other sources that may be supported
* by {@link fopen()} (through URL wrappers). It may be used for local
* filesystem objects only.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_FileParserDataSource_File extends Zend_Pdf_FileParserDataSource
{
/**** Instance Variables ****/
/**
* Fully-qualified path to the file.
* @var string
*/
protected $_filePath = '';
/**
* File resource handle .
* @var resource
*/
protected $_fileResource = null;
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Object constructor.
*
* Validates the path to the file, ensures that it is readable, then opens
* it for reading.
*
* Throws an exception if the file is missing or cannot be opened.
*
* @param string $filePath Fully-qualified path to the file.
* @throws Zend_Pdf_Exception
*/
public function __construct($filePath)
{
if (! (is_file($filePath) || is_link($filePath))) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Invalid file path: $filePath",
Zend_Pdf_Exception::BAD_FILE_PATH);
}
if (! is_readable($filePath)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("File is not readable: $filePath",
Zend_Pdf_Exception::NOT_READABLE);
}
if (($this->_size = @filesize($filePath)) === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Error while obtaining file size: $filePath",
Zend_Pdf_Exception::CANT_GET_FILE_SIZE);
}
if (($this->_fileResource = @fopen($filePath, 'rb')) === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Cannot open file for reading: $filePath",
Zend_Pdf_Exception::CANT_OPEN_FILE);
}
$this->_filePath = $filePath;
}
/**
* Object destructor.
*
* Closes the file if it had been successfully opened.
*/
public function __destruct()
{
if (is_resource($this->_fileResource)) {
@fclose($this->_fileResource);
}
}
/**
* Returns the specified number of raw bytes from the file at the byte
* offset of the current read position.
*
* Advances the read position by the number of bytes read.
*
* Throws an exception if an error was encountered while reading the file or
* if there is insufficient data to completely fulfill the request.
*
* @param integer $byteCount Number of bytes to read.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readBytes($byteCount)
{
$bytes = @fread($this->_fileResource, $byteCount);
if ($bytes === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unexpected error while reading file',
Zend_Pdf_Exception::ERROR_DURING_READ);
}
if (strlen($bytes) != $byteCount) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Insufficient data to read $byteCount bytes",
Zend_Pdf_Exception::INSUFFICIENT_DATA);
}
$this->_offset += $byteCount;
return $bytes;
}
/**
* Returns the entire contents of the file as a string.
*
* Preserves the current file seek position.
*
* @return string
*/
public function readAllBytes()
{
return file_get_contents($this->_filePath);
}
/* Object Magic Methods */
/**
* Returns the full filesystem path of the file.
*
* @return string
*/
public function __toString()
{
return $this->_filePath;
}
/* Primitive Methods */
/**
* Seeks the file read position to the specified byte offset.
*
* Throws an exception if the file pointer cannot be moved or if it is
* moved beyond EOF (end of file).
*
* @param integer $offset Destination byte offset.
* @throws Zend_Pdf_Exception
*/
public function moveToOffset($offset)
{
if ($this->_offset == $offset) {
return; // Not moving; do nothing.
}
parent::moveToOffset($offset);
$result = @fseek($this->_fileResource, $offset, SEEK_SET);
if ($result !== 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Error while setting new file position',
Zend_Pdf_Exception::CANT_SET_FILE_POSITION);
}
if (feof($this->_fileResource)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Moved beyond the end of the file',
Zend_Pdf_Exception::MOVE_BEYOND_END_OF_FILE);
}
}
}

View File

@ -0,0 +1,128 @@
<?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 FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: String.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_FileParserDataSource */
// require_once 'Zend/Pdf/FileParserDataSource.php';
/**
* Concrete subclass of {@link Zend_Pdf_FileParserDataSource} that provides an
* interface to binary strings.
*
* @package Zend_Pdf
* @subpackage FileParser
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_FileParserDataSource_String extends Zend_Pdf_FileParserDataSource
{
/**** Instance Variables ****/
/**
* The string to parse.
* @var string
*/
protected $_string = '';
/**** Public Interface ****/
/* Concrete Class Implementation */
/**
* Object constructor.
*
* Verifies that the string is not empty.
*
* @param string $string String to parse.
*/
public function __construct($string)
{
if (empty($string)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('String is empty',
Zend_Pdf_Exception::PARAMETER_VALUE_OUT_OF_RANGE);
}
$this->_size = strlen($string);
$this->_string = $string;
}
/**
* Object destructor.
*/
public function __destruct()
{
$this->_string = '';
}
/**
* Returns the specified number of raw bytes from the string at the byte
* offset of the current read position.
*
* Advances the read position by the number of bytes read.
*
* Throws an exception if there is insufficient data to completely fulfill
* the request.
*
* @param integer $byteCount Number of bytes to read.
* @return string
* @throws Zend_Pdf_Exception
*/
public function readBytes($byteCount)
{
if (($this->_offset + $byteCount) > $this->_size) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Insufficient data to read $byteCount bytes",
Zend_Pdf_Exception::INSUFFICIENT_DATA);
}
$bytes = substr($this->_string, $this->_offset, $byteCount);
$this->_offset += $byteCount;
return $bytes;
}
/**
* Returns the entire string.
*
* Preserves the current read position.
*
* @return string
*/
public function readAllBytes()
{
return $this->_string;
}
/* Object Magic Methods */
/**
* Returns a string containing the parsed string's length.
*
* @return string
*/
public function __toString()
{
return "String ($this->_size bytes)";
}
}

View File

@ -0,0 +1,181 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Ascii85.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Interface */
// require_once 'Zend/Pdf/Filter/Interface.php';
/**
* ASCII85 stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Filter_Ascii85 implements Zend_Pdf_Filter_Interface
{
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null)
{
$output = '';
$dataLength = strlen($data);
for ($i = 0; $i < $dataLength; $i += 4) {
//convert the 4 characters into a 32-bit number
$chunk = substr($data, $i, 4);
if (strlen($chunk) < 4) {
//partial chunk
break;
}
$b = unpack("N", $chunk);
$b = $b[1];
//special char for all 4 bytes = 0
if ($b == 0) {
$output .= 'z';
continue;
}
//encode into 5 bytes
for ($j = 4; $j >= 0; $j--) {
$foo = (int) (($b / pow(85,$j)) + 33);
$b %= pow(85,$j);
$output .= chr($foo);
}
}
//encode partial chunk
if ($i < $dataLength) {
$n = $dataLength - $i;
$chunk = substr($data, -$n);
//0 pad the rest
for ($j = $n;$j < 4;$j++) {
$chunk .= "\0";
}
$b = unpack("N", $chunk);
$b = $b[1];
//encode just $n + 1
for ($j = 4; $j >= (4 - $n); $j--) {
$foo = (int) (($b / pow(85,$j)) + 33);
$b %= pow(85,$j);
$output .= chr($foo);
}
}
//EOD
$output .= '~>';
//make sure lines are split
$output = chunk_split($output, 76, "\n");
//get rid of new line at the end
$output = substr($output, 0, -1);
return $output;
}
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null)
{
$output = '';
//get rid of the whitespaces
$whiteSpace = array("\x00", "\x09", "\x0A", "\x0C", "\x0D", "\x20");
$data = str_replace($whiteSpace, '', $data);
if (substr($data, -2) != '~>') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid EOF marker');
return '';
}
$data = substr($data, 0, (strlen($data) - 2));
$dataLength = strlen($data);
for ($i = 0; $i < $dataLength; $i += 5) {
$b = 0;
if (substr($data, $i, 1) == "z") {
$i -= 4;
$output .= pack("N", 0);
continue;
}
$c = substr($data, $i, 5);
if(strlen($c) < 5) {
//partial chunk
break;
}
$c = unpack('C5', $c);
$value = 0;
for ($j = 1; $j <= 5; $j++) {
$value += (($c[$j] - 33) * pow(85, (5 - $j)));
}
$output .= pack("N", $value);
}
//decode partial
if ($i < $dataLength) {
$value = 0;
$chunk = substr($data, $i);
$partialLength = strlen($chunk);
//pad the rest of the chunk with u's
//until the lenght of the chunk is 5
for ($j = 0; $j < (5 - $partialLength); $j++) {
$chunk .= 'u';
}
$c = unpack('C5', $chunk);
for ($j = 1; $j <= 5; $j++) {
$value += (($c[$j] - 33) * pow(85, (5 - $j)));
}
$foo = pack("N", $value);
$output .= substr($foo, 0, ($partialLength - 1));
}
return $output;
}
}

View File

@ -0,0 +1,135 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: AsciiHex.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Interface */
// require_once 'Zend/Pdf/Filter/Interface.php';
/**
* AsciiHex stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Filter_AsciiHex implements Zend_Pdf_Filter_Interface
{
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null)
{
return bin2hex($data) . '>';
}
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null)
{
$output = '';
$oddCode = true;
$commentMode = false;
for ($count = 0; $count < strlen($data) && $data[$count] != '>'; $count++) {
$charCode = ord($data[$count]);
if ($commentMode) {
if ($charCode == 0x0A || $charCode == 0x0D ) {
$commentMode = false;
}
continue;
}
switch ($charCode) {
//Skip white space
case 0x00: // null character
// fall through to next case
case 0x09: // Tab
// fall through to next case
case 0x0A: // Line feed
// fall through to next case
case 0x0C: // Form Feed
// fall through to next case
case 0x0D: // Carriage return
// fall through to next case
case 0x20: // Space
// Do nothing
break;
case 0x25: // '%'
// Switch to comment mode
$commentMode = true;
break;
default:
if ($charCode >= 0x30 /*'0'*/ && $charCode <= 0x39 /*'9'*/) {
$code = $charCode - 0x30;
} else if ($charCode >= 0x41 /*'A'*/ && $charCode <= 0x46 /*'F'*/) {
$code = $charCode - 0x37/*0x41 - 0x0A*/;
} else if ($charCode >= 0x61 /*'a'*/ && $charCode <= 0x66 /*'f'*/) {
$code = $charCode - 0x57/*0x61 - 0x0A*/;
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong character in a encoded stream');
}
if ($oddCode) {
// Odd pass. Store hex digit for next pass
// Scope of $hexCodeHigh variable is whole function
$hexCodeHigh = $code;
} else {
// Even pass.
// Add decoded character to the output
// ($hexCodeHigh is stored in previous pass)
$output .= chr($hexCodeHigh*16 + $code);
}
$oddCode = !$oddCode;
break;
}
}
/* Check that stream is terminated by End Of Data marker */
if ($data[$count] != '>') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong encoded stream End Of Data marker.');
}
/* Last '0' character is omitted */
if (!$oddCode) {
$output .= chr($hexCodeHigh*16);
}
return $output;
}
}

View File

@ -0,0 +1,391 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Compression.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Interface */
// require_once 'Zend/Pdf/Filter/Interface.php';
/**
* ASCII85 stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Filter_Compression implements Zend_Pdf_Filter_Interface
{
/**
* Paeth prediction function
*
* @param integer $a
* @param integer $b
* @param integer $c
* @return integer
*/
private static function _paeth($a, $b, $c)
{
// $a - left, $b - above, $c - upper left
$p = $a + $b - $c; // initial estimate
$pa = abs($p - $a); // distances to a, b, c
$pb = abs($p - $b);
$pc = abs($p - $c);
// return nearest of a,b,c,
// breaking ties in order a,b,c.
if ($pa <= $pb && $pa <= $pc) {
return $a;
} else if ($pb <= $pc) {
return $b;
} else {
return $c;
}
}
/**
* Get Predictor decode param value
*
* @param array $params
* @return integer
* @throws Zend_Pdf_Exception
*/
private static function _getPredictorValue(&$params)
{
if (isset($params['Predictor'])) {
$predictor = $params['Predictor'];
if ($predictor != 1 && $predictor != 2 &&
$predictor != 10 && $predictor != 11 && $predictor != 12 &&
$predictor != 13 && $predictor != 14 && $predictor != 15) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid value of \'Predictor\' decode param - ' . $predictor . '.' );
}
return $predictor;
} else {
return 1;
}
}
/**
* Get Colors decode param value
*
* @param array $params
* @return integer
* @throws Zend_Pdf_Exception
*/
private static function _getColorsValue(&$params)
{
if (isset($params['Colors'])) {
$colors = $params['Colors'];
if ($colors != 1 && $colors != 2 && $colors != 3 && $colors != 4) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid value of \'Color\' decode param - ' . $colors . '.' );
}
return $colors;
} else {
return 1;
}
}
/**
* Get BitsPerComponent decode param value
*
* @param array $params
* @return integer
* @throws Zend_Pdf_Exception
*/
private static function _getBitsPerComponentValue(&$params)
{
if (isset($params['BitsPerComponent'])) {
$bitsPerComponent = $params['BitsPerComponent'];
if ($bitsPerComponent != 1 && $bitsPerComponent != 2 &&
$bitsPerComponent != 4 && $bitsPerComponent != 8 &&
$bitsPerComponent != 16 ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid value of \'BitsPerComponent\' decode param - ' . $bitsPerComponent . '.' );
}
return $bitsPerComponent;
} else {
return 8;
}
}
/**
* Get Columns decode param value
*
* @param array $params
* @return integer
*/
private static function _getColumnsValue(&$params)
{
if (isset($params['Columns'])) {
return $params['Columns'];
} else {
return 1;
}
}
/**
* Convert stream data according to the filter params set before encoding.
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
protected static function _applyEncodeParams($data, $params) {
$predictor = self::_getPredictorValue($params);
$colors = self::_getColorsValue($params);
$bitsPerComponent = self::_getBitsPerComponentValue($params);
$columns = self::_getColumnsValue($params);
/** None of prediction */
if ($predictor == 1) {
return $data;
}
/** TIFF Predictor 2 */
if ($predictor == 2) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet' );
}
/** Optimal PNG prediction */
if ($predictor == 15) {
/** Use Paeth prediction as optimal */
$predictor = 14;
}
/** PNG prediction */
if ($predictor == 10 || /** None of prediction */
$predictor == 11 || /** Sub prediction */
$predictor == 12 || /** Up prediction */
$predictor == 13 || /** Average prediction */
$predictor == 14 /** Paeth prediction */
) {
$predictor -= 10;
if($bitsPerComponent == 16) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("PNG Prediction with bit depth greater than 8 not yet supported.");
}
$bitsPerSample = $bitsPerComponent*$colors;
$bytesPerSample = (int)(($bitsPerSample + 7)/8); // (int)ceil(...) emulation
$bytesPerRow = (int)(($bitsPerSample*$columns + 7)/8); // (int)ceil(...) emulation
$rows = strlen($data)/$bytesPerRow;
$output = '';
$offset = 0;
if (!is_integer($rows)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Wrong data length.');
}
switch ($predictor) {
case 0: // None of prediction
for ($count = 0; $count < $rows; $count++) {
$output .= chr($predictor);
$output .= substr($data, $offset, $bytesPerRow);
$offset += $bytesPerRow;
}
break;
case 1: // Sub prediction
for ($count = 0; $count < $rows; $count++) {
$output .= chr($predictor);
$lastSample = array_fill(0, $bytesPerSample, 0);
for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
$newByte = ord($data[$offset++]);
// Note. chr() automatically cuts input to 8 bit
$output .= chr($newByte - $lastSample[$count2 % $bytesPerSample]);
$lastSample[$count2 % $bytesPerSample] = $newByte;
}
}
break;
case 2: // Up prediction
$lastRow = array_fill(0, $bytesPerRow, 0);
for ($count = 0; $count < $rows; $count++) {
$output .= chr($predictor);
for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
$newByte = ord($data[$offset++]);
// Note. chr() automatically cuts input to 8 bit
$output .= chr($newByte - $lastRow[$count2]);
$lastRow[$count2] = $newByte;
}
}
break;
case 3: // Average prediction
$lastRow = array_fill(0, $bytesPerRow, 0);
for ($count = 0; $count < $rows; $count++) {
$output .= chr($predictor);
$lastSample = array_fill(0, $bytesPerSample, 0);
for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
$newByte = ord($data[$offset++]);
// Note. chr() automatically cuts input to 8 bit
$output .= chr($newByte - floor(( $lastSample[$count2 % $bytesPerSample] + $lastRow[$count2])/2));
$lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $newByte;
}
}
break;
case 4: // Paeth prediction
$lastRow = array_fill(0, $bytesPerRow, 0);
$currentRow = array();
for ($count = 0; $count < $rows; $count++) {
$output .= chr($predictor);
$lastSample = array_fill(0, $bytesPerSample, 0);
for ($count2 = 0; $count2 < $bytesPerRow; $count2++) {
$newByte = ord($data[$offset++]);
// Note. chr() automatically cuts input to 8 bit
$output .= chr($newByte - self::_paeth( $lastSample[$count2 % $bytesPerSample],
$lastRow[$count2],
($count2 - $bytesPerSample < 0)?
0 : $lastRow[$count2 - $bytesPerSample] ));
$lastSample[$count2 % $bytesPerSample] = $currentRow[$count2] = $newByte;
}
$lastRow = $currentRow;
}
break;
}
return $output;
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown prediction algorithm - ' . $predictor . '.' );
}
/**
* Convert stream data according to the filter params set after decoding.
*
* @param string $data
* @param array $params
* @return string
*/
protected static function _applyDecodeParams($data, $params) {
$predictor = self::_getPredictorValue($params);
$colors = self::_getColorsValue($params);
$bitsPerComponent = self::_getBitsPerComponentValue($params);
$columns = self::_getColumnsValue($params);
/** None of prediction */
if ($predictor == 1) {
return $data;
}
/** TIFF Predictor 2 */
if ($predictor == 2) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet' );
}
/**
* PNG prediction
* Prediction code is duplicated on each row.
* Thus all cases can be brought to one
*/
if ($predictor == 10 || /** None of prediction */
$predictor == 11 || /** Sub prediction */
$predictor == 12 || /** Up prediction */
$predictor == 13 || /** Average prediction */
$predictor == 14 || /** Paeth prediction */
$predictor == 15 /** Optimal prediction */) {
$bitsPerSample = $bitsPerComponent*$colors;
$bytesPerSample = ceil($bitsPerSample/8);
$bytesPerRow = ceil($bitsPerSample*$columns/8);
$rows = ceil(strlen($data)/($bytesPerRow + 1));
$output = '';
$offset = 0;
$lastRow = array_fill(0, $bytesPerRow, 0);
for ($count = 0; $count < $rows; $count++) {
$lastSample = array_fill(0, $bytesPerSample, 0);
switch (ord($data[$offset++])) {
case 0: // None of prediction
$output .= substr($data, $offset, $bytesPerRow);
for ($count2 = 0; $count2 < $bytesPerRow && $offset < strlen($data); $count2++) {
$lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = ord($data[$offset++]);
}
break;
case 1: // Sub prediction
for ($count2 = 0; $count2 < $bytesPerRow && $offset < strlen($data); $count2++) {
$decodedByte = (ord($data[$offset++]) + $lastSample[$count2 % $bytesPerSample]) & 0xFF;
$lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
$output .= chr($decodedByte);
}
break;
case 2: // Up prediction
for ($count2 = 0; $count2 < $bytesPerRow && $offset < strlen($data); $count2++) {
$decodedByte = (ord($data[$offset++]) + $lastRow[$count2]) & 0xFF;
$lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
$output .= chr($decodedByte);
}
break;
case 3: // Average prediction
for ($count2 = 0; $count2 < $bytesPerRow && $offset < strlen($data); $count2++) {
$decodedByte = (ord($data[$offset++]) +
floor(( $lastSample[$count2 % $bytesPerSample] + $lastRow[$count2])/2)
) & 0xFF;
$lastSample[$count2 % $bytesPerSample] = $lastRow[$count2] = $decodedByte;
$output .= chr($decodedByte);
}
break;
case 4: // Paeth prediction
$currentRow = array();
for ($count2 = 0; $count2 < $bytesPerRow && $offset < strlen($data); $count2++) {
$decodedByte = (ord($data[$offset++]) +
self::_paeth($lastSample[$count2 % $bytesPerSample],
$lastRow[$count2],
($count2 - $bytesPerSample < 0)?
0 : $lastRow[$count2 - $bytesPerSample])
) & 0xFF;
$lastSample[$count2 % $bytesPerSample] = $currentRow[$count2] = $decodedByte;
$output .= chr($decodedByte);
}
$lastRow = $currentRow;
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown prediction tag.');
}
}
return $output;
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Unknown prediction algorithm - ' . $predictor . '.' );
}
}

View File

@ -0,0 +1,102 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Flate.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Compression */
// require_once 'Zend/Pdf/Filter/Compression.php';
/**
* Flate stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Filter_Compression_Flate extends Zend_Pdf_Filter_Compression
{
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null)
{
if ($params != null) {
$data = self::_applyEncodeParams($data, $params);
}
if (extension_loaded('zlib')) {
$trackErrors = ini_get( "track_errors");
ini_set('track_errors', '1');
if (($output = @gzcompress($data)) === false) {
ini_set('track_errors', $trackErrors);
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception($php_errormsg);
}
ini_set('track_errors', $trackErrors);
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet. You have to use zlib extension.');
}
return $output;
}
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null)
{
global $php_errormsg;
if (extension_loaded('zlib')) {
$trackErrors = ini_get( "track_errors");
ini_set('track_errors', '1');
if (($output = @gzuncompress($data)) === false) {
ini_set('track_errors', $trackErrors);
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception($php_errormsg);
}
ini_set('track_errors', $trackErrors);
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet');
}
if ($params !== null) {
return self::_applyDecodeParams($output, $params);
} else {
return $output;
}
}
}

View File

@ -0,0 +1,95 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Lzw.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Compression */
// require_once 'Zend/Pdf/Filter/Compression.php';
/**
* LZW stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Filter_Compression_Lzw extends Zend_Pdf_Filter_Compression
{
/**
* Get EarlyChange decode param value
*
* @param array $params
* @return integer
* @throws Zend_Pdf_Exception
*/
private static function _getEarlyChangeValue($params)
{
if (isset($params['EarlyChange'])) {
$earlyChange = $params['EarlyChange'];
if ($earlyChange != 0 && $earlyChange != 1) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Invalid value of \'EarlyChange\' decode param - ' . $earlyChange . '.' );
}
return $earlyChange;
} else {
return 1;
}
}
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null)
{
if ($params != null) {
$data = self::_applyEncodeParams($data, $params);
}
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet');
}
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null)
{
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Not implemented yet');
if ($params !== null) {
return self::_applyDecodeParams($data, $params);
} else {
return $data;
}
}
}

View File

@ -0,0 +1,50 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* PDF stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Pdf_Filter_Interface
{
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null);
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null);
}

View File

@ -0,0 +1,125 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: RunLength.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Zend_Pdf_Filter_Interface */
// require_once 'Zend/Pdf/Filter/Interface.php';
/**
* RunLength stream filter
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Filter_RunLength implements Zend_Pdf_Filter_Interface
{
/**
* Encode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function encode($data, $params = null)
{
$output = '';
$chainStartOffset = 0;
$offset = 0;
while ($offset < strlen($data)) {
// Do not encode 2 char chains since they produce 2 char run sequence,
// but it takes more time to decode such output (because of processing additional run)
if (($repeatedCharChainLength = strspn($data, $data[$offset], $offset + 1, 127) + 1) > 2) {
if ($chainStartOffset != $offset) {
// Drop down previouse (non-repeatable chars) run
$output .= chr($offset - $chainStartOffset - 1)
. substr($data, $chainStartOffset, $offset - $chainStartOffset);
}
$output .= chr(257 - $repeatedCharChainLength) . $data[$offset];
$offset += $repeatedCharChainLength;
$chainStartOffset = $offset;
} else {
$offset++;
if ($offset - $chainStartOffset == 128) {
// Maximum run length is reached
// Drop down non-repeatable chars run
$output .= "\x7F" . substr($data, $chainStartOffset, 128);
$chainStartOffset = $offset;
}
}
}
if ($chainStartOffset != $offset) {
// Drop down non-repeatable chars run
$output .= chr($offset - $chainStartOffset - 1) . substr($data, $chainStartOffset, $offset - $chainStartOffset);
}
$output .= "\x80";
return $output;
}
/**
* Decode data
*
* @param string $data
* @param array $params
* @return string
* @throws Zend_Pdf_Exception
*/
public static function decode($data, $params = null)
{
$dataLength = strlen($data);
$output = '';
$offset = 0;
while($offset < $dataLength) {
$length = ord($data[$offset]);
$offset++;
if ($length == 128) {
// EOD byte
break;
} else if ($length < 128) {
$length++;
$output .= substr($data, $offset, $length);
$offset += $length;
} else if ($length > 128) {
$output .= str_repeat($data[$offset], 257 - $length);
$offset++;
}
}
return $output;
}
}

732
library/Zend/Pdf/Font.php Normal file
View File

@ -0,0 +1,732 @@
<?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 Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Font.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Abstract factory class which vends {@link Zend_Pdf_Resource_Font} objects.
*
* Font objects themselves are normally instantiated through the factory methods
* {@link fontWithName()} or {@link fontWithPath()}.
*
* This class is also the home for font-related constants because the name of
* the true base class ({@link Zend_Pdf_Resource_Font}) is not intuitive for the
* end user.
*
* @package Zend_Pdf
* @subpackage Fonts
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Font
{
/**** Class Constants ****/
/* Font Types */
/**
* Unknown font type.
*/
const TYPE_UNKNOWN = 0;
/**
* One of the standard 14 PDF fonts.
*/
const TYPE_STANDARD = 1;
/**
* A PostScript Type 1 font.
*/
const TYPE_TYPE_1 = 2;
/**
* A TrueType font or an OpenType font containing TrueType outlines.
*/
const TYPE_TRUETYPE = 3;
/**
* Type 0 composite font.
*/
const TYPE_TYPE_0 = 4;
/**
* CID font containing a PostScript Type 1 font.
* These fonts are used only to construct Type 0 composite fonts and can't be used directly
*/
const TYPE_CIDFONT_TYPE_0 = 5;
/**
* CID font containing a TrueType font or an OpenType font containing TrueType outlines.
* These fonts are used only to construct Type 0 composite fonts and can't be used directly
*/
const TYPE_CIDFONT_TYPE_2 = 6;
/* Names of the Standard 14 PDF Fonts */
/**
* Name of the standard PDF font Courier.
*/
const FONT_COURIER = 'Courier';
/**
* Name of the bold style of the standard PDF font Courier.
*/
const FONT_COURIER_BOLD = 'Courier-Bold';
/**
* Name of the italic style of the standard PDF font Courier.
*/
const FONT_COURIER_OBLIQUE = 'Courier-Oblique';
/**
* Convenience constant for a common misspelling of
* {@link FONT_COURIER_OBLIQUE}.
*/
const FONT_COURIER_ITALIC = 'Courier-Oblique';
/**
* Name of the bold and italic style of the standard PDF font Courier.
*/
const FONT_COURIER_BOLD_OBLIQUE = 'Courier-BoldOblique';
/**
* Convenience constant for a common misspelling of
* {@link FONT_COURIER_BOLD_OBLIQUE}.
*/
const FONT_COURIER_BOLD_ITALIC = 'Courier-BoldOblique';
/**
* Name of the standard PDF font Helvetica.
*/
const FONT_HELVETICA = 'Helvetica';
/**
* Name of the bold style of the standard PDF font Helvetica.
*/
const FONT_HELVETICA_BOLD = 'Helvetica-Bold';
/**
* Name of the italic style of the standard PDF font Helvetica.
*/
const FONT_HELVETICA_OBLIQUE = 'Helvetica-Oblique';
/**
* Convenience constant for a common misspelling of
* {@link FONT_HELVETICA_OBLIQUE}.
*/
const FONT_HELVETICA_ITALIC = 'Helvetica-Oblique';
/**
* Name of the bold and italic style of the standard PDF font Helvetica.
*/
const FONT_HELVETICA_BOLD_OBLIQUE = 'Helvetica-BoldOblique';
/**
* Convenience constant for a common misspelling of
* {@link FONT_HELVETICA_BOLD_OBLIQUE}.
*/
const FONT_HELVETICA_BOLD_ITALIC = 'Helvetica-BoldOblique';
/**
* Name of the standard PDF font Symbol.
*/
const FONT_SYMBOL = 'Symbol';
/**
* Name of the standard PDF font Times.
*/
const FONT_TIMES_ROMAN = 'Times-Roman';
/**
* Convenience constant for a common misspelling of
* {@link FONT_TIMES_ROMAN}.
*/
const FONT_TIMES = 'Times-Roman';
/**
* Name of the bold style of the standard PDF font Times.
*/
const FONT_TIMES_BOLD = 'Times-Bold';
/**
* Name of the italic style of the standard PDF font Times.
*/
const FONT_TIMES_ITALIC = 'Times-Italic';
/**
* Name of the bold and italic style of the standard PDF font Times.
*/
const FONT_TIMES_BOLD_ITALIC = 'Times-BoldItalic';
/**
* Name of the standard PDF font Zapf Dingbats.
*/
const FONT_ZAPFDINGBATS = 'ZapfDingbats';
/* Font Name String Types */
/**
* Full copyright notice for the font.
*/
const NAME_COPYRIGHT = 0;
/**
* Font family name. Used to group similar styles of fonts together.
*/
const NAME_FAMILY = 1;
/**
* Font style within the font family. Examples: Regular, Italic, Bold, etc.
*/
const NAME_STYLE = 2;
/**
* Unique font identifier.
*/
const NAME_ID = 3;
/**
* Full font name. Usually a combination of the {@link NAME_FAMILY} and
* {@link NAME_STYLE} strings.
*/
const NAME_FULL = 4;
/**
* Version number of the font.
*/
const NAME_VERSION = 5;
/**
* PostScript name for the font. This is the name used to identify fonts
* internally and within the PDF file.
*/
const NAME_POSTSCRIPT = 6;
/**
* Font trademark notice. This is distinct from the {@link NAME_COPYRIGHT}.
*/
const NAME_TRADEMARK = 7;
/**
* Name of the font manufacturer.
*/
const NAME_MANUFACTURER = 8;
/**
* Name of the designer of the font.
*/
const NAME_DESIGNER = 9;
/**
* Description of the font. May contain revision information, usage
* recommendations, features, etc.
*/
const NAME_DESCRIPTION = 10;
/**
* URL of the font vendor. Some fonts may contain a unique serial number
* embedded in this URL, which is used for licensing.
*/
const NAME_VENDOR_URL = 11;
/**
* URL of the font designer ({@link NAME_DESIGNER}).
*/
const NAME_DESIGNER_URL = 12;
/**
* Plain language licensing terms for the font.
*/
const NAME_LICENSE = 13;
/**
* URL of more detailed licensing information for the font.
*/
const NAME_LICENSE_URL = 14;
/**
* Preferred font family. Used by some fonts to work around a Microsoft
* Windows limitation where only four fonts styles can share the same
* {@link NAME_FAMILY} value.
*/
const NAME_PREFERRED_FAMILY = 16;
/**
* Preferred font style. A more descriptive string than {@link NAME_STYLE}.
*/
const NAME_PREFERRED_STYLE = 17;
/**
* Suggested text to use as a representative sample of the font.
*/
const NAME_SAMPLE_TEXT = 19;
/**
* PostScript CID findfont name.
*/
const NAME_CID_NAME = 20;
/* Font Weights */
/**
* Thin font weight.
*/
const WEIGHT_THIN = 100;
/**
* Extra-light (Ultra-light) font weight.
*/
const WEIGHT_EXTRA_LIGHT = 200;
/**
* Light font weight.
*/
const WEIGHT_LIGHT = 300;
/**
* Normal (Regular) font weight.
*/
const WEIGHT_NORMAL = 400;
/**
* Medium font weight.
*/
const WEIGHT_MEDIUM = 500;
/**
* Semi-bold (Demi-bold) font weight.
*/
const WEIGHT_SEMI_BOLD = 600;
/**
* Bold font weight.
*/
const WEIGHT_BOLD = 700;
/**
* Extra-bold (Ultra-bold) font weight.
*/
const WEIGHT_EXTRA_BOLD = 800;
/**
* Black (Heavy) font weight.
*/
const WEIGHT_BLACK = 900;
/* Font Widths */
/**
* Ultra-condensed font width. Typically 50% of normal.
*/
const WIDTH_ULTRA_CONDENSED = 1;
/**
* Extra-condensed font width. Typically 62.5% of normal.
*/
const WIDTH_EXTRA_CONDENSED = 2;
/**
* Condensed font width. Typically 75% of normal.
*/
const WIDTH_CONDENSED = 3;
/**
* Semi-condensed font width. Typically 87.5% of normal.
*/
const WIDTH_SEMI_CONDENSED = 4;
/**
* Normal (Medium) font width.
*/
const WIDTH_NORMAL = 5;
/**
* Semi-expanded font width. Typically 112.5% of normal.
*/
const WIDTH_SEMI_EXPANDED = 6;
/**
* Expanded font width. Typically 125% of normal.
*/
const WIDTH_EXPANDED = 7;
/**
* Extra-expanded font width. Typically 150% of normal.
*/
const WIDTH_EXTRA_EXPANDED = 8;
/**
* Ultra-expanded font width. Typically 200% of normal.
*/
const WIDTH_ULTRA_EXPANDED = 9;
/* Font Embedding Options */
/**
* Do not embed the font in the PDF document.
*/
const EMBED_DONT_EMBED = 0x01;
/**
* Embed, but do not subset the font in the PDF document.
*/
const EMBED_DONT_SUBSET = 0x02;
/**
* Embed, but do not compress the font in the PDF document.
*/
const EMBED_DONT_COMPRESS = 0x04;
/**
* Suppress the exception normally thrown if the font cannot be embedded
* due to its copyright bits being set.
*/
const EMBED_SUPPRESS_EMBED_EXCEPTION = 0x08;
/**** Class Variables ****/
/**
* Array whose keys are the unique PostScript names of instantiated fonts.
* The values are the font objects themselves.
* @var array
*/
private static $_fontNames = array();
/**
* Array whose keys are the md5 hash of the full paths on disk for parsed
* fonts. The values are the font objects themselves.
* @var array
*/
private static $_fontFilePaths = array();
/**** Public Interface ****/
/* Factory Methods */
/**
* Returns a {@link Zend_Pdf_Resource_Font} object by full name.
*
* This is the preferred method to obtain one of the standard 14 PDF fonts.
*
* The result of this method is cached, preventing unnecessary duplication
* of font objects. Repetitive calls for a font with the same name will
* return the same object.
*
* The $embeddingOptions parameter allows you to set certain flags related
* to font embedding. You may combine options by OR-ing them together. See
* the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of
* available options and their descriptions. Note that this value is only
* used when creating a font for the first time. If a font with the same
* name already exists, you will get that object and the options you specify
* here will be ignored. This is because fonts are only embedded within the
* PDF file once.
*
* If the font name supplied does not match the name of a previously
* instantiated object and it is not one of the 14 standard PDF fonts, an
* exception will be thrown.
*
* @param string $name Full PostScript name of font.
* @param integer $embeddingOptions (optional) Options for font embedding.
* @return Zend_Pdf_Resource_Font
* @throws Zend_Pdf_Exception
*/
public static function fontWithName($name, $embeddingOptions = 0)
{
/* First check the cache. Don't duplicate font objects.
*/
if (isset(Zend_Pdf_Font::$_fontNames[$name])) {
return Zend_Pdf_Font::$_fontNames[$name];
}
/**
* @todo It would be cool to be able to have a mapping of font names to
* file paths in a configuration file for frequently used custom
* fonts. This would allow a user to use custom fonts without having
* to hard-code file paths all over the place. Table this idea until
* {@link Zend_Config} is ready.
*/
/* Not an existing font and no mapping in the config file. Check to see
* if this is one of the standard 14 PDF fonts.
*/
switch ($name) {
case Zend_Pdf_Font::FONT_COURIER:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Courier.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_Courier();
break;
case Zend_Pdf_Font::FONT_COURIER_BOLD:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierBold.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierBold();
break;
case Zend_Pdf_Font::FONT_COURIER_OBLIQUE:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierOblique.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierOblique();
break;
case Zend_Pdf_Font::FONT_COURIER_BOLD_OBLIQUE:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierBoldOblique.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierBoldOblique();
break;
case Zend_Pdf_Font::FONT_HELVETICA:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Helvetica.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_Helvetica();
break;
case Zend_Pdf_Font::FONT_HELVETICA_BOLD:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBold.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBold();
break;
case Zend_Pdf_Font::FONT_HELVETICA_OBLIQUE:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaOblique.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaOblique();
break;
case Zend_Pdf_Font::FONT_HELVETICA_BOLD_OBLIQUE:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBoldOblique.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBoldOblique();
break;
case Zend_Pdf_Font::FONT_SYMBOL:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Symbol.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_Symbol();
break;
case Zend_Pdf_Font::FONT_TIMES_ROMAN:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesRoman.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesRoman();
break;
case Zend_Pdf_Font::FONT_TIMES_BOLD:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesBold.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesBold();
break;
case Zend_Pdf_Font::FONT_TIMES_ITALIC:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesItalic.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesItalic();
break;
case Zend_Pdf_Font::FONT_TIMES_BOLD_ITALIC:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesBoldItalic.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesBoldItalic();
break;
case Zend_Pdf_Font::FONT_ZAPFDINGBATS:
// require_once 'Zend/Pdf/Resource/Font/Simple/Standard/ZapfDingbats.php';
$font = new Zend_Pdf_Resource_Font_Simple_Standard_ZapfDingbats();
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Unknown font name: $name",
Zend_Pdf_Exception::BAD_FONT_NAME);
}
/* Add this new font to the cache array and return it for use.
*/
Zend_Pdf_Font::$_fontNames[$name] = $font;
return $font;
}
/**
* Returns a {@link Zend_Pdf_Resource_Font} object by file path.
*
* The result of this method is cached, preventing unnecessary duplication
* of font objects. Repetitive calls for the font with the same path will
* return the same object.
*
* The $embeddingOptions parameter allows you to set certain flags related
* to font embedding. You may combine options by OR-ing them together. See
* the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of
* available options and their descriptions. Note that this value is only
* used when creating a font for the first time. If a font with the same
* name already exists, you will get that object and the options you specify
* here will be ignored. This is because fonts are only embedded within the
* PDF file once.
*
* If the file path supplied does not match the path of a previously
* instantiated object or the font type cannot be determined, an exception
* will be thrown.
*
* @param string $filePath Full path to the font file.
* @param integer $embeddingOptions (optional) Options for font embedding.
* @return Zend_Pdf_Resource_Font
* @throws Zend_Pdf_Exception
*/
public static function fontWithPath($filePath, $embeddingOptions = 0)
{
/* First check the cache. Don't duplicate font objects.
*/
$filePathKey = md5($filePath);
if (isset(Zend_Pdf_Font::$_fontFilePaths[$filePathKey])) {
return Zend_Pdf_Font::$_fontFilePaths[$filePathKey];
}
/* Create a file parser data source object for this file. File path and
* access permission checks are handled here.
*/
// require_once 'Zend/Pdf/FileParserDataSource/File.php';
$dataSource = new Zend_Pdf_FileParserDataSource_File($filePath);
/* Attempt to determine the type of font. We can't always trust file
* extensions, but try that first since it's fastest.
*/
$fileExtension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
/* If it turns out that the file is named improperly and we guess the
* wrong type, we'll get null instead of a font object.
*/
switch ($fileExtension) {
case 'ttf':
$font = Zend_Pdf_Font::_extractTrueTypeFont($dataSource, $embeddingOptions);
break;
default:
/* Unrecognized extension. Try to determine the type by actually
* parsing it below.
*/
$font = null;
break;
}
if ($font === null) {
/* There was no match for the file extension or the extension was
* wrong. Attempt to detect the type of font by actually parsing it.
* We'll do the checks in order of most likely format to try to
* reduce the detection time.
*/
// OpenType
// TrueType
if (($font === null) && ($fileExtension != 'ttf')) {
$font = Zend_Pdf_Font::_extractTrueTypeFont($dataSource, $embeddingOptions);
}
// Type 1 PostScript
// Mac OS X dfont
// others?
}
/* Done with the data source object.
*/
$dataSource = null;
if ($font !== null) {
/* Parsing was successful. Add this font instance to the cache arrays
* and return it for use.
*/
$fontName = $font->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT, '', '');
Zend_Pdf_Font::$_fontNames[$fontName] = $font;
$filePathKey = md5($filePath);
Zend_Pdf_Font::$_fontFilePaths[$filePathKey] = $font;
return $font;
} else {
/* The type of font could not be determined. Give up.
*/
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Cannot determine font type: $filePath",
Zend_Pdf_Exception::CANT_DETERMINE_FONT_TYPE);
}
}
/**** Internal Methods ****/
/* Font Extraction Methods */
/**
* Attempts to extract a TrueType font from the data source.
*
* If the font parser throws an exception that suggests the data source
* simply doesn't contain a TrueType font, catches it and returns null. If
* an exception is thrown that suggests the TrueType font is corrupt or
* otherwise unusable, throws that exception. If successful, returns the
* font object.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @param integer $embeddingOptions Options for font embedding.
* @return Zend_Pdf_Resource_Font_OpenType_TrueType May also return null if
* the data source does not appear to contain a TrueType font.
* @throws Zend_Pdf_Exception
*/
protected static function _extractTrueTypeFont($dataSource, $embeddingOptions)
{
try {
// require_once 'Zend/Pdf/FileParser/Font/OpenType/TrueType.php';
$fontParser = new Zend_Pdf_FileParser_Font_OpenType_TrueType($dataSource);
$fontParser->parse();
if ($fontParser->isAdobeLatinSubset) {
// require_once 'Zend/Pdf/Resource/Font/Simple/Parsed/TrueType.php';
$font = new Zend_Pdf_Resource_Font_Simple_Parsed_TrueType($fontParser, $embeddingOptions);
} else {
// require_once 'Zend/Pdf/Resource/Font/CidFont/TrueType.php';
// require_once 'Zend/Pdf/Resource/Font/Type0.php';
/* Use Composite Type 0 font which supports Unicode character mapping */
$cidFont = new Zend_Pdf_Resource_Font_CidFont_TrueType($fontParser, $embeddingOptions);
$font = new Zend_Pdf_Resource_Font_Type0($cidFont);
}
} catch (Zend_Pdf_Exception $e) {
/* The following exception codes suggest that this isn't really a
* TrueType font. If we caught such an exception, simply return
* null. For all other cases, it probably is a TrueType font but has
* a problem; throw the exception again.
*/
$fontParser = null;
// require_once 'Zend/Pdf/Exception.php';
switch ($e->getCode()) {
case Zend_Pdf_Exception::WRONG_FONT_TYPE: // break intentionally omitted
case Zend_Pdf_Exception::BAD_TABLE_COUNT: // break intentionally omitted
case Zend_Pdf_Exception::BAD_MAGIC_NUMBER:
return null;
default:
throw new Zend_Pdf_Exception($e->getMessage(), $e->getCode(), $e);
}
}
return $font;
}
}

247
library/Zend/Pdf/Image.php Normal file
View File

@ -0,0 +1,247 @@
<?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 Images
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Image.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Abstract factory class which vends {@link Zend_Pdf_Resource_Image} objects.
*
* This class is also the home for image-related constants because the name of
* the true base class ({@link Zend_Pdf_Resource_Image}) is not intuitive for the
* end user.
*
* @package Zend_Pdf
* @subpackage Images
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Image
{
/**** Class Constants ****/
/* Image Types */
const TYPE_UNKNOWN = 0;
const TYPE_JPEG = 1;
const TYPE_PNG = 2;
const TYPE_TIFF = 3;
/* TIFF Constants */
const TIFF_FIELD_TYPE_BYTE=1;
const TIFF_FIELD_TYPE_ASCII=2;
const TIFF_FIELD_TYPE_SHORT=3;
const TIFF_FIELD_TYPE_LONG=4;
const TIFF_FIELD_TYPE_RATIONAL=5;
const TIFF_TAG_IMAGE_WIDTH=256;
const TIFF_TAG_IMAGE_LENGTH=257; //Height
const TIFF_TAG_BITS_PER_SAMPLE=258;
const TIFF_TAG_COMPRESSION=259;
const TIFF_TAG_PHOTOMETRIC_INTERPRETATION=262;
const TIFF_TAG_STRIP_OFFSETS=273;
const TIFF_TAG_SAMPLES_PER_PIXEL=277;
const TIFF_TAG_STRIP_BYTE_COUNTS=279;
const TIFF_COMPRESSION_UNCOMPRESSED = 1;
const TIFF_COMPRESSION_CCITT1D = 2;
const TIFF_COMPRESSION_GROUP_3_FAX = 3;
const TIFF_COMPRESSION_GROUP_4_FAX = 4;
const TIFF_COMPRESSION_LZW = 5;
const TIFF_COMPRESSION_JPEG = 6;
const TIFF_COMPRESSION_FLATE = 8;
const TIFF_COMPRESSION_FLATE_OBSOLETE_CODE = 32946;
const TIFF_COMPRESSION_PACKBITS = 32773;
const TIFF_PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO=0;
const TIFF_PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO=1;
const TIFF_PHOTOMETRIC_INTERPRETATION_RGB=2;
const TIFF_PHOTOMETRIC_INTERPRETATION_RGB_INDEXED=3;
const TIFF_PHOTOMETRIC_INTERPRETATION_CMYK=5;
const TIFF_PHOTOMETRIC_INTERPRETATION_YCBCR=6;
const TIFF_PHOTOMETRIC_INTERPRETATION_CIELAB=8;
/* PNG Constants */
const PNG_COMPRESSION_DEFAULT_STRATEGY = 0;
const PNG_COMPRESSION_FILTERED = 1;
const PNG_COMPRESSION_HUFFMAN_ONLY = 2;
const PNG_COMPRESSION_RLE = 3;
const PNG_FILTER_NONE = 0;
const PNG_FILTER_SUB = 1;
const PNG_FILTER_UP = 2;
const PNG_FILTER_AVERAGE = 3;
const PNG_FILTER_PAETH = 4;
const PNG_INTERLACING_DISABLED = 0;
const PNG_INTERLACING_ENABLED = 1;
const PNG_CHANNEL_GRAY = 0;
const PNG_CHANNEL_RGB = 2;
const PNG_CHANNEL_INDEXED = 3;
const PNG_CHANNEL_GRAY_ALPHA = 4;
const PNG_CHANNEL_RGB_ALPHA = 6;
/**** Public Interface ****/
/* Factory Methods */
/**
* Returns a {@link Zend_Pdf_Resource_Image} object by file path.
*
* @param string $filePath Full path to the image file.
* @return Zend_Pdf_Resource_Image
* @throws Zend_Pdf_Exception
*/
public static function imageWithPath($filePath)
{
/**
* use old implementation
* @todo switch to new implementation
*/
// require_once 'Zend/Pdf/Resource/ImageFactory.php';
return Zend_Pdf_Resource_ImageFactory::factory($filePath);
/* Create a file parser data source object for this file. File path and
* access permission checks are handled here.
*/
// require_once 'Zend/Pdf/FileParserDataSource/File.php';
$dataSource = new Zend_Pdf_FileParserDataSource_File($filePath);
/* Attempt to determine the type of image. We can't always trust file
* extensions, but try that first since it's fastest.
*/
$fileExtension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
/* If it turns out that the file is named improperly and we guess the
* wrong type, we'll get null instead of an image object.
*/
switch ($fileExtension) {
case 'tif':
//Fall through to next case;
case 'tiff':
$image = Zend_Pdf_Image::_extractTiffImage($dataSource);
break;
case 'png':
$image = Zend_Pdf_Image::_extractPngImage($dataSource);
break;
case 'jpg':
//Fall through to next case;
case 'jpe':
//Fall through to next case;
case 'jpeg':
$image = Zend_Pdf_Image::_extractJpegImage($dataSource);
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Cannot create image resource. File extension not known or unsupported type.");
break;
}
/* Done with the data source object.
*/
$dataSource = null;
if ($image !== null) {
return $image;
} else {
/* The type of image could not be determined. Give up.
*/
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Cannot determine image type: $filePath",
Zend_Pdf_Exception::CANT_DETERMINE_IMAGE_TYPE);
}
}
/**** Internal Methods ****/
/* Image Extraction Methods */
/**
* Attempts to extract a JPEG Image from the data source.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @return Zend_Pdf_Resource_Image_Jpeg May also return null if
* the data source does not appear to contain valid image data.
* @throws Zend_Pdf_Exception
*/
protected static function _extractJpegImage($dataSource)
{
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Jpeg image fileparser is not implemented. Old styly implementation has to be used.');
// require_once 'Zend/Pdf/FileParser/Image/Jpeg.php';
$imageParser = new Zend_Pdf_FileParser_Image_Jpeg($dataSource);
// require_once 'Zend/Pdf/Resource/Image/Jpeg.php';
$image = new Zend_Pdf_Resource_Image_Jpeg($imageParser);
unset($imageParser);
return $image;
}
/**
* Attempts to extract a PNG Image from the data source.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @return Zend_Pdf_Resource_Image_Png May also return null if
* the data source does not appear to contain valid image data.
*/
protected static function _extractPngImage($dataSource)
{
// require_once 'Zend/Pdf/FileParser/Image/Png.php';
$imageParser = new Zend_Pdf_FileParser_Image_Png($dataSource);
// require_once 'Zend/Pdf/Resource/Image/Png.php';
$image = new Zend_Pdf_Resource_Image_Png($imageParser);
unset($imageParser);
return $image;
}
/**
* Attempts to extract a TIFF Image from the data source.
*
* @param Zend_Pdf_FileParserDataSource $dataSource
* @return Zend_Pdf_Resource_Image_Tiff May also return null if
* the data source does not appear to contain valid image data.
* @throws Zend_Pdf_Exception
*/
protected static function _extractTiffImage($dataSource)
{
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Tiff image fileparser is not implemented. Old styly implementation has to be used.');
// require_once 'Zend/Pdf/FileParser/Image/Tiff.php';
$imageParser = new Zend_Pdf_FileParser_Image_Tiff($dataSource);
// require_once 'Zend/Pdf/Resource/Image/Tiff.php';
$image = new Zend_Pdf_Resource_Image_Tiff($imageParser);
unset($imageParser);
return $image;
}
}

View File

@ -0,0 +1,154 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: NameTree.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
/**
* PDF name tree representation class
*
* @todo implement lazy resource loading so resources will be really loaded at access time
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_NameTree implements ArrayAccess, Iterator, Countable
{
/**
* Elements
* Array of name => object tree entries
*
* @var array
*/
protected $_items = array();
/**
* Object constructor
*
* @param Zend_Pdf_Element $rootDictionary root of name dictionary
*/
public function __construct(Zend_Pdf_Element $rootDictionary)
{
if ($rootDictionary->getType() != Zend_Pdf_Element::TYPE_DICTIONARY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Name tree root must be a dictionary.');
}
$intermediateNodes = array();
$leafNodes = array();
if ($rootDictionary->Kids !== null) {
$intermediateNodes[] = $rootDictionary;
} else {
$leafNodes[] = $rootDictionary;
}
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->Names->items)/2;
for ($count = 0; $count < $destinationsCount; $count++) {
$this->_items[$leafNode->Names->items[$count*2]->value] = $leafNode->Names->items[$count*2 + 1];
}
}
}
public function current()
{
return current($this->_items);
}
public function next()
{
return next($this->_items);
}
public function key()
{
return key($this->_items);
}
public function valid() {
return current($this->_items)!==false;
}
public function rewind()
{
reset($this->_items);
}
public function offsetExists($offset)
{
return array_key_exists($offset, $this->_items);
}
public function offsetGet($offset)
{
return $this->_items[$offset];
}
public function offsetSet($offset, $value)
{
if ($offset === null) {
$this->_items[] = $value;
} else {
$this->_items[$offset] = $value;
}
}
public function offsetUnset($offset)
{
unset($this->_items[$offset]);
}
public function clear()
{
$this->_items = array();
}
public function count()
{
return count($this->_items);
}
}

View File

@ -0,0 +1,373 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Outline.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Abstract PDF outline representation class
*
* @todo Implement an ability to associate an outline item with a structure element (PDF 1.3 feature)
*
* @package Zend_Pdf
* @subpackage Outlines
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Pdf_Outline implements RecursiveIterator, Countable
{
/**
* True if outline is open.
*
* @var boolean
*/
protected $_open = false;
/**
* Array of child outlines (array of Zend_Pdf_Outline objects)
*
* @var array
*/
public $childOutlines = array();
/**
* Get outline title.
*
* @return string
*/
abstract public function getTitle();
/**
* Set outline title
*
* @param string $title
* @return Zend_Pdf_Outline
*/
abstract public function setTitle($title);
/**
* Returns true if outline item is open by default
*
* @return boolean
*/
public function isOpen()
{
return $this->_open;
}
/**
* Sets 'isOpen' outline flag
*
* @param boolean $isOpen
* @return Zend_Pdf_Outline
*/
public function setIsOpen($isOpen)
{
$this->_open = $isOpen;
return $this;
}
/**
* Returns true if outline item is displayed in italic
*
* @return boolean
*/
abstract public function isItalic();
/**
* Sets 'isItalic' outline flag
*
* @param boolean $isItalic
* @return Zend_Pdf_Outline
*/
abstract public function setIsItalic($isItalic);
/**
* Returns true if outline item is displayed in bold
*
* @return boolean
*/
abstract public function isBold();
/**
* Sets 'isBold' outline flag
*
* @param boolean $isBold
* @return Zend_Pdf_Outline
*/
abstract public function setIsBold($isBold);
/**
* Get outline text color.
*
* @return Zend_Pdf_Color_Rgb
*/
abstract public function getColor();
/**
* Set outline text color.
* (null means default color which is black)
*
* @param Zend_Pdf_Color_Rgb $color
* @return Zend_Pdf_Outline
*/
abstract public function setColor(Zend_Pdf_Color_Rgb $color);
/**
* Get outline target.
*
* @return Zend_Pdf_Target
*/
abstract public function getTarget();
/**
* Set outline target.
* Null means no target
*
* @param Zend_Pdf_Target|string $target
* @return Zend_Pdf_Outline
*/
abstract public function setTarget($target = null);
/**
* Get outline options
*
* @return array
*/
public function getOptions()
{
return array('title' => $this->_title,
'open' => $this->_open,
'color' => $this->_color,
'italic' => $this->_italic,
'bold' => $this->_bold,
'target' => $this->_target);
}
/**
* Set outline options
*
* @param array $options
* @return Zend_Pdf_Action
* @throws Zend_Pdf_Exception
*/
public function setOptions(array $options)
{
foreach ($options as $key => $value) {
switch ($key) {
case 'title':
$this->setTitle($value);
break;
case 'open':
$this->setIsOpen($value);
break;
case 'color':
$this->setColor($value);
break;
case 'italic':
$this->setIsItalic($value);
break;
case 'bold':
$this->setIsBold($value);
break;
case 'target':
$this->setTarget($value);
break;
default:
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception("Unknown option name - '$key'.");
break;
}
}
return $this;
}
/**
* Create new Outline object
*
* It provides two forms of input parameters:
*
* 1. Zend_Pdf_Outline::create(string $title[, Zend_Pdf_Target $target])
* 2. Zend_Pdf_Outline::create(array $options)
*
* Second form allows to provide outline options as an array.
* The followed options are supported:
* 'title' - string, outline title, required
* 'open' - boolean, true if outline entry is open (default value is false)
* 'color' - Zend_Pdf_Color_Rgb object, true if outline entry is open (default value is null - black)
* 'italic' - boolean, true if outline entry is displayed in italic (default value is false)
* 'bold' - boolean, true if outline entry is displayed in bold (default value is false)
* 'target' - Zend_Pdf_Target object or string, outline item destination
*
* @return Zend_Pdf_Outline
* @throws Zend_Pdf_Exception
*/
public static function create($param1, $param2 = null)
{
// require_once 'Zend/Pdf/Outline/Created.php';
if (is_string($param1)) {
if ($param2 !== null && !($param2 instanceof Zend_Pdf_Target || is_string($param2))) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Outline create method takes $title (string) and $target (Zend_Pdf_Target or string) or an array as an input');
}
return new Zend_Pdf_Outline_Created(array('title' => $param1,
'target' => $param2));
} else {
if (!is_array($param1) || $param2 !== null) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Outline create method takes $title (string) and $destination (Zend_Pdf_Destination) or an array as an input');
}
return new Zend_Pdf_Outline_Created($param1);
}
}
/**
* Returns number of the total number of open items at all levels of the outline.
*
* @internal
* @return integer
*/
public function openOutlinesCount()
{
$count = 1; // Include this outline
if ($this->isOpen()) {
foreach ($this->childOutlines as $child) {
$count += $child->openOutlinesCount();
}
}
return $count;
}
/**
* Dump Outline and its child outlines into PDF structures
*
* Returns dictionary indirect object or reference
*
* @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
*/
abstract public function dumpOutline(Zend_Pdf_ElementFactory_Interface $factory,
$updateNavigation,
Zend_Pdf_Element $parent,
Zend_Pdf_Element $prev = null,
SplObjectStorage $processedOutlines = null);
////////////////////////////////////////////////////////////////////////
// RecursiveIterator interface methods
//////////////
/**
* Returns the child outline.
*
* @return Zend_Pdf_Outline
*/
public function current()
{
return current($this->childOutlines);
}
/**
* Returns current iterator key
*
* @return integer
*/
public function key()
{
return key($this->childOutlines);
}
/**
* Go to next child
*/
public function next()
{
return next($this->childOutlines);
}
/**
* Rewind children
*/
public function rewind()
{
return reset($this->childOutlines);
}
/**
* Check if current position is valid
*
* @return boolean
*/
public function valid()
{
return current($this->childOutlines) !== false;
}
/**
* Returns the child outline.
*
* @return Zend_Pdf_Outline|null
*/
public function getChildren()
{
return current($this->childOutlines);
}
/**
* Implements RecursiveIterator interface.
*
* @return bool whether container has any pages
*/
public function hasChildren()
{
return count($this->childOutlines) > 0;
}
////////////////////////////////////////////////////////////////////////
// Countable interface methods
//////////////
/**
* count()
*
* @return int
*/
public function count()
{
return count($this->childOutlines);
}
}

View File

@ -0,0 +1,315 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Created.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Dictionary.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
// require_once 'Zend/Pdf/Element/String.php';
/** Zend_Pdf_Outline */
// require_once 'Zend/Pdf/Outline.php';
/**
* PDF outline representation class
*
* @todo Implement an ability to associate an outline item with a structure element (PDF 1.3 feature)
*
* @package Zend_Pdf
* @subpackage Outlines
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Outline_Created extends Zend_Pdf_Outline
{
/**
* Outline title.
*
* @var string
*/
protected $_title;
/**
* Color to be used for the outline entrys text.
* It uses the DeviceRGB color space for color representation.
* Null means default value - black ([0.0 0.0 0.0] in RGB representation).
*
* @var Zend_Pdf_Color_Rgb
*/
protected $_color = null;
/**
* True if outline item is displayed in italic.
* Default value is false.
*
* @var boolean
*/
protected $_italic = false;
/**
* True if outline item is displayed in bold.
* Default value is false.
*
* @var boolean
*/
protected $_bold = false;
/**
* Target destination or action.
* String means named destination
*
* Null means no target.
*
* @var Zend_Pdf_Destination|Zend_Pdf_Action
*/
protected $_target = null;
/**
* Get outline title.
*
* @return string
*/
public function getTitle()
{
return $this->_title;
}
/**
* Set outline title
*
* @param string $title
* @return Zend_Pdf_Outline
*/
public function setTitle($title)
{
$this->_title = $title;
return $this;
}
/**
* Returns true if outline item is displayed in italic
*
* @return boolean
*/
public function isItalic()
{
return $this->_italic;
}
/**
* Sets 'isItalic' outline flag
*
* @param boolean $isItalic
* @return Zend_Pdf_Outline
*/
public function setIsItalic($isItalic)
{
$this->_italic = $isItalic;
return $this;
}
/**
* Returns true if outline item is displayed in bold
*
* @return boolean
*/
public function isBold()
{
return $this->_bold;
}
/**
* Sets 'isBold' outline flag
*
* @param boolean $isBold
* @return Zend_Pdf_Outline
*/
public function setIsBold($isBold)
{
$this->_bold = $isBold;
return $this;
}
/**
* Get outline text color.
*
* @return Zend_Pdf_Color_Rgb
*/
public function getColor()
{
return $this->_color;
}
/**
* 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->_color = $color;
return $this;
}
/**
* Get outline target.
*
* @return Zend_Pdf_Target
*/
public function getTarget()
{
return $this->_target;
}
/**
* 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)
{
if (is_string($target)) {
// require_once 'Zend/Pdf/Destination/Named.php';
$target = new Zend_Pdf_Destination_Named($target);
}
if ($target === null || $target instanceof Zend_Pdf_Target) {
$this->_target = $target;
} 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;
}
/**
* Object constructor
*
* @param array $options
* @throws Zend_Pdf_Exception
*/
public function __construct($options = array())
{
if (!isset($options['title'])) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Title parameter is required.');
}
$this->setOptions($options);
}
/**
* 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);
$outlineDictionary = $factory->newObject(new Zend_Pdf_Element_Dictionary());
$outlineDictionary->Title = new Zend_Pdf_Element_String($this->getTitle());
$target = $this->getTarget();
if ($target === null) {
// Do nothing
} else if ($target instanceof Zend_Pdf_Destination) {
$outlineDictionary->Dest = $target->getResource();
} else if ($target instanceof Zend_Pdf_Action) {
$outlineDictionary->A = $target->getResource();
} else {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Outline target has to be Zend_Pdf_Destination, Zend_Pdf_Action object or null');
}
$color = $this->getColor();
if ($color !== null) {
$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]));
$outlineDictionary->C = new Zend_Pdf_Element_Array($colorComponentElements);
}
if ($this->isItalic() || $this->isBold()) {
$outlineDictionary->F = new Zend_Pdf_Element_Numeric(($this->isItalic()? 1 : 0) | // Bit 1 - Italic
($this->isBold()? 2 : 0)); // Bit 2 - Bold
}
$outlineDictionary->Parent = $parent;
$outlineDictionary->Prev = $prev;
$lastChild = 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) {
$lastChild = $childOutline->dumpOutline($factory, true, $outlineDictionary, null, $processedOutlines);
$outlineDictionary->First = $lastChild;
} else {
$childOutlineDictionary = $childOutline->dumpOutline($factory, true, $outlineDictionary, $lastChild, $processedOutlines);
$lastChild->Next = $childOutlineDictionary;
$lastChild = $childOutlineDictionary;
}
}
$outlineDictionary->Last = $lastChild;
if (count($this->childOutlines) != 0) {
$outlineDictionary->Count = new Zend_Pdf_Element_Numeric(($this->isOpen()? 1 : -1)*count($this->childOutlines));
}
return $outlineDictionary;
}
}

View File

@ -0,0 +1,460 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Loaded.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Array.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
// require_once 'Zend/Pdf/Element/String.php';
/** Zend_Pdf_Outline */
// require_once 'Zend/Pdf/Outline.php';
/**
* Traceable PDF outline representation class
*
* Instances of this class trace object update uperations. That allows to avoid outlines PDF tree update
* which should be performed at each document update otherwise.
*
* @package Zend_Pdf
* @subpackage Outlines
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Outline_Loaded extends Zend_Pdf_Outline
{
/**
* Outline dictionary object
*
* @var Zend_Pdf_Element_Dictionary|Zend_Pdf_Element_Object|Zend_Pdf_Element_Reference
*/
protected $_outlineDictionary;
/**
* original array of child outlines
*
* @var array
*/
protected $_originalChildOutlines = array();
/**
* Get outline title.
*
* @return string
* @throws Zend_Pdf_Exception
*/
public function getTitle()
{
if ($this->_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);
}
}
}
}

773
library/Zend/Pdf/Page.php Normal file
View File

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

472
library/Zend/Pdf/Parser.php Normal file
View File

@ -0,0 +1,472 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Parser.php 24593 2012-01-05 20:35:02Z matthew $
*/
/** Internally used classes */
// require_once 'Zend/Pdf/Element.php';
// require_once 'Zend/Pdf/Element/Numeric.php';
/** Zend_Pdf_StringParser */
// require_once 'Zend/Pdf/StringParser.php';
/**
* PDF file parser
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_Parser
{
/**
* String parser
*
* @var Zend_Pdf_StringParser
*/
private $_stringParser;
/**
* Last PDF file trailer
*
* @var Zend_Pdf_Trailer_Keeper
*/
private $_trailer;
/**
* PDF version specified in the file header
*
* @var string
*/
private $_pdfVersion;
/**
* Get length of source PDF
*
* @return integer
*/
public function getPDFLength()
{
return strlen($this->_stringParser->data);
}
/**
* Get PDF String
*
* @return string
*/
public function getPDFString()
{
return $this->_stringParser->data;
}
/**
* PDF version specified in the file header
*
* @return string
*/
public function getPDFVersion()
{
return $this->_pdfVersion;
}
/**
* Load XReference table and referenced objects
*
* @param integer $offset
* @throws Zend_Pdf_Exception
* @return Zend_Pdf_Trailer_Keeper
*/
private function _loadXRefTable($offset)
{
$this->_stringParser->offset = $offset;
// require_once 'Zend/Pdf/Element/Reference/Table.php';
$refTable = new Zend_Pdf_Element_Reference_Table();
// require_once 'Zend/Pdf/Element/Reference/Context.php';
$context = new Zend_Pdf_Element_Reference_Context($this->_stringParser, $refTable);
$this->_stringParser->setContext($context);
$nextLexeme = $this->_stringParser->readLexeme();
if ($nextLexeme == 'xref') {
/**
* Common cross-reference table
*/
$this->_stringParser->skipWhiteSpace();
while ( ($nextLexeme = $this->_stringParser->readLexeme()) != 'trailer' ) {
if (!ctype_digit($nextLexeme)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross-reference table subheader values must contain only digits.', $this->_stringParser->offset-strlen($nextLexeme)));
}
$objNum = (int)$nextLexeme;
$refCount = $this->_stringParser->readLexeme();
if (!ctype_digit($refCount)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross-reference table subheader values must contain only digits.', $this->_stringParser->offset-strlen($refCount)));
}
$this->_stringParser->skipWhiteSpace();
while ($refCount > 0) {
$objectOffset = substr($this->_stringParser->data, $this->_stringParser->offset, 10);
if (!ctype_digit($objectOffset)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Offset must contain only digits.', $this->_stringParser->offset));
}
// Force $objectOffset to be treated as decimal instead of octal number
for ($numStart = 0; $numStart < strlen($objectOffset)-1; $numStart++) {
if ($objectOffset[$numStart] != '0') {
break;
}
}
$objectOffset = substr($objectOffset, $numStart);
$this->_stringParser->offset += 10;
if (strpos("\x00\t\n\f\r ", $this->_stringParser->data[$this->_stringParser->offset]) === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Value separator must be white space.', $this->_stringParser->offset));
}
$this->_stringParser->offset++;
$genNumber = substr($this->_stringParser->data, $this->_stringParser->offset, 5);
if (!ctype_digit($objectOffset)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Offset must contain only digits.', $this->_stringParser->offset));
}
// Force $objectOffset to be treated as decimal instead of octal number
for ($numStart = 0; $numStart < strlen($genNumber)-1; $numStart++) {
if ($genNumber[$numStart] != '0') {
break;
}
}
$genNumber = substr($genNumber, $numStart);
$this->_stringParser->offset += 5;
if (strpos("\x00\t\n\f\r ", $this->_stringParser->data[$this->_stringParser->offset]) === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Value separator must be white space.', $this->_stringParser->offset));
}
$this->_stringParser->offset++;
$inUseKey = $this->_stringParser->data[$this->_stringParser->offset];
$this->_stringParser->offset++;
switch ($inUseKey) {
case 'f':
// free entry
unset( $this->_refTable[$objNum . ' ' . $genNumber . ' R'] );
$refTable->addReference($objNum . ' ' . $genNumber . ' R',
$objectOffset,
false);
break;
case 'n':
// in-use entry
$refTable->addReference($objNum . ' ' . $genNumber . ' R',
$objectOffset,
true);
}
if ( !Zend_Pdf_StringParser::isWhiteSpace(ord( $this->_stringParser->data[$this->_stringParser->offset] )) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Value separator must be white space.', $this->_stringParser->offset));
}
$this->_stringParser->offset++;
if ( !Zend_Pdf_StringParser::isWhiteSpace(ord( $this->_stringParser->data[$this->_stringParser->offset] )) ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file cross-reference table syntax error. Offset - 0x%X. Value separator must be white space.', $this->_stringParser->offset));
}
$this->_stringParser->offset++;
$refCount--;
$objNum++;
}
}
$trailerDictOffset = $this->_stringParser->offset;
$trailerDict = $this->_stringParser->readElement();
if (!$trailerDict instanceof Zend_Pdf_Element_Dictionary) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Dictionary expected after \'trailer\' keyword.', $trailerDictOffset));
}
} else {
$xrefStream = $this->_stringParser->getObject($offset, $context);
if (!$xrefStream instanceof Zend_Pdf_Element_Object_Stream) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross-reference stream expected.', $offset));
}
$trailerDict = $xrefStream->dictionary;
if ($trailerDict->Type->value != 'XRef') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross-reference stream object must have /Type property assigned to /XRef.', $offset));
}
if ($trailerDict->W === null || $trailerDict->W->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross reference stream dictionary doesn\'t have W entry or it\'s not an array.', $offset));
}
$entryField1Size = $trailerDict->W->items[0]->value;
$entryField2Size = $trailerDict->W->items[1]->value;
$entryField3Size = $trailerDict->W->items[2]->value;
if ($entryField2Size == 0 || $entryField3Size == 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Wrong W dictionary entry. Only type field of stream entries has default value and could be zero length.', $offset));
}
$xrefStreamData = $xrefStream->value;
if ($trailerDict->Index !== null) {
if ($trailerDict->Index->getType() != Zend_Pdf_Element::TYPE_ARRAY) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('PDF file syntax error. Offset - 0x%X. Cross reference stream dictionary Index entry must be an array.', $offset));
}
$sections = count($trailerDict->Index->items)/2;
} else {
$sections = 1;
}
$streamOffset = 0;
$size = $entryField1Size + $entryField2Size + $entryField3Size;
$entries = strlen($xrefStreamData)/$size;
for ($count = 0; $count < $sections; $count++) {
if ($trailerDict->Index !== null) {
$objNum = $trailerDict->Index->items[$count*2 ]->value;
$entries = $trailerDict->Index->items[$count*2 + 1]->value;
} else {
$objNum = 0;
$entries = $trailerDict->Size->value;
}
for ($count2 = 0; $count2 < $entries; $count2++) {
if ($entryField1Size == 0) {
$type = 1;
} else if ($entryField1Size == 1) { // Optimyze one-byte field case
$type = ord($xrefStreamData[$streamOffset++]);
} else {
$type = Zend_Pdf_StringParser::parseIntFromStream($xrefStreamData, $streamOffset, $entryField1Size);
$streamOffset += $entryField1Size;
}
if ($entryField2Size == 1) { // Optimyze one-byte field case
$field2 = ord($xrefStreamData[$streamOffset++]);
} else {
$field2 = Zend_Pdf_StringParser::parseIntFromStream($xrefStreamData, $streamOffset, $entryField2Size);
$streamOffset += $entryField2Size;
}
if ($entryField3Size == 1) { // Optimyze one-byte field case
$field3 = ord($xrefStreamData[$streamOffset++]);
} else {
$field3 = Zend_Pdf_StringParser::parseIntFromStream($xrefStreamData, $streamOffset, $entryField3Size);
$streamOffset += $entryField3Size;
}
switch ($type) {
case 0:
// Free object
$refTable->addReference($objNum . ' ' . $field3 . ' R', $field2, false);
// Debug output:
// echo "Free object - $objNum $field3 R, next free - $field2\n";
break;
case 1:
// In use object
$refTable->addReference($objNum . ' ' . $field3 . ' R', $field2, true);
// Debug output:
// echo "In-use object - $objNum $field3 R, offset - $field2\n";
break;
case 2:
// Object in an object stream
// Debug output:
// echo "Compressed object - $objNum 0 R, object stream - $field2 0 R, offset - $field3\n";
break;
}
$objNum++;
}
}
// $streamOffset . ' ' . strlen($xrefStreamData) . "\n";
// "$entries\n";
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Cross-reference streams are not supported yet.');
}
// require_once 'Zend/Pdf/Trailer/Keeper.php';
$trailerObj = new Zend_Pdf_Trailer_Keeper($trailerDict, $context);
if ($trailerDict->Prev instanceof Zend_Pdf_Element_Numeric ||
$trailerDict->Prev instanceof Zend_Pdf_Element_Reference ) {
$trailerObj->setPrev($this->_loadXRefTable($trailerDict->Prev->value));
$context->getRefTable()->setParent($trailerObj->getPrev()->getRefTable());
}
/**
* We set '/Prev' dictionary property to the current cross-reference section offset.
* It doesn't correspond to the actual data, but is true when trailer will be used
* as a trailer for next generated PDF section.
*/
$trailerObj->Prev = new Zend_Pdf_Element_Numeric($offset);
return $trailerObj;
}
/**
* Get Trailer object
*
* @return Zend_Pdf_Trailer_Keeper
*/
public function getTrailer()
{
return $this->_trailer;
}
/**
* Object constructor
*
* Note: PHP duplicates string, which is sent by value, only of it's updated.
* Thus we don't need to care about overhead
*
* @param mixed $source
* @param Zend_Pdf_ElementFactory_Interface $factory
* @param boolean $load
* @throws Zend_Exception
*/
public function __construct($source, Zend_Pdf_ElementFactory_Interface $factory, $load)
{
if ($load) {
if (($pdfFile = @fopen($source, 'rb')) === false ) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Can not open '$source' file for reading." );
}
$data = '';
$byteCount = filesize($source);
while ($byteCount > 0 && !feof($pdfFile)) {
$nextBlock = fread($pdfFile, $byteCount);
if ($nextBlock === false) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Error occured while '$source' file reading." );
}
$data .= $nextBlock;
$byteCount -= strlen($nextBlock);
}
if ($byteCount != 0) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception( "Error occured while '$source' file reading." );
}
fclose($pdfFile);
$this->_stringParser = new Zend_Pdf_StringParser($data, $factory);
} else {
$this->_stringParser = new Zend_Pdf_StringParser($source, $factory);
}
$pdfVersionComment = $this->_stringParser->readComment();
if (substr($pdfVersionComment, 0, 5) != '%PDF-') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('File is not a PDF.');
}
$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)
* Stream compression filter must be implemented (for compressed object streams).
* Cross reference streams must be implemented
*/
// require_once 'Zend/Pdf/Exception.php';
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 ||
strlen($this->_stringParser->data) - $this->_stringParser->offset > 7) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception('Pdf file syntax error. End-of-fle marker expected at the end of file.');
}
$this->_stringParser->offset--;
/**
* Go to end of cross-reference table offset
*/
while (Zend_Pdf_StringParser::isWhiteSpace( ord($this->_stringParser->data[$this->_stringParser->offset]) )&&
($this->_stringParser->offset > 0)) {
$this->_stringParser->offset--;
}
/**
* Go to the start of cross-reference table offset
*/
while ( (!Zend_Pdf_StringParser::isWhiteSpace( ord($this->_stringParser->data[$this->_stringParser->offset]) ))&&
($this->_stringParser->offset > 0)) {
$this->_stringParser->offset--;
}
/**
* Go to the end of 'startxref' keyword
*/
while (Zend_Pdf_StringParser::isWhiteSpace( ord($this->_stringParser->data[$this->_stringParser->offset]) )&&
($this->_stringParser->offset > 0)) {
$this->_stringParser->offset--;
}
/**
* Go to the white space (eol marker) before 'startxref' keyword
*/
$this->_stringParser->offset -= 9;
$nextLexeme = $this->_stringParser->readLexeme();
if ($nextLexeme != 'startxref') {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('Pdf file syntax error. \'startxref\' keyword expected. Offset - 0x%X.', $this->_stringParser->offset-strlen($nextLexeme)));
}
$startXref = $this->_stringParser->readLexeme();
if (!ctype_digit($startXref)) {
// require_once 'Zend/Pdf/Exception.php';
throw new Zend_Pdf_Exception(sprintf('Pdf file syntax error. Cross-reference table offset must contain only digits. Offset - 0x%X.', $this->_stringParser->offset-strlen($nextLexeme)));
}
$this->_trailer = $this->_loadXRefTable($startXref);
$factory->setObjectCount($this->_trailer->Size->value);
}
/**
* Object destructor
*/
public function __destruct()
{
$this->_stringParser->cleanUp();
}
}

View File

@ -0,0 +1,45 @@
<?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-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: RecursivelyIteratableObjectsContainer.php 24593 2012-01-05 20:35:02Z matthew $
*/
/**
* Iteratable objects container
*
* @package Zend_Pdf
* @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Pdf_RecursivelyIteratableObjectsContainer implements RecursiveIterator, Countable
{
protected $_objects = array();
public function __construct(array $objects) { $this->_objects = $objects; }
public function current() { return current($this->_objects); }
public function key() { return key($this->_objects); }
public function next() { return next($this->_objects); }
public function rewind() { return reset($this->_objects); }
public function valid() { return current($this->_objects) !== false; }
public function getChildren() { return current($this->_objects); }
public function hasChildren() { return count($this->_objects) > 0; }
public function count() { return count($this->_objects); }
}

Some files were not shown because too many files have changed in this diff Show More