PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Pdf/Resource/Font.php

https://bitbucket.org/luizbrandaoj/mini-blog
PHP | 530 lines | 125 code | 58 blank | 347 comment | 13 complexity | 4a20a17f8d12637ea90fd172d3034e21 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. * @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: Font.php 23775 2011-03-01 17:25:24Z ralph $
  21. */
  22. /** Zend_Pdf_Resource */
  23. require_once 'Zend/Pdf/Resource.php';
  24. /**
  25. * Zend_Pdf_Font
  26. *
  27. * Zend_Pdf_Font class constants are used within Zend_Pdf_Resource_Font
  28. * and its subclusses.
  29. */
  30. require_once 'Zend/Pdf/Font.php';
  31. /**
  32. * Abstract class which manages PDF fonts.
  33. *
  34. * Defines the public interface and creates shared storage for concrete
  35. * subclasses which are responsible for generating the font's information
  36. * dictionaries, mapping characters to glyphs, and providing both overall font
  37. * and glyph-specific metric data.
  38. *
  39. * Font objects should be normally be obtained from the factory methods
  40. * {@link Zend_Pdf_Font::fontWithName} and {@link Zend_Pdf_Font::fontWithPath}.
  41. *
  42. * @package Zend_Pdf
  43. * @subpackage Fonts
  44. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  45. * @license http://framework.zend.com/license/new-bsd New BSD License
  46. */
  47. abstract class Zend_Pdf_Resource_Font extends Zend_Pdf_Resource
  48. {
  49. /**** Instance Variables ****/
  50. /**
  51. * The type of font. Use TYPE_ constants defined in {@link Zend_Pdf_Font}.
  52. * @var integer
  53. */
  54. protected $_fontType = Zend_Pdf_Font::TYPE_UNKNOWN;
  55. /**
  56. * Array containing descriptive names for the font. See {@link fontName()}.
  57. * @var array
  58. */
  59. protected $_fontNames = array();
  60. /**
  61. * Flag indicating whether or not this font is bold.
  62. * @var boolean
  63. */
  64. protected $_isBold = false;
  65. /**
  66. * Flag indicating whether or not this font is italic.
  67. * @var boolean
  68. */
  69. protected $_isItalic = false;
  70. /**
  71. * Flag indicating whether or not this font is monospaced.
  72. * @var boolean
  73. */
  74. protected $_isMonospace = false;
  75. /**
  76. * The position below the text baseline of the underline (in glyph units).
  77. * @var integer
  78. */
  79. protected $_underlinePosition = 0;
  80. /**
  81. * The thickness of the underline (in glyph units).
  82. * @var integer
  83. */
  84. protected $_underlineThickness = 0;
  85. /**
  86. * The position above the text baseline of the strikethrough (in glyph units).
  87. * @var integer
  88. */
  89. protected $_strikePosition = 0;
  90. /**
  91. * The thickness of the strikethrough (in glyph units).
  92. * @var integer
  93. */
  94. protected $_strikeThickness = 0;
  95. /**
  96. * Number of glyph units per em. See {@link getUnitsPerEm()}.
  97. * @var integer
  98. */
  99. protected $_unitsPerEm = 0;
  100. /**
  101. * Typographical ascent. See {@link getAscent()}.
  102. * @var integer
  103. */
  104. protected $_ascent = 0;
  105. /**
  106. * Typographical descent. See {@link getDescent()}.
  107. * @var integer
  108. */
  109. protected $_descent = 0;
  110. /**
  111. * Typographical line gap. See {@link getLineGap()}.
  112. * @var integer
  113. */
  114. protected $_lineGap = 0;
  115. /**** Public Interface ****/
  116. /* Object Lifecycle */
  117. /**
  118. * Object constructor.
  119. *
  120. */
  121. public function __construct()
  122. {
  123. parent::__construct(new Zend_Pdf_Element_Dictionary());
  124. $this->_resource->Type = new Zend_Pdf_Element_Name('Font');
  125. }
  126. /* Object Magic Methods */
  127. /**
  128. * Returns the full name of the font in the encoding method of the current
  129. * locale. Transliterates any characters that cannot be naturally
  130. * represented in that character set.
  131. *
  132. * @return string
  133. */
  134. public function __toString()
  135. {
  136. return $this->getFontName(Zend_Pdf_Font::NAME_FULL, '', '//TRANSLIT');
  137. }
  138. /* Accessors */
  139. /**
  140. * Returns the type of font.
  141. *
  142. * @return integer One of the TYPE_ constants defined in
  143. * {@link Zend_Pdf_Font}.
  144. */
  145. public function getFontType()
  146. {
  147. return $this->_fontType;
  148. }
  149. /**
  150. * Returns the specified descriptive name for the font.
  151. *
  152. * The font name type is usually one of the following:
  153. * <ul>
  154. * <li>{@link Zend_Pdf_Font::NAME_FULL}
  155. * <li>{@link Zend_Pdf_Font::NAME_FAMILY}
  156. * <li>{@link Zend_Pdf_Font::NAME_PREFERRED_FAMILY}
  157. * <li>{@link Zend_Pdf_Font::NAME_STYLE}
  158. * <li>{@link Zend_Pdf_Font::NAME_PREFERRED_STYLE}
  159. * <li>{@link Zend_Pdf_Font::NAME_DESCRIPTION}
  160. * <li>{@link Zend_Pdf_Font::NAME_SAMPLE_TEXT}
  161. * <li>{@link Zend_Pdf_Font::NAME_ID}
  162. * <li>{@link Zend_Pdf_Font::NAME_VERSION}
  163. * <li>{@link Zend_Pdf_Font::NAME_POSTSCRIPT}
  164. * <li>{@link Zend_Pdf_Font::NAME_CID_NAME}
  165. * <li>{@link Zend_Pdf_Font::NAME_DESIGNER}
  166. * <li>{@link Zend_Pdf_Font::NAME_DESIGNER_URL}
  167. * <li>{@link Zend_Pdf_Font::NAME_MANUFACTURER}
  168. * <li>{@link Zend_Pdf_Font::NAME_VENDOR_URL}
  169. * <li>{@link Zend_Pdf_Font::NAME_COPYRIGHT}
  170. * <li>{@link Zend_Pdf_Font::NAME_TRADEMARK}
  171. * <li>{@link Zend_Pdf_Font::NAME_LICENSE}
  172. * <li>{@link Zend_Pdf_Font::NAME_LICENSE_URL}
  173. * </ul>
  174. *
  175. * Note that not all names are available for all fonts. In addition, some
  176. * fonts may contain additional names, whose indicies are in the range
  177. * 256 to 32767 inclusive, which are used for certain font layout features.
  178. *
  179. * If the preferred language translation is not available, uses the first
  180. * available translation for the name, which is usually English.
  181. *
  182. * If the requested name does not exist, returns null.
  183. *
  184. * All names are stored internally as Unicode strings, using UTF-16BE
  185. * encoding. You may optionally supply a different resulting character set.
  186. *
  187. * @param integer $nameType Type of name requested.
  188. * @param mixed $language Preferred language (string) or array of languages
  189. * in preferred order. Use the ISO 639 standard 2-letter language codes.
  190. * @param string $characterSet (optional) Desired resulting character set.
  191. * You may use any character set supported by {@link iconv()};
  192. * @return string
  193. */
  194. public function getFontName($nameType, $language, $characterSet = null)
  195. {
  196. if (! isset($this->_fontNames[$nameType])) {
  197. return null;
  198. }
  199. $name = null;
  200. if (is_array($language)) {
  201. foreach ($language as $code) {
  202. if (isset($this->_fontNames[$nameType][$code])) {
  203. $name = $this->_fontNames[$nameType][$code];
  204. break;
  205. }
  206. }
  207. } else {
  208. if (isset($this->_fontNames[$nameType][$language])) {
  209. $name = $this->_fontNames[$nameType][$language];
  210. }
  211. }
  212. /* If the preferred language could not be found, use whatever is first.
  213. */
  214. if ($name === null) {
  215. $names = $this->_fontNames[$nameType];
  216. $name = reset($names);
  217. }
  218. /* Convert the character set if requested.
  219. */
  220. if (($characterSet !== null) && ($characterSet != 'UTF-16BE') && PHP_OS != 'AIX') { // AIX knows not this charset
  221. $name = iconv('UTF-16BE', $characterSet, $name);
  222. }
  223. return $name;
  224. }
  225. /**
  226. * Returns whole set of font names.
  227. *
  228. * @return array
  229. */
  230. public function getFontNames()
  231. {
  232. return $this->_fontNames;
  233. }
  234. /**
  235. * Returns true if font is bold.
  236. *
  237. * @return boolean
  238. */
  239. public function isBold()
  240. {
  241. return $this->_isBold;
  242. }
  243. /**
  244. * Returns true if font is italic.
  245. *
  246. * @return boolean
  247. */
  248. public function isItalic()
  249. {
  250. return $this->_isItalic;
  251. }
  252. /**
  253. * Returns true if font is monospace.
  254. *
  255. * @return boolean
  256. */
  257. public function isMonospace()
  258. {
  259. return $this->_isMonospace;
  260. }
  261. /**
  262. * Returns the suggested position below the text baseline of the underline
  263. * in glyph units.
  264. *
  265. * This value is usually negative.
  266. *
  267. * @return integer
  268. */
  269. public function getUnderlinePosition()
  270. {
  271. return $this->_underlinePosition;
  272. }
  273. /**
  274. * Returns the suggested line thickness of the underline in glyph units.
  275. *
  276. * @return integer
  277. */
  278. public function getUnderlineThickness()
  279. {
  280. return $this->_underlineThickness;
  281. }
  282. /**
  283. * Returns the suggested position above the text baseline of the
  284. * strikethrough in glyph units.
  285. *
  286. * @return integer
  287. */
  288. public function getStrikePosition()
  289. {
  290. return $this->_strikePosition;
  291. }
  292. /**
  293. * Returns the suggested line thickness of the strikethrough in glyph units.
  294. *
  295. * @return integer
  296. */
  297. public function getStrikeThickness()
  298. {
  299. return $this->_strikeThickness;
  300. }
  301. /**
  302. * Returns the number of glyph units per em.
  303. *
  304. * Used to convert glyph space to user space. Frequently used in conjunction
  305. * with {@link widthsForGlyphs()} to calculate the with of a run of text.
  306. *
  307. * @return integer
  308. */
  309. public function getUnitsPerEm()
  310. {
  311. return $this->_unitsPerEm;
  312. }
  313. /**
  314. * Returns the typographic ascent in font glyph units.
  315. *
  316. * The typographic ascent is the distance from the font's baseline to the
  317. * top of the text frame. It is frequently used to locate the initial
  318. * baseline for a paragraph of text inside a given rectangle.
  319. *
  320. * @return integer
  321. */
  322. public function getAscent()
  323. {
  324. return $this->_ascent;
  325. }
  326. /**
  327. * Returns the typographic descent in font glyph units.
  328. *
  329. * The typographic descent is the distance below the font's baseline to the
  330. * bottom of the text frame. It is always negative.
  331. *
  332. * @return integer
  333. */
  334. public function getDescent()
  335. {
  336. return $this->_descent;
  337. }
  338. /**
  339. * Returns the typographic line gap in font glyph units.
  340. *
  341. * The typographic line gap is the distance between the bottom of the text
  342. * frame of one line to the top of the text frame of the next. It is
  343. * typically combined with the typographical ascent and descent to determine
  344. * the font's total line height (or leading).
  345. *
  346. * @return integer
  347. */
  348. public function getLineGap()
  349. {
  350. return $this->_lineGap;
  351. }
  352. /**
  353. * Returns the suggested line height (or leading) in font glyph units.
  354. *
  355. * This value is determined by adding together the values of the typographic
  356. * ascent, descent, and line gap. This value yields the suggested line
  357. * spacing as determined by the font developer.
  358. *
  359. * It should be noted that this is only a guideline; layout engines will
  360. * frequently modify this value to achieve special effects such as double-
  361. * spacing.
  362. *
  363. * @return integer
  364. */
  365. public function getLineHeight()
  366. {
  367. return $this->_ascent - $this->_descent + $this->_lineGap;
  368. }
  369. /* Information and Conversion Methods */
  370. /**
  371. * Returns an array of glyph numbers corresponding to the Unicode characters.
  372. *
  373. * If a particular character doesn't exist in this font, the special 'missing
  374. * character glyph' will be substituted.
  375. *
  376. * See also {@link glyphNumberForCharacter()}.
  377. *
  378. * @param array $characterCodes Array of Unicode character codes (code points).
  379. * @return array Array of glyph numbers.
  380. */
  381. abstract public function glyphNumbersForCharacters($characterCodes);
  382. /**
  383. * Returns the glyph number corresponding to the Unicode character.
  384. *
  385. * If a particular character doesn't exist in this font, the special 'missing
  386. * character glyph' will be substituted.
  387. *
  388. * See also {@link glyphNumbersForCharacters()} which is optimized for bulk
  389. * operations.
  390. *
  391. * @param integer $characterCode Unicode character code (code point).
  392. * @return integer Glyph number.
  393. */
  394. abstract public function glyphNumberForCharacter($characterCode);
  395. /**
  396. * Returns a number between 0 and 1 inclusive that indicates the percentage
  397. * of characters in the string which are covered by glyphs in this font.
  398. *
  399. * Since no one font will contain glyphs for the entire Unicode character
  400. * range, this method can be used to help locate a suitable font when the
  401. * actual contents of the string are not known.
  402. *
  403. * Note that some fonts lie about the characters they support. Additionally,
  404. * fonts don't usually contain glyphs for control characters such as tabs
  405. * and line breaks, so it is rare that you will get back a full 1.0 score.
  406. * The resulting value should be considered informational only.
  407. *
  408. * @param string $string
  409. * @param string $charEncoding (optional) Character encoding of source text.
  410. * If omitted, uses 'current locale'.
  411. * @return float
  412. */
  413. abstract public function getCoveredPercentage($string, $charEncoding = '');
  414. /**
  415. * Returns the widths of the glyphs.
  416. *
  417. * The widths are expressed in the font's glyph space. You are responsible
  418. * for converting to user space as necessary. See {@link unitsPerEm()}.
  419. *
  420. * See also {@link widthForGlyph()}.
  421. *
  422. * @param array $glyphNumbers Array of glyph numbers.
  423. * @return array Array of glyph widths (integers).
  424. * @throws Zend_Pdf_Exception
  425. */
  426. abstract public function widthsForGlyphs($glyphNumbers);
  427. /**
  428. * Returns the width of the glyph.
  429. *
  430. * Like {@link widthsForGlyphs()} but used for one glyph at a time.
  431. *
  432. * @param integer $glyphNumber
  433. * @return integer
  434. * @throws Zend_Pdf_Exception
  435. */
  436. abstract public function widthForGlyph($glyphNumber);
  437. /**
  438. * Convert string to the font encoding.
  439. *
  440. * The method is used to prepare string for text drawing operators
  441. *
  442. * @param string $string
  443. * @param string $charEncoding Character encoding of source text.
  444. * @return string
  445. */
  446. abstract public function encodeString($string, $charEncoding);
  447. /**
  448. * Convert string from the font encoding.
  449. *
  450. * The method is used to convert strings retrieved from existing content streams
  451. *
  452. * @param string $string
  453. * @param string $charEncoding Character encoding of resulting text.
  454. * @return string
  455. */
  456. abstract public function decodeString($string, $charEncoding);
  457. /**** Internal Methods ****/
  458. /**
  459. * If the font's glyph space is not 1000 units per em, converts the value.
  460. *
  461. * @internal
  462. * @param integer $value
  463. * @return integer
  464. */
  465. public function toEmSpace($value)
  466. {
  467. if ($this->_unitsPerEm == 1000) {
  468. return $value;
  469. }
  470. return ceil(($value / $this->_unitsPerEm) * 1000); // always round up
  471. }
  472. }