You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
9.2 KiB

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