/zf/library/Zend/Pdf/Resource/Font/FontDescriptor.php
PHP | 204 lines | 77 code | 17 blank | 110 comment | 15 complexity | 6456e3fccc39d93e4fe51bace876c74b MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
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-2011 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 23775 2011-03-01 17:25:24Z ralph $ 21 */ 22 23 24/** Internally used classes */ 25require_once 'Zend/Pdf/Element/Array.php'; 26require_once 'Zend/Pdf/Element/Dictionary.php'; 27require_once 'Zend/Pdf/Element/Name.php'; 28require_once 'Zend/Pdf/Element/Numeric.php'; 29 30/** Zend_Pdf_Font */ 31require_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-2011 Zend Technologies USA Inc. (http://www.zend.com) 46 * @license http://framework.zend.com/license/new-bsd New BSD License 47 */ 48class 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}