PageRenderTime 1003ms CodeModel.GetById 101ms app.highlight 69ms RepoModel.GetById 118ms app.codeStats 0ms

/library/Zend/Pdf/Cmap.php

https://bitbucket.org/baruffaldi/website-2008-computer-shopping-3
PHP | 337 lines | 85 code | 50 blank | 202 comment | 7 complexity | 638072946a02d5ac0fb7afa750c217e9 MD5 | raw file
  1<?php
  2/**
  3 * Zend Framework
  4 *
  5 * LICENSE
  6 *
  7 * This source file is subject to the new BSD license that is bundled
  8 * with this package in the file LICENSE.txt.
  9 * It is also available through the world-wide-web at this URL:
 10 * http://framework.zend.com/license/new-bsd
 11 * If you did not receive a copy of the license and are unable to
 12 * obtain it through the world-wide-web, please send an email
 13 * to license@zend.com so we can send you a copy immediately.
 14 *
 15 * @package    Zend_Pdf
 16 * @subpackage Fonts
 17 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 18 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 19 */
 20
 21/** Zend_Pdf_Exception */
 22require_once 'Zend/Pdf/Exception.php';
 23
 24/** Zend_Pdf_Cmap_ByteEncoding */
 25require_once 'Zend/Pdf/Cmap/ByteEncoding.php';
 26
 27/** Zend_Pdf_Cmap_ByteEncoding_Static */
 28require_once 'Zend/Pdf/Cmap/ByteEncoding/Static.php';
 29
 30/** Zend_Pdf_Cmap_SegmentToDelta */
 31require_once 'Zend/Pdf/Cmap/SegmentToDelta.php';
 32
 33/** Zend_Pdf_Cmap_TrimmedTable */
 34require_once 'Zend/Pdf/Cmap/TrimmedTable.php';
 35
 36
 37/**
 38 * Abstract helper class for {@link Zend_Pdf_Resource_Font} which manages font
 39 * character maps.
 40 *
 41 * Defines the public interface for concrete subclasses which are responsible
 42 * for mapping Unicode characters to the font's glyph numbers. Also provides
 43 * shared utility methods.
 44 *
 45 * Cmap objects should ordinarily be obtained through the factory method
 46 * {@link cmapWithTypeData()}.
 47 *
 48 * The supported character map types are those found in the OpenType spec. For
 49 * additional detail on the internal binary format of these tables, see:
 50 * <ul>
 51 *  <li>{@link http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6cmap.html}
 52 *  <li>{@link http://www.microsoft.com/OpenType/OTSpec/cmap.htm}
 53 *  <li>{@link http://partners.adobe.com/public/developer/opentype/index_cmap.html}
 54 * </ul>
 55 *
 56 * @todo Write code for Zend_Pdf_FontCmap_HighByteMapping class.
 57 * @todo Write code for Zend_Pdf_FontCmap_MixedCoverage class.
 58 * @todo Write code for Zend_Pdf_FontCmap_TrimmedArray class.
 59 * @todo Write code for Zend_Pdf_FontCmap_SegmentedCoverage class.
 60 *
 61 * @package    Zend_Pdf
 62 * @subpackage Fonts
 63 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 64 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 65 */
 66abstract class Zend_Pdf_Cmap
 67{
 68  /**** Class Constants ****/
 69
 70
 71  /* Cmap Table Types */
 72
 73    /**
 74     * Byte Encoding character map table type.
 75     */
 76    const TYPE_BYTE_ENCODING = 0x00;
 77
 78    /**
 79     * High Byte Mapping character map table type.
 80     */
 81    const TYPE_HIGH_BYTE_MAPPING = 0x02;
 82
 83    /**
 84     * Segment Value to Delta Mapping character map table type.
 85     */
 86    const TYPE_SEGMENT_TO_DELTA = 0x04;
 87
 88    /**
 89     * Trimmed Table character map table type.
 90     */
 91    const TYPE_TRIMMED_TABLE = 0x06;
 92
 93    /**
 94     * Mixed Coverage character map table type.
 95     */
 96    const TYPE_MIXED_COVERAGE = 0x08;
 97
 98    /**
 99     * Trimmed Array character map table type.
100     */
101    const TYPE_TRIMMED_ARRAY = 0x0a;
102
103    /**
104     * Segmented Coverage character map table type.
105     */
106    const TYPE_SEGMENTED_COVERAGE = 0x0c;
107
108    /**
109     * Static Byte Encoding character map table type. Variant of
110     * {@link TYPE_BYTEENCODING}.
111     */
112    const TYPE_BYTE_ENCODING_STATIC = 0xf1;
113
114    /**
115     * Unknown character map table type.
116     */
117    const TYPE_UNKNOWN = 0xff;
118
119
120  /* Special Glyph Names */
121
122    /**
123     * Glyph representing missing characters.
124     */
125    const MISSING_CHARACTER_GLYPH = 0x00;
126
127
128
129  /**** Public Interface ****/
130
131
132  /* Factory Methods */
133
134    /**
135     * Instantiates the appropriate concrete subclass based on the type of cmap
136     * table and returns the instance.
137     *
138     * The cmap type must be one of the following values:
139     * <ul>
140     *  <li>{@link Zend_Pdf_Cmap::TYPE_BYTE_ENCODING}
141     *  <li>{@link Zend_Pdf_Cmap::TYPE_BYTE_ENCODING_STATIC}
142     *  <li>{@link Zend_Pdf_Cmap::TYPE_HIGH_BYTE_MAPPING}
143     *  <li>{@link Zend_Pdf_Cmap::TYPE_SEGMENT_TO_DELTA}
144     *  <li>{@link Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE}
145     *  <li>{@link Zend_Pdf_Cmap::TYPE_MIXED_COVERAGE}
146     *  <li>{@link Zend_Pdf_Cmap::TYPE_TRIMMED_ARRAY}
147     *  <li>{@link Zend_Pdf_Cmap::TYPE_SEGMENTED_COVERAGE}
148     * </ul>
149     *
150     * Throws an exception if the table type is invalid or the cmap table data
151     * cannot be validated.
152     *
153     * @param integer $cmapType Type of cmap.
154     * @param mixed $cmapData Cmap table data. Usually a string or array.
155     * @return Zend_Pdf_Cmap
156     * @throws Zend_Pdf_Exception
157     */
158    public static function cmapWithTypeData($cmapType, $cmapData)
159    {
160        switch ($cmapType) {
161            case Zend_Pdf_Cmap::TYPE_BYTE_ENCODING:
162                return new Zend_Pdf_Cmap_ByteEncoding($cmapData);
163
164            case Zend_Pdf_Cmap::TYPE_BYTE_ENCODING_STATIC:
165                return new Zend_Pdf_Cmap_ByteEncoding_Static($cmapData);
166
167            case Zend_Pdf_Cmap::TYPE_HIGH_BYTE_MAPPING:
168                throw new Zend_Pdf_Exception('High byte mapping cmap currently unsupported',
169                                             Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
170
171            case Zend_Pdf_Cmap::TYPE_SEGMENT_TO_DELTA:
172                return new Zend_Pdf_Cmap_SegmentToDelta($cmapData);
173
174            case Zend_Pdf_Cmap::TYPE_TRIMMED_TABLE:
175                return new Zend_Pdf_Cmap_TrimmedTable($cmapData);
176
177            case Zend_Pdf_Cmap::TYPE_MIXED_COVERAGE:
178                throw new Zend_Pdf_Exception('Mixed coverage cmap currently unsupported',
179                                             Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
180
181            case Zend_Pdf_Cmap::TYPE_TRIMMED_ARRAY:
182                throw new Zend_Pdf_Exception('Trimmed array cmap currently unsupported',
183                                             Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
184
185            case Zend_Pdf_Cmap::TYPE_SEGMENTED_COVERAGE:
186                throw new Zend_Pdf_Exception('Segmented coverage cmap currently unsupported',
187                                             Zend_Pdf_Exception::CMAP_TYPE_UNSUPPORTED);
188
189            default:
190                throw new Zend_Pdf_Exception("Unknown cmap type: $cmapType",
191                                             Zend_Pdf_Exception::CMAP_UNKNOWN_TYPE);
192        }
193    }
194
195
196  /* Abstract Methods */
197
198    /**
199     * Object constructor
200     *
201     * Parses the raw binary table data. Throws an exception if the table is
202     * malformed.
203     *
204     * @param string $cmapData Raw binary cmap table data.
205     * @throws Zend_Pdf_Exception
206     */
207    abstract public function __construct($cmapData);
208
209    /**
210     * Returns an array of glyph numbers corresponding to the Unicode characters.
211     *
212     * If a particular character doesn't exist in this font, the special 'missing
213     * character glyph' will be substituted.
214     *
215     * See also {@link glyphNumberForCharacter()}.
216     *
217     * @param array $characterCodes Array of Unicode character codes (code points).
218     * @return array Array of glyph numbers.
219     */
220    abstract public function glyphNumbersForCharacters($characterCodes);
221
222    /**
223     * Returns the glyph number corresponding to the Unicode character.
224     *
225     * If a particular character doesn't exist in this font, the special 'missing
226     * character glyph' will be substituted.
227     *
228     * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
229     * operations.
230     *
231     * @param integer $characterCode Unicode character code (code point).
232     * @return integer Glyph number.
233     */
234    abstract public function glyphNumberForCharacter($characterCode);
235
236    /**
237     * Returns an array containing the Unicode characters that have entries in
238     * this character map.
239     *
240     * @return array Unicode character codes.
241     */
242    abstract public function getCoveredCharacters();
243
244    /**
245     * Returns an array containing the glyphs numbers that have entries in this character map.
246     * Keys are Unicode character codes (integers)
247     * 
248     * This functionality is partially covered by glyphNumbersForCharacters(getCoveredCharacters())
249     * call, but this method do it in more effective way (prepare complete list instead of searching 
250     * glyph for each character code).
251     *
252     * @internal
253     * @return array Array representing <Unicode character code> => <glyph number> pairs.
254     */
255    abstract public function getCoveredCharactersGlyphs();
256
257
258  /**** Internal Methods ****/
259
260
261  /* Internal Utility Methods */
262
263    /**
264     * Extracts a signed 2-byte integer from a string.
265     *
266     * Integers are always big-endian. Throws an exception if the index is out
267     * of range.
268     *
269     * @param string &$data
270     * @param integer $index Position in string of integer.
271     * @return integer
272     * @throws Zend_Pdf_Exception
273     */
274    protected function _extractInt2(&$data, $index)
275    {
276        if (($index < 0) | (($index + 1) > strlen($data))) {
277            throw new Zend_Pdf_Exception("Index out of range: $index",
278                                         Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
279        }
280        $number = ord($data[$index]);
281        if (($number & 0x80) == 0x80) {    // negative
282            $number = ~((((~ $number) & 0xff) << 8) | ((~ ord($data[++$index])) & 0xff));
283        } else {
284            $number = ($number << 8) | ord($data[++$index]);
285        }
286        return $number;
287    }
288
289    /**
290     * Extracts an unsigned 2-byte integer from a string.
291     *
292     * Integers are always big-endian. Throws an exception if the index is out
293     * of range.
294     *
295     * @param string &$data
296     * @param integer $index Position in string of integer.
297     * @return integer
298     * @throws Zend_Pdf_Exception
299     */
300    protected function _extractUInt2(&$data, $index)
301    {
302        if (($index < 0) | (($index + 1) > strlen($data))) {
303            throw new Zend_Pdf_Exception("Index out of range: $index",
304                                         Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
305        }
306        $number = (ord($data[$index]) << 8) | ord($data[++$index]);
307        return $number;
308    }
309
310    /**
311     * Extracts an unsigned 4-byte integer from a string.
312     *
313     * Integers are always big-endian. Throws an exception if the index is out
314     * of range.
315     *
316     * NOTE: If you ask for a 4-byte unsigned integer on a 32-bit machine, the
317     * resulting value WILL BE SIGNED because PHP uses signed integers internally
318     * for everything. To guarantee portability, be sure to use bitwise or
319     * similar operators on large integers!
320     *
321     * @param string &$data
322     * @param integer $index Position in string of integer.
323     * @return integer
324     * @throws Zend_Pdf_Exception
325     */
326    protected function _extractUInt4(&$data, $index)
327    {
328        if (($index < 0) | (($index + 3) > strlen($data))) {
329            throw new Zend_Pdf_Exception("Index out of range: $index",
330                                         Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);
331        }
332        $number = (ord($data[$index]) << 24) | (ord($data[++$index]) << 16) |
333                  (ord($data[++$index]) << 8) | ord($data[++$index]);
334        return $number;
335    }
336
337}