web/lib/Zend/Pdf/Resource/Font.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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-2010 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 20096 2010-01-06 02:05:09Z bkarwin $
       
    21  */
       
    22 
       
    23 /** Zend_Pdf_Resource */
       
    24 require_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  */
       
    32 require_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-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    48  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    49  */
       
    50 abstract 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