File indexing completed on 2025-01-19 05:21:23
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 0024 /** Internally used classes */ 0025 // require_once 'Zend/Pdf/Element/Array.php'; 0026 // require_once 'Zend/Pdf/Element/Dictionary.php'; 0027 // require_once 'Zend/Pdf/Element/Name.php'; 0028 // require_once 'Zend/Pdf/Element/Numeric.php'; 0029 0030 /** Zend_Pdf_Font */ 0031 // require_once 'Zend/Pdf/Font.php'; 0032 0033 0034 /** 0035 * FontDescriptor implementation 0036 * 0037 * A font descriptor specifies metrics and other attributes of a simple font or a 0038 * CIDFont as a whole, as distinct from the metrics of individual glyphs. These font 0039 * metrics provide information that enables a viewer application to synthesize a 0040 * substitute font or select a similar font when the font program is unavailable. The 0041 * font descriptor may also be used to embed the font program in the PDF file. 0042 * 0043 * @package Zend_Pdf 0044 * @subpackage Fonts 0045 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0046 * @license http://framework.zend.com/license/new-bsd New BSD License 0047 */ 0048 class Zend_Pdf_Resource_Font_FontDescriptor 0049 { 0050 /** 0051 * Object constructor 0052 * @throws Zend_Pdf_Exception 0053 */ 0054 public function __construct() 0055 { 0056 // require_once 'Zend/Pdf/Exception.php'; 0057 throw new Zend_Pdf_Exception('Zend_Pdf_Resource_Font_FontDescriptor is not intended to be instantiated'); 0058 } 0059 0060 /** 0061 * Object constructor 0062 * 0063 * The $embeddingOptions parameter allows you to set certain flags related 0064 * to font embedding. You may combine options by OR-ing them together. See 0065 * the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of 0066 * available options and their descriptions. 0067 * 0068 * Note that it is not requried that fonts be embedded within the PDF file 0069 * to use them. If the recipient of the PDF has the font installed on their 0070 * computer, they will see the correct fonts in the document. If they don't, 0071 * the PDF viewer will substitute or synthesize a replacement. 0072 * 0073 * 0074 * @param Zend_Pdf_Resource_Font $font Font 0075 * @param Zend_Pdf_FileParser_Font_OpenType $fontParser Font parser object containing parsed TrueType file. 0076 * @param integer $embeddingOptions Options for font embedding. 0077 * @return Zend_Pdf_Element_Dictionary 0078 * @throws Zend_Pdf_Exception 0079 */ 0080 static public function factory(Zend_Pdf_Resource_Font $font, Zend_Pdf_FileParser_Font_OpenType $fontParser, $embeddingOptions) 0081 { 0082 /* The font descriptor object contains the rest of the font metrics and 0083 * the information about the embedded font program (if applicible). 0084 */ 0085 $fontDescriptor = new Zend_Pdf_Element_Dictionary(); 0086 0087 $fontDescriptor->Type = new Zend_Pdf_Element_Name('FontDescriptor'); 0088 $fontDescriptor->FontName = new Zend_Pdf_Element_Name($font->getResource()->BaseFont->value); 0089 0090 /* The font flags value is a bitfield that describes the stylistic 0091 * attributes of the font. We will set as many of the bits as can be 0092 * determined from the font parser. 0093 */ 0094 $flags = 0; 0095 if ($fontParser->isMonospaced) { // bit 1: FixedPitch 0096 $flags |= 1 << 0; 0097 } 0098 if ($fontParser->isSerifFont) { // bit 2: Serif 0099 $flags |= 1 << 1; 0100 } 0101 if (! $fontParser->isAdobeLatinSubset) { // bit 3: Symbolic 0102 $flags |= 1 << 2; 0103 } 0104 if ($fontParser->isScriptFont) { // bit 4: Script 0105 $flags |= 1 << 3; 0106 } 0107 if ($fontParser->isAdobeLatinSubset) { // bit 6: Nonsymbolic 0108 $flags |= 1 << 5; 0109 } 0110 if ($fontParser->isItalic) { // bit 7: Italic 0111 $flags |= 1 << 6; 0112 } 0113 // bits 17-19: AllCap, SmallCap, ForceBold; not available 0114 $fontDescriptor->Flags = new Zend_Pdf_Element_Numeric($flags); 0115 0116 $fontBBox = array(new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->xMin)), 0117 new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->yMin)), 0118 new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->xMax)), 0119 new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->yMax))); 0120 $fontDescriptor->FontBBox = new Zend_Pdf_Element_Array($fontBBox); 0121 0122 $fontDescriptor->ItalicAngle = new Zend_Pdf_Element_Numeric($fontParser->italicAngle); 0123 0124 $fontDescriptor->Ascent = new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->ascent)); 0125 $fontDescriptor->Descent = new Zend_Pdf_Element_Numeric($font->toEmSpace($fontParser->descent)); 0126 0127 $fontDescriptor->CapHeight = new Zend_Pdf_Element_Numeric($fontParser->capitalHeight); 0128 /** 0129 * The vertical stem width is not yet extracted from the OpenType font 0130 * file. For now, record zero which is interpreted as 'unknown'. 0131 * @todo Calculate value for StemV. 0132 */ 0133 $fontDescriptor->StemV = new Zend_Pdf_Element_Numeric(0); 0134 0135 $fontDescriptor->MissingWidth = new Zend_Pdf_Element_Numeric($fontParser->glyphWidths[0]); 0136 0137 /* Set up font embedding. This is where the actual font program itself 0138 * is embedded within the PDF document. 0139 * 0140 * Note that it is not requried that fonts be embedded within the PDF 0141 * document to use them. If the recipient of the PDF has the font 0142 * installed on their computer, they will see the correct fonts in the 0143 * document. If they don't, the PDF viewer will substitute or synthesize 0144 * a replacement. 0145 * 0146 * There are several guidelines for font embedding: 0147 * 0148 * First, the developer might specifically request not to embed the font. 0149 */ 0150 if (!($embeddingOptions & Zend_Pdf_Font::EMBED_DONT_EMBED)) { 0151 0152 /* Second, the font author may have set copyright bits that prohibit 0153 * the font program from being embedded. Yes this is controversial, 0154 * but it's the rules: 0155 * http://partners.adobe.com/public/developer/en/acrobat/sdk/FontPolicies.pdf 0156 * 0157 * To keep the developer in the loop, and to prevent surprising bug 0158 * reports of "your PDF doesn't have the right fonts," throw an 0159 * exception if the font cannot be embedded. 0160 */ 0161 if (! $fontParser->isEmbeddable) { 0162 /* This exception may be suppressed if the developer decides that 0163 * it's not a big deal that the font program can't be embedded. 0164 */ 0165 if (!($embeddingOptions & Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION)) { 0166 $message = 'This font cannot be embedded in the PDF document. If you would like to use ' 0167 . 'it anyway, you must pass Zend_Pdf_Font::EMBED_SUPPRESS_EMBED_EXCEPTION ' 0168 . 'in the $options parameter of the font constructor.'; 0169 // require_once 'Zend/Pdf/Exception.php'; 0170 throw new Zend_Pdf_Exception($message, Zend_Pdf_Exception::FONT_CANT_BE_EMBEDDED); 0171 } 0172 0173 } else { 0174 /* Otherwise, the default behavior is to embed all custom fonts. 0175 */ 0176 /* This section will change soon to a stream object data 0177 * provider model so that we don't have to keep a copy of the 0178 * entire font in memory. 0179 * 0180 * We also cannot build font subsetting until the data provider 0181 * model is in place. 0182 */ 0183 $fontFile = $fontParser->getDataSource()->readAllBytes(); 0184 $fontFileObject = $font->getFactory()->newStreamObject($fontFile); 0185 $fontFileObject->dictionary->Length1 = new Zend_Pdf_Element_Numeric(strlen($fontFile)); 0186 if (!($embeddingOptions & Zend_Pdf_Font::EMBED_DONT_COMPRESS)) { 0187 /* Compress the font file using Flate. This generally cuts file 0188 * sizes by about half! 0189 */ 0190 $fontFileObject->dictionary->Filter = new Zend_Pdf_Element_Name('FlateDecode'); 0191 } 0192 if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_Type1 /* not implemented now */) { 0193 $fontDescriptor->FontFile = $fontFileObject; 0194 } else if ($fontParser instanceof Zend_Pdf_FileParser_Font_OpenType_TrueType) { 0195 $fontDescriptor->FontFile2 = $fontFileObject; 0196 } else { 0197 $fontDescriptor->FontFile3 = $fontFileObject; 0198 } 0199 } 0200 } 0201 0202 return $fontDescriptor; 0203 } 0204 }