File indexing completed on 2024-12-22 05:36:56

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Pdf
0017  * @subpackage Fonts
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /** Zend_Pdf_Resource */
0024 // require_once 'Zend/Pdf/Resource.php';
0025 
0026 /**
0027  * Zend_Pdf_Font
0028  *
0029  * Zend_Pdf_Font class constants are used within Zend_Pdf_Resource_Font
0030  * and its subclusses.
0031  */
0032 // require_once 'Zend/Pdf/Font.php';
0033 
0034 /**
0035  * Abstract class which manages PDF fonts.
0036  *
0037  * Defines the public interface and creates shared storage for concrete
0038  * subclasses which are responsible for generating the font's information
0039  * dictionaries, mapping characters to glyphs, and providing both overall font
0040  * and glyph-specific metric data.
0041  *
0042  * Font objects should be normally be obtained from the factory methods
0043  * {@link Zend_Pdf_Font::fontWithName} and {@link Zend_Pdf_Font::fontWithPath}.
0044  *
0045  * @package    Zend_Pdf
0046  * @subpackage Fonts
0047  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0048  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0049  */
0050 abstract class Zend_Pdf_Resource_Font extends Zend_Pdf_Resource
0051 {
0052   /**** Instance Variables ****/
0053 
0054 
0055     /**
0056      * The type of font. Use TYPE_ constants defined in {@link Zend_Pdf_Font}.
0057      * @var integer
0058      */
0059     protected $_fontType = Zend_Pdf_Font::TYPE_UNKNOWN;
0060 
0061     /**
0062      * Array containing descriptive names for the font. See {@link fontName()}.
0063      * @var array
0064      */
0065     protected $_fontNames = array();
0066 
0067     /**
0068      * Flag indicating whether or not this font is bold.
0069      * @var boolean
0070      */
0071     protected $_isBold = false;
0072 
0073     /**
0074      * Flag indicating whether or not this font is italic.
0075      * @var boolean
0076      */
0077     protected $_isItalic = false;
0078 
0079     /**
0080      * Flag indicating whether or not this font is monospaced.
0081      * @var boolean
0082      */
0083     protected $_isMonospace = false;
0084 
0085     /**
0086      * The position below the text baseline of the underline (in glyph units).
0087      * @var integer
0088      */
0089     protected $_underlinePosition = 0;
0090 
0091     /**
0092      * The thickness of the underline (in glyph units).
0093      * @var integer
0094      */
0095     protected $_underlineThickness = 0;
0096 
0097     /**
0098      * The position above the text baseline of the strikethrough (in glyph units).
0099      * @var integer
0100      */
0101     protected $_strikePosition = 0;
0102 
0103     /**
0104      * The thickness of the strikethrough (in glyph units).
0105      * @var integer
0106      */
0107     protected $_strikeThickness = 0;
0108 
0109     /**
0110      * Number of glyph units per em. See {@link getUnitsPerEm()}.
0111      * @var integer
0112      */
0113     protected $_unitsPerEm = 0;
0114 
0115     /**
0116      * Typographical ascent. See {@link getAscent()}.
0117      * @var integer
0118      */
0119     protected $_ascent = 0;
0120 
0121     /**
0122      * Typographical descent. See {@link getDescent()}.
0123      * @var integer
0124      */
0125     protected $_descent = 0;
0126 
0127     /**
0128      * Typographical line gap. See {@link getLineGap()}.
0129      * @var integer
0130      */
0131     protected $_lineGap = 0;
0132 
0133 
0134 
0135   /**** Public Interface ****/
0136 
0137 
0138   /* Object Lifecycle */
0139 
0140     /**
0141      * Object constructor.
0142      *
0143      */
0144     public function __construct()
0145     {
0146         parent::__construct(new Zend_Pdf_Element_Dictionary());
0147         $this->_resource->Type = new Zend_Pdf_Element_Name('Font');
0148     }
0149 
0150 
0151   /* Object Magic Methods */
0152 
0153     /**
0154      * Returns the full name of the font in the encoding method of the current
0155      * locale. Transliterates any characters that cannot be naturally
0156      * represented in that character set.
0157      *
0158      * @return string
0159      */
0160     public function __toString()
0161     {
0162         return $this->getFontName(Zend_Pdf_Font::NAME_FULL, '', '//TRANSLIT');
0163     }
0164 
0165 
0166   /* Accessors */
0167 
0168     /**
0169      * Returns the type of font.
0170      *
0171      * @return integer One of the TYPE_ constants defined in
0172      *   {@link Zend_Pdf_Font}.
0173      */
0174     public function getFontType()
0175     {
0176         return $this->_fontType;
0177     }
0178 
0179     /**
0180      * Returns the specified descriptive name for the font.
0181      *
0182      * The font name type is usually one of the following:
0183      * <ul>
0184      *  <li>{@link Zend_Pdf_Font::NAME_FULL}
0185      *  <li>{@link Zend_Pdf_Font::NAME_FAMILY}
0186      *  <li>{@link Zend_Pdf_Font::NAME_PREFERRED_FAMILY}
0187      *  <li>{@link Zend_Pdf_Font::NAME_STYLE}
0188      *  <li>{@link Zend_Pdf_Font::NAME_PREFERRED_STYLE}
0189      *  <li>{@link Zend_Pdf_Font::NAME_DESCRIPTION}
0190      *  <li>{@link Zend_Pdf_Font::NAME_SAMPLE_TEXT}
0191      *  <li>{@link Zend_Pdf_Font::NAME_ID}
0192      *  <li>{@link Zend_Pdf_Font::NAME_VERSION}
0193      *  <li>{@link Zend_Pdf_Font::NAME_POSTSCRIPT}
0194      *  <li>{@link Zend_Pdf_Font::NAME_CID_NAME}
0195      *  <li>{@link Zend_Pdf_Font::NAME_DESIGNER}
0196      *  <li>{@link Zend_Pdf_Font::NAME_DESIGNER_URL}
0197      *  <li>{@link Zend_Pdf_Font::NAME_MANUFACTURER}
0198      *  <li>{@link Zend_Pdf_Font::NAME_VENDOR_URL}
0199      *  <li>{@link Zend_Pdf_Font::NAME_COPYRIGHT}
0200      *  <li>{@link Zend_Pdf_Font::NAME_TRADEMARK}
0201      *  <li>{@link Zend_Pdf_Font::NAME_LICENSE}
0202      *  <li>{@link Zend_Pdf_Font::NAME_LICENSE_URL}
0203      * </ul>
0204      *
0205      * Note that not all names are available for all fonts. In addition, some
0206      * fonts may contain additional names, whose indicies are in the range
0207      * 256 to 32767 inclusive, which are used for certain font layout features.
0208      *
0209      * If the preferred language translation is not available, uses the first
0210      * available translation for the name, which is usually English.
0211      *
0212      * If the requested name does not exist, returns null.
0213      *
0214      * All names are stored internally as Unicode strings, using UTF-16BE
0215      * encoding. You may optionally supply a different resulting character set.
0216      *
0217      * @param integer $nameType Type of name requested.
0218      * @param mixed $language Preferred language (string) or array of languages
0219      *   in preferred order. Use the ISO 639 standard 2-letter language codes.
0220      * @param string $characterSet (optional) Desired resulting character set.
0221      *   You may use any character set supported by {@link iconv()};
0222      * @return string
0223      */
0224     public function getFontName($nameType, $language, $characterSet = null)
0225     {
0226         if (! isset($this->_fontNames[$nameType])) {
0227             return null;
0228         }
0229         $name = null;
0230         if (is_array($language)) {
0231             foreach ($language as $code) {
0232                 if (isset($this->_fontNames[$nameType][$code])) {
0233                     $name = $this->_fontNames[$nameType][$code];
0234                     break;
0235                 }
0236             }
0237         } else {
0238             if (isset($this->_fontNames[$nameType][$language])) {
0239                 $name = $this->_fontNames[$nameType][$language];
0240             }
0241         }
0242         /* If the preferred language could not be found, use whatever is first.
0243          */
0244         if ($name === null) {
0245             $names = $this->_fontNames[$nameType];
0246             $name  = reset($names);
0247         }
0248         /* Convert the character set if requested.
0249          */
0250         if (($characterSet !== null) && ($characterSet != 'UTF-16BE') && PHP_OS != 'AIX') { // AIX knows not this charset
0251             $name = iconv('UTF-16BE', $characterSet, $name);
0252         }
0253         return $name;
0254     }
0255 
0256     /**
0257      * Returns whole set of font names.
0258      *
0259      * @return array
0260      */
0261     public function getFontNames()
0262     {
0263         return $this->_fontNames;
0264     }
0265 
0266     /**
0267      * Returns true if font is bold.
0268      *
0269      * @return boolean
0270      */
0271     public function isBold()
0272     {
0273         return $this->_isBold;
0274     }
0275 
0276     /**
0277      * Returns true if font is italic.
0278      *
0279      * @return boolean
0280      */
0281     public function isItalic()
0282     {
0283         return $this->_isItalic;
0284     }
0285 
0286     /**
0287      * Returns true if font is monospace.
0288      *
0289      * @return boolean
0290      */
0291     public function isMonospace()
0292     {
0293         return $this->_isMonospace;
0294     }
0295 
0296     /**
0297      * Returns the suggested position below the text baseline of the underline
0298      * in glyph units.
0299      *
0300      * This value is usually negative.
0301      *
0302      * @return integer
0303      */
0304     public function getUnderlinePosition()
0305     {
0306         return $this->_underlinePosition;
0307     }
0308 
0309     /**
0310      * Returns the suggested line thickness of the underline in glyph units.
0311      *
0312      * @return integer
0313      */
0314     public function getUnderlineThickness()
0315     {
0316         return $this->_underlineThickness;
0317     }
0318 
0319     /**
0320      * Returns the suggested position above the text baseline of the
0321      * strikethrough in glyph units.
0322      *
0323      * @return integer
0324      */
0325     public function getStrikePosition()
0326     {
0327         return $this->_strikePosition;
0328     }
0329 
0330     /**
0331      * Returns the suggested line thickness of the strikethrough in glyph units.
0332      *
0333      * @return integer
0334      */
0335     public function getStrikeThickness()
0336     {
0337         return $this->_strikeThickness;
0338     }
0339 
0340     /**
0341      * Returns the number of glyph units per em.
0342      *
0343      * Used to convert glyph space to user space. Frequently used in conjunction
0344      * with {@link widthsForGlyphs()} to calculate the with of a run of text.
0345      *
0346      * @return integer
0347      */
0348     public function getUnitsPerEm()
0349     {
0350         return $this->_unitsPerEm;
0351     }
0352 
0353     /**
0354      * Returns the typographic ascent in font glyph units.
0355      *
0356      * The typographic ascent is the distance from the font's baseline to the
0357      * top of the text frame. It is frequently used to locate the initial
0358      * baseline for a paragraph of text inside a given rectangle.
0359      *
0360      * @return integer
0361      */
0362     public function getAscent()
0363     {
0364         return $this->_ascent;
0365     }
0366 
0367     /**
0368      * Returns the typographic descent in font glyph units.
0369      *
0370      * The typographic descent is the distance below the font's baseline to the
0371      * bottom of the text frame. It is always negative.
0372      *
0373      * @return integer
0374      */
0375     public function getDescent()
0376     {
0377         return $this->_descent;
0378     }
0379 
0380     /**
0381      * Returns the typographic line gap in font glyph units.
0382      *
0383      * The typographic line gap is the distance between the bottom of the text
0384      * frame of one line to the top of the text frame of the next. It is
0385      * typically combined with the typographical ascent and descent to determine
0386      * the font's total line height (or leading).
0387      *
0388      * @return integer
0389      */
0390     public function getLineGap()
0391     {
0392         return $this->_lineGap;
0393     }
0394 
0395     /**
0396      * Returns the suggested line height (or leading) in font glyph units.
0397      *
0398      * This value is determined by adding together the values of the typographic
0399      * ascent, descent, and line gap. This value yields the suggested line
0400      * spacing as determined by the font developer.
0401      *
0402      * It should be noted that this is only a guideline; layout engines will
0403      * frequently modify this value to achieve special effects such as double-
0404      * spacing.
0405      *
0406      * @return integer
0407      */
0408     public function getLineHeight()
0409     {
0410         return $this->_ascent - $this->_descent + $this->_lineGap;
0411     }
0412 
0413 
0414   /* Information and Conversion Methods */
0415 
0416     /**
0417      * Returns an array of glyph numbers corresponding to the Unicode characters.
0418      *
0419      * If a particular character doesn't exist in this font, the special 'missing
0420      * character glyph' will be substituted.
0421      *
0422      * See also {@link glyphNumberForCharacter()}.
0423      *
0424      * @param array $characterCodes Array of Unicode character codes (code points).
0425      * @return array Array of glyph numbers.
0426      */
0427     abstract public function glyphNumbersForCharacters($characterCodes);
0428 
0429     /**
0430      * Returns the glyph number corresponding to the Unicode character.
0431      *
0432      * If a particular character doesn't exist in this font, the special 'missing
0433      * character glyph' will be substituted.
0434      *
0435      * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
0436      * operations.
0437      *
0438      * @param integer $characterCode Unicode character code (code point).
0439      * @return integer Glyph number.
0440      */
0441     abstract public function glyphNumberForCharacter($characterCode);
0442 
0443     /**
0444      * Returns a number between 0 and 1 inclusive that indicates the percentage
0445      * of characters in the string which are covered by glyphs in this font.
0446      *
0447      * Since no one font will contain glyphs for the entire Unicode character
0448      * range, this method can be used to help locate a suitable font when the
0449      * actual contents of the string are not known.
0450      *
0451      * Note that some fonts lie about the characters they support. Additionally,
0452      * fonts don't usually contain glyphs for control characters such as tabs
0453      * and line breaks, so it is rare that you will get back a full 1.0 score.
0454      * The resulting value should be considered informational only.
0455      *
0456      * @param string $string
0457      * @param string $charEncoding (optional) Character encoding of source text.
0458      *   If omitted, uses 'current locale'.
0459      * @return float
0460      */
0461     abstract public function getCoveredPercentage($string, $charEncoding = '');
0462 
0463     /**
0464      * Returns the widths of the glyphs.
0465      *
0466      * The widths are expressed in the font's glyph space. You are responsible
0467      * for converting to user space as necessary. See {@link unitsPerEm()}.
0468      *
0469      * See also {@link widthForGlyph()}.
0470      *
0471      * @param array $glyphNumbers Array of glyph numbers.
0472      * @return array Array of glyph widths (integers).
0473      * @throws Zend_Pdf_Exception
0474      */
0475     abstract public function widthsForGlyphs($glyphNumbers);
0476 
0477     /**
0478      * Returns the width of the glyph.
0479      *
0480      * Like {@link widthsForGlyphs()} but used for one glyph at a time.
0481      *
0482      * @param integer $glyphNumber
0483      * @return integer
0484      * @throws Zend_Pdf_Exception
0485      */
0486     abstract public function widthForGlyph($glyphNumber);
0487 
0488     /**
0489      * Convert string to the font encoding.
0490      *
0491      * The method is used to prepare string for text drawing operators
0492      *
0493      * @param string $string
0494      * @param string $charEncoding Character encoding of source text.
0495      * @return string
0496      */
0497     abstract public function encodeString($string, $charEncoding);
0498 
0499     /**
0500      * Convert string from the font encoding.
0501      *
0502      * The method is used to convert strings retrieved from existing content streams
0503      *
0504      * @param string $string
0505      * @param string $charEncoding Character encoding of resulting text.
0506      * @return string
0507      */
0508     abstract public function decodeString($string, $charEncoding);
0509 
0510 
0511 
0512   /**** Internal Methods ****/
0513 
0514 
0515     /**
0516      * If the font's glyph space is not 1000 units per em, converts the value.
0517      *
0518      * @internal
0519      * @param integer $value
0520      * @return integer
0521      */
0522     public function toEmSpace($value)
0523     {
0524         if ($this->_unitsPerEm == 1000) {
0525             return $value;
0526         }
0527         return ceil(($value / $this->_unitsPerEm) * 1000);    // always round up
0528     }
0529 }
0530