PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Pdf/Font.php

https://bitbucket.org/baruffaldi/cms-php-bfcms
PHP | 775 lines | 207 code | 158 blank | 410 comment | 13 complexity | f5bdc9285a419bf14fb202cd73dd22d8 MD5 | raw file
  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. * @package Zend_Pdf
  16. * @subpackage Fonts
  17. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. /** Zend_Pdf_FileParserDataSource */
  21. require_once 'Zend/Pdf/FileParserDataSource.php';
  22. /** Zend_Pdf_FileParserDataSource_File */
  23. require_once 'Zend/Pdf/FileParserDataSource/File.php';
  24. /** Zend_Pdf_FileParserDataSource_String */
  25. require_once 'Zend/Pdf/FileParserDataSource/String.php';
  26. /** Zend_Pdf_FileParser_Font_OpenType_TrueType */
  27. require_once 'Zend/Pdf/FileParser/Font/OpenType/TrueType.php';
  28. /** Zend_Pdf_Resource_Font_Simple_Parsed_TrueType */
  29. require_once 'Zend/Pdf/Resource/Font/Simple/Parsed/TrueType.php';
  30. /** Zend_Pdf_Resource_Font_Type0 */
  31. require_once 'Zend/Pdf/Resource/Font/Type0.php';
  32. /** Zend_Pdf_Resource_Font_CidFont_TrueType */
  33. require_once 'Zend/Pdf/Resource/Font/CidFont/TrueType.php';
  34. /** Zend_Pdf_Resource_Font_Simple_Standard_Courier */
  35. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Courier.php';
  36. /** Zend_Pdf_Resource_Font_Simple_Standard_CourierBold */
  37. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierBold.php';
  38. /** Zend_Pdf_Resource_Font_Simple_Standard_CourierBoldOblique */
  39. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierBoldOblique.php';
  40. /** Zend_Pdf_Resource_Font_Simple_Standard_CourierOblique */
  41. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/CourierOblique.php';
  42. /** Zend_Pdf_Resource_Font_Simple_Standard_Helvetica */
  43. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Helvetica.php';
  44. /** Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBold */
  45. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBold.php';
  46. /** Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBoldOblique */
  47. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaBoldOblique.php';
  48. /** Zend_Pdf_Resource_Font_Simple_Standard_HelveticaOblique */
  49. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/HelveticaOblique.php';
  50. /** Zend_Pdf_Resource_Font_Simple_Standard_Symbol */
  51. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/Symbol.php';
  52. /** Zend_Pdf_Resource_Font_Simple_Standard_TimesBold */
  53. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesBold.php';
  54. /** Zend_Pdf_Resource_Font_Simple_Standard_TimesBoldItalic */
  55. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesBoldItalic.php';
  56. /** Zend_Pdf_Resource_Font_Simple_Standard_TimesItalic */
  57. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesItalic.php';
  58. /** Zend_Pdf_Resource_Font_Simple_Standard_TimesRoman */
  59. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/TimesRoman.php';
  60. /** Zend_Pdf_Resource_Font_Simple_Standard_ZapfDingbats */
  61. require_once 'Zend/Pdf/Resource/Font/Simple/Standard/ZapfDingbats.php';
  62. /** Zend_Pdf_Resource_Font_Extracted */
  63. require_once 'Zend/Pdf/Resource/Font/Extracted.php';
  64. /**
  65. * Abstract factory class which vends {@link Zend_Pdf_Resource_Font} objects.
  66. *
  67. * Font objects themselves are normally instantiated through the factory methods
  68. * {@link fontWithName()} or {@link fontWithPath()}.
  69. *
  70. * This class is also the home for font-related constants because the name of
  71. * the true base class ({@link Zend_Pdf_Resource_Font}) is not intuitive for the
  72. * end user.
  73. *
  74. * @package Zend_Pdf
  75. * @subpackage Fonts
  76. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  77. * @license http://framework.zend.com/license/new-bsd New BSD License
  78. */
  79. abstract class Zend_Pdf_Font
  80. {
  81. /**** Class Constants ****/
  82. /* Font Types */
  83. /**
  84. * Unknown font type.
  85. */
  86. const TYPE_UNKNOWN = 0;
  87. /**
  88. * One of the standard 14 PDF fonts.
  89. */
  90. const TYPE_STANDARD = 1;
  91. /**
  92. * A PostScript Type 1 font.
  93. */
  94. const TYPE_TYPE_1 = 2;
  95. /**
  96. * A TrueType font or an OpenType font containing TrueType outlines.
  97. */
  98. const TYPE_TRUETYPE = 3;
  99. /**
  100. * Type 0 composite font.
  101. */
  102. const TYPE_TYPE_0 = 4;
  103. /**
  104. * CID font containing a PostScript Type 1 font.
  105. * These fonts are used only to construct Type 0 composite fonts and can't be used directly
  106. */
  107. const TYPE_CIDFONT_TYPE_0 = 5;
  108. /**
  109. * CID font containing a TrueType font or an OpenType font containing TrueType outlines.
  110. * These fonts are used only to construct Type 0 composite fonts and can't be used directly
  111. */
  112. const TYPE_CIDFONT_TYPE_2 = 6;
  113. /* Names of the Standard 14 PDF Fonts */
  114. /**
  115. * Name of the standard PDF font Courier.
  116. */
  117. const FONT_COURIER = 'Courier';
  118. /**
  119. * Name of the bold style of the standard PDF font Courier.
  120. */
  121. const FONT_COURIER_BOLD = 'Courier-Bold';
  122. /**
  123. * Name of the italic style of the standard PDF font Courier.
  124. */
  125. const FONT_COURIER_OBLIQUE = 'Courier-Oblique';
  126. /**
  127. * Convenience constant for a common misspelling of
  128. * {@link FONT_COURIER_OBLIQUE}.
  129. */
  130. const FONT_COURIER_ITALIC = 'Courier-Oblique';
  131. /**
  132. * Name of the bold and italic style of the standard PDF font Courier.
  133. */
  134. const FONT_COURIER_BOLD_OBLIQUE = 'Courier-BoldOblique';
  135. /**
  136. * Convenience constant for a common misspelling of
  137. * {@link FONT_COURIER_BOLD_OBLIQUE}.
  138. */
  139. const FONT_COURIER_BOLD_ITALIC = 'Courier-BoldOblique';
  140. /**
  141. * Name of the standard PDF font Helvetica.
  142. */
  143. const FONT_HELVETICA = 'Helvetica';
  144. /**
  145. * Name of the bold style of the standard PDF font Helvetica.
  146. */
  147. const FONT_HELVETICA_BOLD = 'Helvetica-Bold';
  148. /**
  149. * Name of the italic style of the standard PDF font Helvetica.
  150. */
  151. const FONT_HELVETICA_OBLIQUE = 'Helvetica-Oblique';
  152. /**
  153. * Convenience constant for a common misspelling of
  154. * {@link FONT_HELVETICA_OBLIQUE}.
  155. */
  156. const FONT_HELVETICA_ITALIC = 'Helvetica-Oblique';
  157. /**
  158. * Name of the bold and italic style of the standard PDF font Helvetica.
  159. */
  160. const FONT_HELVETICA_BOLD_OBLIQUE = 'Helvetica-BoldOblique';
  161. /**
  162. * Convenience constant for a common misspelling of
  163. * {@link FONT_HELVETICA_BOLD_OBLIQUE}.
  164. */
  165. const FONT_HELVETICA_BOLD_ITALIC = 'Helvetica-BoldOblique';
  166. /**
  167. * Name of the standard PDF font Symbol.
  168. */
  169. const FONT_SYMBOL = 'Symbol';
  170. /**
  171. * Name of the standard PDF font Times.
  172. */
  173. const FONT_TIMES_ROMAN = 'Times-Roman';
  174. /**
  175. * Convenience constant for a common misspelling of
  176. * {@link FONT_TIMES_ROMAN}.
  177. */
  178. const FONT_TIMES = 'Times-Roman';
  179. /**
  180. * Name of the bold style of the standard PDF font Times.
  181. */
  182. const FONT_TIMES_BOLD = 'Times-Bold';
  183. /**
  184. * Name of the italic style of the standard PDF font Times.
  185. */
  186. const FONT_TIMES_ITALIC = 'Times-Italic';
  187. /**
  188. * Name of the bold and italic style of the standard PDF font Times.
  189. */
  190. const FONT_TIMES_BOLD_ITALIC = 'Times-BoldItalic';
  191. /**
  192. * Name of the standard PDF font Zapf Dingbats.
  193. */
  194. const FONT_ZAPFDINGBATS = 'ZapfDingbats';
  195. /* Font Name String Types */
  196. /**
  197. * Full copyright notice for the font.
  198. */
  199. const NAME_COPYRIGHT = 0;
  200. /**
  201. * Font family name. Used to group similar styles of fonts together.
  202. */
  203. const NAME_FAMILY = 1;
  204. /**
  205. * Font style within the font family. Examples: Regular, Italic, Bold, etc.
  206. */
  207. const NAME_STYLE = 2;
  208. /**
  209. * Unique font identifier.
  210. */
  211. const NAME_ID = 3;
  212. /**
  213. * Full font name. Usually a combination of the {@link NAME_FAMILY} and
  214. * {@link NAME_STYLE} strings.
  215. */
  216. const NAME_FULL = 4;
  217. /**
  218. * Version number of the font.
  219. */
  220. const NAME_VERSION = 5;
  221. /**
  222. * PostScript name for the font. This is the name used to identify fonts
  223. * internally and within the PDF file.
  224. */
  225. const NAME_POSTSCRIPT = 6;
  226. /**
  227. * Font trademark notice. This is distinct from the {@link NAME_COPYRIGHT}.
  228. */
  229. const NAME_TRADEMARK = 7;
  230. /**
  231. * Name of the font manufacturer.
  232. */
  233. const NAME_MANUFACTURER = 8;
  234. /**
  235. * Name of the designer of the font.
  236. */
  237. const NAME_DESIGNER = 9;
  238. /**
  239. * Description of the font. May contain revision information, usage
  240. * recommendations, features, etc.
  241. */
  242. const NAME_DESCRIPTION = 10;
  243. /**
  244. * URL of the font vendor. Some fonts may contain a unique serial number
  245. * embedded in this URL, which is used for licensing.
  246. */
  247. const NAME_VENDOR_URL = 11;
  248. /**
  249. * URL of the font designer ({@link NAME_DESIGNER}).
  250. */
  251. const NAME_DESIGNER_URL = 12;
  252. /**
  253. * Plain language licensing terms for the font.
  254. */
  255. const NAME_LICENSE = 13;
  256. /**
  257. * URL of more detailed licensing information for the font.
  258. */
  259. const NAME_LICENSE_URL = 14;
  260. /**
  261. * Preferred font family. Used by some fonts to work around a Microsoft
  262. * Windows limitation where only four fonts styles can share the same
  263. * {@link NAME_FAMILY} value.
  264. */
  265. const NAME_PREFERRED_FAMILY = 16;
  266. /**
  267. * Preferred font style. A more descriptive string than {@link NAME_STYLE}.
  268. */
  269. const NAME_PREFERRED_STYLE = 17;
  270. /**
  271. * Suggested text to use as a representative sample of the font.
  272. */
  273. const NAME_SAMPLE_TEXT = 19;
  274. /**
  275. * PostScript CID findfont name.
  276. */
  277. const NAME_CID_NAME = 20;
  278. /* Font Weights */
  279. /**
  280. * Thin font weight.
  281. */
  282. const WEIGHT_THIN = 100;
  283. /**
  284. * Extra-light (Ultra-light) font weight.
  285. */
  286. const WEIGHT_EXTRA_LIGHT = 200;
  287. /**
  288. * Light font weight.
  289. */
  290. const WEIGHT_LIGHT = 300;
  291. /**
  292. * Normal (Regular) font weight.
  293. */
  294. const WEIGHT_NORMAL = 400;
  295. /**
  296. * Medium font weight.
  297. */
  298. const WEIGHT_MEDIUM = 500;
  299. /**
  300. * Semi-bold (Demi-bold) font weight.
  301. */
  302. const WEIGHT_SEMI_BOLD = 600;
  303. /**
  304. * Bold font weight.
  305. */
  306. const WEIGHT_BOLD = 700;
  307. /**
  308. * Extra-bold (Ultra-bold) font weight.
  309. */
  310. const WEIGHT_EXTRA_BOLD = 800;
  311. /**
  312. * Black (Heavy) font weight.
  313. */
  314. const WEIGHT_BLACK = 900;
  315. /* Font Widths */
  316. /**
  317. * Ultra-condensed font width. Typically 50% of normal.
  318. */
  319. const WIDTH_ULTRA_CONDENSED = 1;
  320. /**
  321. * Extra-condensed font width. Typically 62.5% of normal.
  322. */
  323. const WIDTH_EXTRA_CONDENSED = 2;
  324. /**
  325. * Condensed font width. Typically 75% of normal.
  326. */
  327. const WIDTH_CONDENSED = 3;
  328. /**
  329. * Semi-condensed font width. Typically 87.5% of normal.
  330. */
  331. const WIDTH_SEMI_CONDENSED = 4;
  332. /**
  333. * Normal (Medium) font width.
  334. */
  335. const WIDTH_NORMAL = 5;
  336. /**
  337. * Semi-expanded font width. Typically 112.5% of normal.
  338. */
  339. const WIDTH_SEMI_EXPANDED = 6;
  340. /**
  341. * Expanded font width. Typically 125% of normal.
  342. */
  343. const WIDTH_EXPANDED = 7;
  344. /**
  345. * Extra-expanded font width. Typically 150% of normal.
  346. */
  347. const WIDTH_EXTRA_EXPANDED = 8;
  348. /**
  349. * Ultra-expanded font width. Typically 200% of normal.
  350. */
  351. const WIDTH_ULTRA_EXPANDED = 9;
  352. /* Font Embedding Options */
  353. /**
  354. * Do not embed the font in the PDF document.
  355. */
  356. const EMBED_DONT_EMBED = 0x01;
  357. /**
  358. * Embed, but do not subset the font in the PDF document.
  359. */
  360. const EMBED_DONT_SUBSET = 0x02;
  361. /**
  362. * Embed, but do not compress the font in the PDF document.
  363. */
  364. const EMBED_DONT_COMPRESS = 0x04;
  365. /**
  366. * Suppress the exception normally thrown if the font cannot be embedded
  367. * due to its copyright bits being set.
  368. */
  369. const EMBED_SUPPRESS_EMBED_EXCEPTION = 0x08;
  370. /**** Class Variables ****/
  371. /**
  372. * Array whose keys are the unique PostScript names of instantiated fonts.
  373. * The values are the font objects themselves.
  374. * @var array
  375. */
  376. private static $_fontNames = array();
  377. /**
  378. * Array whose keys are the md5 hash of the full paths on disk for parsed
  379. * fonts. The values are the font objects themselves.
  380. * @var array
  381. */
  382. private static $_fontFilePaths = array();
  383. /**** Public Interface ****/
  384. /* Factory Methods */
  385. /**
  386. * Returns a {@link Zend_Pdf_Resource_Font} object by full name.
  387. *
  388. * This is the preferred method to obtain one of the standard 14 PDF fonts.
  389. *
  390. * The result of this method is cached, preventing unnecessary duplication
  391. * of font objects. Repetitive calls for a font with the same name will
  392. * return the same object.
  393. *
  394. * The $embeddingOptions parameter allows you to set certain flags related
  395. * to font embedding. You may combine options by OR-ing them together. See
  396. * the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of
  397. * available options and their descriptions. Note that this value is only
  398. * used when creating a font for the first time. If a font with the same
  399. * name already exists, you will get that object and the options you specify
  400. * here will be ignored. This is because fonts are only embedded within the
  401. * PDF file once.
  402. *
  403. * If the font name supplied does not match the name of a previously
  404. * instantiated object and it is not one of the 14 standard PDF fonts, an
  405. * exception will be thrown.
  406. *
  407. * @param string $name Full PostScript name of font.
  408. * @param integer $embeddingOptions (optional) Options for font embedding.
  409. * @return Zend_Pdf_Resource_Font
  410. * @throws Zend_Pdf_Exception
  411. */
  412. public static function fontWithName($name, $embeddingOptions = 0)
  413. {
  414. /* First check the cache. Don't duplicate font objects.
  415. */
  416. if (isset(Zend_Pdf_Font::$_fontNames[$name])) {
  417. return Zend_Pdf_Font::$_fontNames[$name];
  418. }
  419. /**
  420. * @todo It would be cool to be able to have a mapping of font names to
  421. * file paths in a configuration file for frequently used custom
  422. * fonts. This would allow a user to use custom fonts without having
  423. * to hard-code file paths all over the place. Table this idea until
  424. * {@link Zend_Config} is ready.
  425. */
  426. /* Not an existing font and no mapping in the config file. Check to see
  427. * if this is one of the standard 14 PDF fonts.
  428. */
  429. switch ($name) {
  430. case Zend_Pdf_Font::FONT_COURIER:
  431. $font = new Zend_Pdf_Resource_Font_Simple_Standard_Courier();
  432. break;
  433. case Zend_Pdf_Font::FONT_COURIER_BOLD:
  434. $font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierBold();
  435. break;
  436. case Zend_Pdf_Font::FONT_COURIER_OBLIQUE:
  437. $font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierOblique();
  438. break;
  439. case Zend_Pdf_Font::FONT_COURIER_BOLD_OBLIQUE:
  440. $font = new Zend_Pdf_Resource_Font_Simple_Standard_CourierBoldOblique();
  441. break;
  442. case Zend_Pdf_Font::FONT_HELVETICA:
  443. $font = new Zend_Pdf_Resource_Font_Simple_Standard_Helvetica();
  444. break;
  445. case Zend_Pdf_Font::FONT_HELVETICA_BOLD:
  446. $font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBold();
  447. break;
  448. case Zend_Pdf_Font::FONT_HELVETICA_OBLIQUE:
  449. $font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaOblique();
  450. break;
  451. case Zend_Pdf_Font::FONT_HELVETICA_BOLD_OBLIQUE:
  452. $font = new Zend_Pdf_Resource_Font_Simple_Standard_HelveticaBoldOblique();
  453. break;
  454. case Zend_Pdf_Font::FONT_SYMBOL:
  455. $font = new Zend_Pdf_Resource_Font_Simple_Standard_Symbol();
  456. break;
  457. case Zend_Pdf_Font::FONT_TIMES_ROMAN:
  458. $font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesRoman();
  459. break;
  460. case Zend_Pdf_Font::FONT_TIMES_BOLD:
  461. $font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesBold();
  462. break;
  463. case Zend_Pdf_Font::FONT_TIMES_ITALIC:
  464. $font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesItalic();
  465. break;
  466. case Zend_Pdf_Font::FONT_TIMES_BOLD_ITALIC:
  467. $font = new Zend_Pdf_Resource_Font_Simple_Standard_TimesBoldItalic();
  468. break;
  469. case Zend_Pdf_Font::FONT_ZAPFDINGBATS:
  470. $font = new Zend_Pdf_Resource_Font_Simple_Standard_ZapfDingbats();
  471. break;
  472. default:
  473. throw new Zend_Pdf_Exception("Unknown font name: $name",
  474. Zend_Pdf_Exception::BAD_FONT_NAME);
  475. }
  476. /* Add this new font to the cache array and return it for use.
  477. */
  478. Zend_Pdf_Font::$_fontNames[$name] = $font;
  479. return $font;
  480. }
  481. /**
  482. * Returns a {@link Zend_Pdf_Resource_Font} object by file path.
  483. *
  484. * The result of this method is cached, preventing unnecessary duplication
  485. * of font objects. Repetitive calls for the font with the same path will
  486. * return the same object.
  487. *
  488. * The $embeddingOptions parameter allows you to set certain flags related
  489. * to font embedding. You may combine options by OR-ing them together. See
  490. * the EMBED_ constants defined in {@link Zend_Pdf_Font} for the list of
  491. * available options and their descriptions. Note that this value is only
  492. * used when creating a font for the first time. If a font with the same
  493. * name already exists, you will get that object and the options you specify
  494. * here will be ignored. This is because fonts are only embedded within the
  495. * PDF file once.
  496. *
  497. * If the file path supplied does not match the path of a previously
  498. * instantiated object or the font type cannot be determined, an exception
  499. * will be thrown.
  500. *
  501. * @param string $filePath Full path to the font file.
  502. * @param integer $embeddingOptions (optional) Options for font embedding.
  503. * @return Zend_Pdf_Resource_Font
  504. * @throws Zend_Pdf_Exception
  505. */
  506. public static function fontWithPath($filePath, $embeddingOptions = 0)
  507. {
  508. /* First check the cache. Don't duplicate font objects.
  509. */
  510. $filePathKey = md5($filePath);
  511. if (isset(Zend_Pdf_Font::$_fontFilePaths[$filePathKey])) {
  512. return Zend_Pdf_Font::$_fontFilePaths[$filePathKey];
  513. }
  514. /* Create a file parser data source object for this file. File path and
  515. * access permission checks are handled here.
  516. */
  517. $dataSource = new Zend_Pdf_FileParserDataSource_File($filePath);
  518. /* Attempt to determine the type of font. We can't always trust file
  519. * extensions, but try that first since it's fastest.
  520. */
  521. $fileExtension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
  522. /* If it turns out that the file is named improperly and we guess the
  523. * wrong type, we'll get null instead of a font object.
  524. */
  525. switch ($fileExtension) {
  526. case 'ttf':
  527. $font = Zend_Pdf_Font::_extractTrueTypeFont($dataSource, $embeddingOptions);
  528. break;
  529. default:
  530. /* Unrecognized extension. Try to determine the type by actually
  531. * parsing it below.
  532. */
  533. $font = null;
  534. break;
  535. }
  536. if (is_null($font)) {
  537. /* There was no match for the file extension or the extension was
  538. * wrong. Attempt to detect the type of font by actually parsing it.
  539. * We'll do the checks in order of most likely format to try to
  540. * reduce the detection time.
  541. */
  542. // OpenType
  543. // TrueType
  544. if ((is_null($font)) && ($fileExtension != 'ttf')) {
  545. $font = Zend_Pdf_Font::_extractTrueTypeFont($dataSource, $embeddingOptions);
  546. }
  547. // Type 1 PostScript
  548. // Mac OS X dfont
  549. // others?
  550. }
  551. /* Done with the data source object.
  552. */
  553. $dataSource = null;
  554. if (! is_null($font)) {
  555. /* Parsing was successful. Add this font instance to the cache arrays
  556. * and return it for use.
  557. */
  558. $fontName = $font->getFontName(Zend_Pdf_Font::NAME_POSTSCRIPT, '', '');
  559. Zend_Pdf_Font::$_fontNames[$fontName] = $font;
  560. $filePathKey = md5($filePath);
  561. Zend_Pdf_Font::$_fontFilePaths[$filePathKey] = $font;
  562. return $font;
  563. } else {
  564. /* The type of font could not be determined. Give up.
  565. */
  566. throw new Zend_Pdf_Exception("Cannot determine font type: $filePath",
  567. Zend_Pdf_Exception::CANT_DETERMINE_FONT_TYPE);
  568. }
  569. }
  570. /**** Internal Methods ****/
  571. /* Font Extraction Methods */
  572. /**
  573. * Attempts to extract a TrueType font from the data source.
  574. *
  575. * If the font parser throws an exception that suggests the data source
  576. * simply doesn't contain a TrueType font, catches it and returns null. If
  577. * an exception is thrown that suggests the TrueType font is corrupt or
  578. * otherwise unusable, throws that exception. If successful, returns the
  579. * font object.
  580. *
  581. * @param Zend_Pdf_FileParserDataSource $dataSource
  582. * @param integer $embeddingOptions Options for font embedding.
  583. * @return Zend_Pdf_Resource_Font_OpenType_TrueType May also return null if
  584. * the data source does not appear to contain a TrueType font.
  585. * @throws Zend_Pdf_Exception
  586. */
  587. protected static function _extractTrueTypeFont($dataSource, $embeddingOptions)
  588. {
  589. try {
  590. $fontParser = new Zend_Pdf_FileParser_Font_OpenType_TrueType($dataSource);
  591. $fontParser->parse();
  592. if ($fontParser->isAdobeLatinSubset) {
  593. $font = new Zend_Pdf_Resource_Font_Simple_Parsed_TrueType($fontParser, $embeddingOptions);
  594. } else {
  595. /* Use Composite Type 0 font which supports Unicode character mapping */
  596. $cidFont = new Zend_Pdf_Resource_Font_CidFont_TrueType($fontParser, $embeddingOptions);
  597. $font = new Zend_Pdf_Resource_Font_Type0($cidFont);
  598. }
  599. } catch (Zend_Pdf_Exception $exception) {
  600. /* The following exception codes suggest that this isn't really a
  601. * TrueType font. If we caught such an exception, simply return
  602. * null. For all other cases, it probably is a TrueType font but has
  603. * a problem; throw the exception again.
  604. */
  605. $fontParser = null;
  606. switch ($exception->getCode()) {
  607. case Zend_Pdf_Exception::WRONG_FONT_TYPE: // break intentionally omitted
  608. case Zend_Pdf_Exception::BAD_TABLE_COUNT: // break intentionally omitted
  609. case Zend_Pdf_Exception::BAD_MAGIC_NUMBER:
  610. return null;
  611. default:
  612. throw $exception;
  613. }
  614. }
  615. return $font;
  616. }
  617. }