web/lib/Zend/Pdf/Resource/Font/FontDescriptor.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: FontDescriptor.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    21  */
       
    22 
       
    23 
       
    24 /** Internally used classes */
       
    25 require_once 'Zend/Pdf/Element/Array.php';
       
    26 require_once 'Zend/Pdf/Element/Dictionary.php';
       
    27 require_once 'Zend/Pdf/Element/Name.php';
       
    28 require_once 'Zend/Pdf/Element/Numeric.php';
       
    29 
       
    30 /** Zend_Pdf_Font */
       
    31 require_once 'Zend/Pdf/Font.php';
       
    32 
       
    33 
       
    34 /**
       
    35  * FontDescriptor implementation
       
    36  *
       
    37  * A font descriptor specifies metrics and other attributes of a simple font or a
       
    38  * CIDFont as a whole, as distinct from the metrics of individual glyphs. These font
       
    39  * metrics provide information that enables a viewer application to synthesize a
       
    40  * substitute font or select a similar font when the font program is unavailable. The
       
    41  * font descriptor may also be used to embed the font program in the PDF file.
       
    42  *
       
    43  * @package    Zend_Pdf
       
    44  * @subpackage Fonts
       
    45  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    46  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    47  */
       
    48 class Zend_Pdf_Resource_Font_FontDescriptor
       
    49 {
       
    50     /**
       
    51      * Object constructor
       
    52      * @throws Zend_Pdf_Exception
       
    53      */
       
    54     public function __construct()
       
    55     {
       
    56         require_once 'Zend/Pdf/Exception.php';
       
    57         throw new Zend_Pdf_Exception('Zend_Pdf_Resource_Font_FontDescriptor is not intended to be instantiated');
       
    58     }
       
    59 
       
    60     /**
       
    61      * Object constructor
       
    62      *
       
    63      * The $embeddingOptions parameter allows you to set certain flags related
       
    64      * to font embedding. You may combine options by OR-ing them together. See
       
    65      * the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of
       
    66      * available options and their descriptions.
       
    67      *
       
    68      * Note that it is not requried that fonts be embedded within the PDF file
       
    69      * to use them. If the recipient of the PDF has the font installed on their
       
    70      * computer, they will see the correct fonts in the document. If they don't,
       
    71      * the PDF viewer will substitute or synthesize a replacement.
       
    72      *
       
    73      *
       
    74      * @param Zend_Pdf_Resource_Font $font Font
       
    75      * @param Zend_Pdf_FileParser_Font_OpenType $fontParser Font parser object containing parsed TrueType file.
       
    76      * @param integer $embeddingOptions Options for font embedding.
       
    77      * @return Zend_Pdf_Element_Dictionary
       
    78      * @throws Zend_Pdf_Exception
       
    79      */
       
    80     static public function factory(Zend_Pdf_Resource_Font $font, Zend_Pdf_FileParser_Font_OpenType $fontParser, $embeddingOptions)
       
    81     {
       
    82         /* The font descriptor object contains the rest of the font metrics and
       
    83          * the information about the embedded font program (if applicible).
       
    84          */
       
    85         $fontDescriptor = new Zend_Pdf_Element_Dictionary();
       
    86 
       
    87         $fontDescriptor->Type     = new Zend_Pdf_Element_Name('FontDescriptor');
       
    88         $fontDescriptor->FontName = new Zend_Pdf_Element_Name($font->getResource()->BaseFont->value);
       
    89 
       
    90         /* The font flags value is a bitfield that describes the stylistic
       
    91          * attributes of the font. We will set as many of the bits as can be
       
    92          * determined from the font parser.
       
    93          */
       
    94         $flags = 0;
       
    95         if ($fontParser->isMonospaced) {    // bit 1: FixedPitch
       
    96             $flags |= 1 << 0;
       
    97         }
       
    98         if ($fontParser->isSerifFont) {    // bit 2: Serif
       
    99             $flags |= 1 << 1;
       
   100         }
       
   101         if (! $fontParser->isAdobeLatinSubset) {    // bit 3: Symbolic
       
   102             $flags |= 1 << 2;
       
   103         }
       
   104         if ($fontParser->isScriptFont) {    // bit 4: Script
       
   105             $flags |= 1 << 3;
       
   106         }
       
   107         if ($fontParser->isAdobeLatinSubset) {    // bit 6: Nonsymbolic
       
   108             $flags |= 1 << 5;
       
   109         }
       
   110         if ($fontParser->isItalic) {    // bit 7: Italic
       
   111             $flags |= 1 << 6;
       
   112         }
       
   113         // bits 17-19: AllCap, SmallCap, ForceBold; not available
       
   114         $fontDescriptor->Flags = new Zend_Pdf_Element_Numeric($flags);
       
   115 
       
   116         $fontBBox = array(new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->xMin)),
       
   117                           new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->yMin)),
       
   118                           new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->xMax)),
       
   119                           new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->yMax)));
       
   120         $fontDescriptor->FontBBox     = new Zend_Pdf_Element_Array($fontBBox);
       
   121 
       
   122         $fontDescriptor->ItalicAngle  = new Zend_Pdf_Element_Numeric($fontParser->italicAngle);
       
   123 
       
   124         $fontDescriptor->Ascent       = new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->ascent));
       
   125         $fontDescriptor->Descent      = new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->descent));
       
   126 
       
   127         $fontDescriptor->CapHeight    = new Zend_Pdf_Element_Numeric($fontParser->capitalHeight);
       
   128         /**
       
   129          * The vertical stem width is not yet extracted from the OpenType font
       
   130          * file. For now, record zero which is interpreted as 'unknown'.
       
   131          * @todo Calculate value for StemV.
       
   132          */
       
   133         $fontDescriptor->StemV        = new Zend_Pdf_Element_Numeric(0);
       
   134 
       
   135         $fontDescriptor->MissingWidth = new Zend_Pdf_Element_Numeric($fontParser->glyphWidths[0]);
       
   136 
       
   137         /* Set up font embedding. This is where the actual font program itself
       
   138          * is embedded within the PDF document.
       
   139          *
       
   140          * Note that it is not requried that fonts be embedded within the PDF
       
   141          * document to use them. If the recipient of the PDF has the font
       
   142          * installed on their computer, they will see the correct fonts in the
       
   143          * document. If they don't, the PDF viewer will substitute or synthesize
       
   144          * a replacement.
       
   145          *
       
   146          * There are several guidelines for font embedding:
       
   147          *
       
   148          * First, the developer might specifically request not to embed the font.
       
   149          */
       
   150         if (!($embeddingOptions & Zend_Pdf_Font::EMBED_DONT_EMBED)) {
       
   151 
       
   152             /* Second, the font author may have set copyright bits that prohibit
       
   153              * the font program from being embedded. Yes this is controversial,
       
   154              * but it's the rules:
       
   155              *   http://partners.adobe.com/public/developer/en/acrobat/sdk/FontPolicies.pdf
       
   156              *
       
   157              * To keep the developer in the loop, and to prevent surprising bug
       
   158              * reports of "your PDF doesn't have the right fonts," throw an
       
   159              * exception if the font cannot be embedded.
       
   160              */
       
   161             if (! $fontParser->isEmbeddable) {
       
   162                 /* This exception may be suppressed if the developer decides that
       
   163                  * it's not a big deal that the font program can't be embedded.
       
   164                  */
       
   165                 if (!($embeddingOptions & Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION)) {
       
   166                     $message = 'This font cannot be embedded in the PDF document. If you would like to use '
       
   167                              . 'it anyway, you must pass Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION '
       
   168                              . 'in the $options parameter of the font constructor.';
       
   169                     require_once 'Zend/Pdf/Exception.php';
       
   170                     throw new Zend_Pdf_Exception($message, Zend_Pdf_Exception::FONT_CANT_BE_EMBEDDED);
       
   171                 }
       
   172 
       
   173             } else {
       
   174                 /* Otherwise, the default behavior is to embed all custom fonts.
       
   175                  */
       
   176                 /* This section will change soon to a stream object data
       
   177                  * provider model so that we don't have to keep a copy of the
       
   178                  * entire font in memory.
       
   179                  *
       
   180                  * We also cannot build font subsetting until the data provider
       
   181                  * model is in place.
       
   182                  */
       
   183                 $fontFile = $fontParser->getDataSource()->readAllBytes();
       
   184                 $fontFileObject = $font->getFactory()->newStreamObject($fontFile);
       
   185                 $fontFileObject->dictionary->Length1 = new Zend_Pdf_Element_Numeric(strlen($fontFile));
       
   186                 if (!($embeddingOptions & Zend_Pdf_Font::EMBED_DONT_COMPRESS)) {
       
   187                     /* Compress the font file using Flate. This generally cuts file
       
   188                      * sizes by about half!
       
   189                      */
       
   190                     $fontFileObject->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode');
       
   191                 }
       
   192                 if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_Type1 /* not implemented now */) {
       
   193                     $fontDescriptor->FontFile  = $fontFileObject;
       
   194                 } else if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_TrueType) {
       
   195                     $fontDescriptor->FontFile2 = $fontFileObject;
       
   196                 } else {
       
   197                     $fontDescriptor->FontFile3 = $fontFileObject;
       
   198                 }
       
   199             }
       
   200         }
       
   201 
       
   202         return $fontDescriptor;
       
   203     }
       
   204 }