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