PageRenderTime 31ms CodeModel.GetById 19ms app.highlight 9ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Pdf/Resource/Font.php

https://bitbucket.org/hamidrezas/melobit
PHP | 530 lines | 125 code | 58 blank | 347 comment | 13 complexity | 8a4e75395b1b53621f5b527499dcd7ec MD5 | raw file
Possible License(s): AGPL-1.0
  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 * @category   Zend
 16 * @package    Zend_Pdf
 17 * @subpackage Fonts
 18 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 19 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20 * @version    $Id: Font.php 24594 2012-01-05 21:27:01Z matthew $
 21 */
 22
 23/** Zend_Pdf_Resource */
 24require_once 'Zend/Pdf/Resource.php';
 25
 26/**
 27 * Zend_Pdf_Font
 28 *
 29 * Zend_Pdf_Font class constants are used within Zend_Pdf_Resource_Font
 30 * and its subclusses.
 31 */
 32require_once 'Zend/Pdf/Font.php';
 33
 34/**
 35 * Abstract class which manages PDF fonts.
 36 *
 37 * Defines the public interface and creates shared storage for concrete
 38 * subclasses which are responsible for generating the font's information
 39 * dictionaries, mapping characters to glyphs, and providing both overall font
 40 * and glyph-specific metric data.
 41 *
 42 * Font objects should be normally be obtained from the factory methods
 43 * {@link Zend_Pdf_Font::fontWithName} and {@link Zend_Pdf_Font::fontWithPath}.
 44 *
 45 * @package    Zend_Pdf
 46 * @subpackage Fonts
 47 * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 48 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 49 */
 50abstract class Zend_Pdf_Resource_Font extends Zend_Pdf_Resource
 51{
 52  /**** Instance Variables ****/
 53
 54
 55    /**
 56     * The type of font. Use TYPE_ constants defined in {@link Zend_Pdf_Font}.
 57     * @var integer
 58     */
 59    protected $_fontType = Zend_Pdf_Font::TYPE_UNKNOWN;
 60
 61    /**
 62     * Array containing descriptive names for the font. See {@link fontName()}.
 63     * @var array
 64     */
 65    protected $_fontNames = array();
 66
 67    /**
 68     * Flag indicating whether or not this font is bold.
 69     * @var boolean
 70     */
 71    protected $_isBold = false;
 72
 73    /**
 74     * Flag indicating whether or not this font is italic.
 75     * @var boolean
 76     */
 77    protected $_isItalic = false;
 78
 79    /**
 80     * Flag indicating whether or not this font is monospaced.
 81     * @var boolean
 82     */
 83    protected $_isMonospace = false;
 84
 85    /**
 86     * The position below the text baseline of the underline (in glyph units).
 87     * @var integer
 88     */
 89    protected $_underlinePosition = 0;
 90
 91    /**
 92     * The thickness of the underline (in glyph units).
 93     * @var integer
 94     */
 95    protected $_underlineThickness = 0;
 96
 97    /**
 98     * The position above the text baseline of the strikethrough (in glyph units).
 99     * @var integer
100     */
101    protected $_strikePosition = 0;
102
103    /**
104     * The thickness of the strikethrough (in glyph units).
105     * @var integer
106     */
107    protected $_strikeThickness = 0;
108
109    /**
110     * Number of glyph units per em. See {@link getUnitsPerEm()}.
111     * @var integer
112     */
113    protected $_unitsPerEm = 0;
114
115    /**
116     * Typographical ascent. See {@link getAscent()}.
117     * @var integer
118     */
119    protected $_ascent = 0;
120
121    /**
122     * Typographical descent. See {@link getDescent()}.
123     * @var integer
124     */
125    protected $_descent = 0;
126
127    /**
128     * Typographical line gap. See {@link getLineGap()}.
129     * @var integer
130     */
131    protected $_lineGap = 0;
132
133
134
135  /**** Public Interface ****/
136
137
138  /* Object Lifecycle */
139
140    /**
141     * Object constructor.
142     *
143     */
144    public function __construct()
145    {
146        parent::__construct(new Zend_Pdf_Element_Dictionary());
147        $this->_resource->Type = new Zend_Pdf_Element_Name('Font');
148    }
149
150
151  /* Object Magic Methods */
152
153    /**
154     * Returns the full name of the font in the encoding method of the current
155     * locale. Transliterates any characters that cannot be naturally
156     * represented in that character set.
157     *
158     * @return string
159     */
160    public function __toString()
161    {
162        return $this->getFontName(Zend_Pdf_Font::NAME_FULL, '', '//TRANSLIT');
163    }
164
165
166  /* Accessors */
167
168    /**
169     * Returns the type of font.
170     *
171     * @return integer One of the TYPE_ constants defined in
172     *   {@link Zend_Pdf_Font}.
173     */
174    public function getFontType()
175    {
176        return $this->_fontType;
177    }
178
179    /**
180     * Returns the specified descriptive name for the font.
181     *
182     * The font name type is usually one of the following:
183     * <ul>
184     *  <li>{@link Zend_Pdf_Font::NAME_FULL}
185     *  <li>{@link Zend_Pdf_Font::NAME_FAMILY}
186     *  <li>{@link Zend_Pdf_Font::NAME_PREFERRED_FAMILY}
187     *  <li>{@link Zend_Pdf_Font::NAME_STYLE}
188     *  <li>{@link Zend_Pdf_Font::NAME_PREFERRED_STYLE}
189     *  <li>{@link Zend_Pdf_Font::NAME_DESCRIPTION}
190     *  <li>{@link Zend_Pdf_Font::NAME_SAMPLE_TEXT}
191     *  <li>{@link Zend_Pdf_Font::NAME_ID}
192     *  <li>{@link Zend_Pdf_Font::NAME_VERSION}
193     *  <li>{@link Zend_Pdf_Font::NAME_POSTSCRIPT}
194     *  <li>{@link Zend_Pdf_Font::NAME_CID_NAME}
195     *  <li>{@link Zend_Pdf_Font::NAME_DESIGNER}
196     *  <li>{@link Zend_Pdf_Font::NAME_DESIGNER_URL}
197     *  <li>{@link Zend_Pdf_Font::NAME_MANUFACTURER}
198     *  <li>{@link Zend_Pdf_Font::NAME_VENDOR_URL}
199     *  <li>{@link Zend_Pdf_Font::NAME_COPYRIGHT}
200     *  <li>{@link Zend_Pdf_Font::NAME_TRADEMARK}
201     *  <li>{@link Zend_Pdf_Font::NAME_LICENSE}
202     *  <li>{@link Zend_Pdf_Font::NAME_LICENSE_URL}
203     * </ul>
204     *
205     * Note that not all names are available for all fonts. In addition, some
206     * fonts may contain additional names, whose indicies are in the range
207     * 256 to 32767 inclusive, which are used for certain font layout features.
208     *
209     * If the preferred language translation is not available, uses the first
210     * available translation for the name, which is usually English.
211     *
212     * If the requested name does not exist, returns null.
213     *
214     * All names are stored internally as Unicode strings, using UTF-16BE
215     * encoding. You may optionally supply a different resulting character set.
216     *
217     * @param integer $nameType Type of name requested.
218     * @param mixed $language Preferred language (string) or array of languages
219     *   in preferred order. Use the ISO 639 standard 2-letter language codes.
220     * @param string $characterSet (optional) Desired resulting character set.
221     *   You may use any character set supported by {@link iconv()};
222     * @return string
223     */
224    public function getFontName($nameType, $language, $characterSet = null)
225    {
226        if (! isset($this->_fontNames[$nameType])) {
227            return null;
228        }
229        $name = null;
230        if (is_array($language)) {
231            foreach ($language as $code) {
232                if (isset($this->_fontNames[$nameType][$code])) {
233                    $name = $this->_fontNames[$nameType][$code];
234                    break;
235                }
236            }
237        } else {
238            if (isset($this->_fontNames[$nameType][$language])) {
239                $name = $this->_fontNames[$nameType][$language];
240            }
241        }
242        /* If the preferred language could not be found, use whatever is first.
243         */
244        if ($name === null) {
245            $names = $this->_fontNames[$nameType];
246            $name  = reset($names);
247        }
248        /* Convert the character set if requested.
249         */
250        if (($characterSet !== null) && ($characterSet != 'UTF-16BE') && PHP_OS != 'AIX') { // AIX knows not this charset
251            $name = iconv('UTF-16BE', $characterSet, $name);
252        }
253        return $name;
254    }
255
256    /**
257     * Returns whole set of font names.
258     *
259     * @return array
260     */
261    public function getFontNames()
262    {
263        return $this->_fontNames;
264    }
265
266    /**
267     * Returns true if font is bold.
268     *
269     * @return boolean
270     */
271    public function isBold()
272    {
273        return $this->_isBold;
274    }
275
276    /**
277     * Returns true if font is italic.
278     *
279     * @return boolean
280     */
281    public function isItalic()
282    {
283        return $this->_isItalic;
284    }
285
286    /**
287     * Returns true if font is monospace.
288     *
289     * @return boolean
290     */
291    public function isMonospace()
292    {
293        return $this->_isMonospace;
294    }
295
296    /**
297     * Returns the suggested position below the text baseline of the underline
298     * in glyph units.
299     *
300     * This value is usually negative.
301     *
302     * @return integer
303     */
304    public function getUnderlinePosition()
305    {
306        return $this->_underlinePosition;
307    }
308
309    /**
310     * Returns the suggested line thickness of the underline in glyph units.
311     *
312     * @return integer
313     */
314    public function getUnderlineThickness()
315    {
316        return $this->_underlineThickness;
317    }
318
319    /**
320     * Returns the suggested position above the text baseline of the
321     * strikethrough in glyph units.
322     *
323     * @return integer
324     */
325    public function getStrikePosition()
326    {
327        return $this->_strikePosition;
328    }
329
330    /**
331     * Returns the suggested line thickness of the strikethrough in glyph units.
332     *
333     * @return integer
334     */
335    public function getStrikeThickness()
336    {
337        return $this->_strikeThickness;
338    }
339
340    /**
341     * Returns the number of glyph units per em.
342     *
343     * Used to convert glyph space to user space. Frequently used in conjunction
344     * with {@link widthsForGlyphs()} to calculate the with of a run of text.
345     *
346     * @return integer
347     */
348    public function getUnitsPerEm()
349    {
350        return $this->_unitsPerEm;
351    }
352
353    /**
354     * Returns the typographic ascent in font glyph units.
355     *
356     * The typographic ascent is the distance from the font's baseline to the
357     * top of the text frame. It is frequently used to locate the initial
358     * baseline for a paragraph of text inside a given rectangle.
359     *
360     * @return integer
361     */
362    public function getAscent()
363    {
364        return $this->_ascent;
365    }
366
367    /**
368     * Returns the typographic descent in font glyph units.
369     *
370     * The typographic descent is the distance below the font's baseline to the
371     * bottom of the text frame. It is always negative.
372     *
373     * @return integer
374     */
375    public function getDescent()
376    {
377        return $this->_descent;
378    }
379
380    /**
381     * Returns the typographic line gap in font glyph units.
382     *
383     * The typographic line gap is the distance between the bottom of the text
384     * frame of one line to the top of the text frame of the next. It is
385     * typically combined with the typographical ascent and descent to determine
386     * the font's total line height (or leading).
387     *
388     * @return integer
389     */
390    public function getLineGap()
391    {
392        return $this->_lineGap;
393    }
394
395    /**
396     * Returns the suggested line height (or leading) in font glyph units.
397     *
398     * This value is determined by adding together the values of the typographic
399     * ascent, descent, and line gap. This value yields the suggested line
400     * spacing as determined by the font developer.
401     *
402     * It should be noted that this is only a guideline; layout engines will
403     * frequently modify this value to achieve special effects such as double-
404     * spacing.
405     *
406     * @return integer
407     */
408    public function getLineHeight()
409    {
410        return $this->_ascent - $this->_descent + $this->_lineGap;
411    }
412
413
414  /* Information and Conversion Methods */
415
416    /**
417     * Returns an array of glyph numbers corresponding to the Unicode characters.
418     *
419     * If a particular character doesn't exist in this font, the special 'missing
420     * character glyph' will be substituted.
421     *
422     * See also {@link glyphNumberForCharacter()}.
423     *
424     * @param array $characterCodes Array of Unicode character codes (code points).
425     * @return array Array of glyph numbers.
426     */
427    abstract public function glyphNumbersForCharacters($characterCodes);
428
429    /**
430     * Returns the glyph number corresponding to the Unicode character.
431     *
432     * If a particular character doesn't exist in this font, the special 'missing
433     * character glyph' will be substituted.
434     *
435     * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
436     * operations.
437     *
438     * @param integer $characterCode Unicode character code (code point).
439     * @return integer Glyph number.
440     */
441    abstract public function glyphNumberForCharacter($characterCode);
442
443    /**
444     * Returns a number between 0 and 1 inclusive that indicates the percentage
445     * of characters in the string which are covered by glyphs in this font.
446     *
447     * Since no one font will contain glyphs for the entire Unicode character
448     * range, this method can be used to help locate a suitable font when the
449     * actual contents of the string are not known.
450     *
451     * Note that some fonts lie about the characters they support. Additionally,
452     * fonts don't usually contain glyphs for control characters such as tabs
453     * and line breaks, so it is rare that you will get back a full 1.0 score.
454     * The resulting value should be considered informational only.
455     *
456     * @param string $string
457     * @param string $charEncoding (optional) Character encoding of source text.
458     *   If omitted, uses 'current locale'.
459     * @return float
460     */
461    abstract public function getCoveredPercentage($string, $charEncoding = '');
462
463    /**
464     * Returns the widths of the glyphs.
465     *
466     * The widths are expressed in the font's glyph space. You are responsible
467     * for converting to user space as necessary. See {@link unitsPerEm()}.
468     *
469     * See also {@link widthForGlyph()}.
470     *
471     * @param array $glyphNumbers Array of glyph numbers.
472     * @return array Array of glyph widths (integers).
473     * @throws Zend_Pdf_Exception
474     */
475    abstract public function widthsForGlyphs($glyphNumbers);
476
477    /**
478     * Returns the width of the glyph.
479     *
480     * Like {@link widthsForGlyphs()} but used for one glyph at a time.
481     *
482     * @param integer $glyphNumber
483     * @return integer
484     * @throws Zend_Pdf_Exception
485     */
486    abstract public function widthForGlyph($glyphNumber);
487
488    /**
489     * Convert string to the font encoding.
490     *
491     * The method is used to prepare string for text drawing operators
492     *
493     * @param string $string
494     * @param string $charEncoding Character encoding of source text.
495     * @return string
496     */
497    abstract public function encodeString($string, $charEncoding);
498
499    /**
500     * Convert string from the font encoding.
501     *
502     * The method is used to convert strings retrieved from existing content streams
503     *
504     * @param string $string
505     * @param string $charEncoding Character encoding of resulting text.
506     * @return string
507     */
508    abstract public function decodeString($string, $charEncoding);
509
510
511
512  /**** Internal Methods ****/
513
514
515    /**
516     * If the font's glyph space is not 1000 units per em, converts the value.
517     *
518     * @internal
519     * @param integer $value
520     * @return integer
521     */
522    public function toEmSpace($value)
523    {
524        if ($this->_unitsPerEm == 1000) {
525            return $value;
526        }
527        return ceil(($value / $this->_unitsPerEm) * 1000);    // always round up
528    }
529}
530