File indexing completed on 2025-01-26 05:25:33
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Text_Figlet 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * Zend_Text_Figlet is a PHP implementation of FIGlet 0024 * 0025 * @category Zend 0026 * @package Zend_Text_Figlet 0027 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0028 * @license http://framework.zend.com/license/new-bsd New BSD License 0029 */ 0030 class Zend_Text_Figlet 0031 { 0032 /** 0033 * Smush2 layout modes 0034 */ 0035 const SM_EQUAL = 0x01; 0036 const SM_LOWLINE = 0x02; 0037 const SM_HIERARCHY = 0x04; 0038 const SM_PAIR = 0x08; 0039 const SM_BIGX = 0x10; 0040 const SM_HARDBLANK = 0x20; 0041 const SM_KERN = 0x40; 0042 const SM_SMUSH = 0x80; 0043 0044 /** 0045 * Smush mode override modes 0046 */ 0047 const SMO_NO = 0; 0048 const SMO_YES = 1; 0049 const SMO_FORCE = 2; 0050 0051 /** 0052 * Justifications 0053 */ 0054 const JUSTIFICATION_LEFT = 0; 0055 const JUSTIFICATION_CENTER = 1; 0056 const JUSTIFICATION_RIGHT = 2; 0057 0058 /** 0059 * Write directions 0060 */ 0061 const DIRECTION_LEFT_TO_RIGHT = 0; 0062 const DIRECTION_RIGHT_TO_LEFT = 1; 0063 0064 /** 0065 * Magic fontfile number 0066 */ 0067 const FONTFILE_MAGIC_NUMBER = 'flf2'; 0068 0069 /** 0070 * Array containing all characters of the current font 0071 * 0072 * @var array 0073 */ 0074 protected $_charList = array(); 0075 0076 /** 0077 * Indicates if a font was loaded yet 0078 * 0079 * @var boolean 0080 */ 0081 protected $_fontLoaded = false; 0082 0083 /** 0084 * Latin-1 codes for German letters, respectively: 0085 * 0086 * LATIN CAPITAL LETTER A WITH DIAERESIS = A-umlaut 0087 * LATIN CAPITAL LETTER O WITH DIAERESIS = O-umlaut 0088 * LATIN CAPITAL LETTER U WITH DIAERESIS = U-umlaut 0089 * LATIN SMALL LETTER A WITH DIAERESIS = a-umlaut 0090 * LATIN SMALL LETTER O WITH DIAERESIS = o-umlaut 0091 * LATIN SMALL LETTER U WITH DIAERESIS = u-umlaut 0092 * LATIN SMALL LETTER SHARP S = ess-zed 0093 * 0094 * @var array 0095 */ 0096 protected $_germanChars = array(196, 214, 220, 228, 246, 252, 223); 0097 0098 /** 0099 * Output width, defaults to 80. 0100 * 0101 * @var integer 0102 */ 0103 protected $_outputWidth = 80; 0104 0105 /** 0106 * Hard blank character 0107 * 0108 * @var string 0109 */ 0110 protected $_hardBlank; 0111 0112 /** 0113 * Height of the characters 0114 * 0115 * @var integer 0116 */ 0117 protected $_charHeight; 0118 0119 /** 0120 * Max length of any character 0121 * 0122 * @var integer 0123 */ 0124 protected $_maxLength; 0125 0126 /** 0127 * Smush mode 0128 * 0129 * @var integer 0130 */ 0131 protected $_smushMode = 0; 0132 0133 /** 0134 * Smush defined by the font 0135 * 0136 * @var integer 0137 */ 0138 protected $_fontSmush = 0; 0139 0140 /** 0141 * Smush defined by the user 0142 * 0143 * @var integer 0144 */ 0145 protected $_userSmush = 0; 0146 0147 /** 0148 * Wether to handle paragraphs || not 0149 * 0150 * @var boolean 0151 */ 0152 protected $_handleParagraphs = false; 0153 0154 /** 0155 * Justification for the text, according to $_outputWidth 0156 * 0157 * For using font default, this parameter should be null, else one of 0158 * the values of Zend_Text_Figlet::JUSTIFICATION_* 0159 * 0160 * @var integer 0161 */ 0162 protected $_justification = null; 0163 0164 /** 0165 * Direction of text-writing, namely right to left 0166 * 0167 * For using font default, this parameter should be null, else one of 0168 * the values of Zend_Text_Figlet::DIRECTION_* 0169 * 0170 * @var integer 0171 */ 0172 protected $_rightToLeft = null; 0173 0174 /** 0175 * Override font file smush layout 0176 * 0177 * @var integer 0178 */ 0179 protected $_smushOverride = 0; 0180 0181 /** 0182 * Options of the current font 0183 * 0184 * @var array 0185 */ 0186 protected $_fontOptions = array(); 0187 0188 /** 0189 * Previous character width 0190 * 0191 * @var integer 0192 */ 0193 protected $_previousCharWidth = 0; 0194 0195 /** 0196 * Current character width 0197 * 0198 * @var integer 0199 */ 0200 protected $_currentCharWidth = 0; 0201 0202 /** 0203 * Current outline length 0204 * 0205 * @var integer 0206 */ 0207 protected $_outlineLength = 0; 0208 0209 /** 0210 * Maxmimum outline length 0211 * 0212 * @var integer 0213 */ 0214 protected $_outlineLengthLimit = 0; 0215 0216 /** 0217 * In character line 0218 * 0219 * @var string 0220 */ 0221 protected $_inCharLine; 0222 0223 /** 0224 * In character line length 0225 * 0226 * @var integer 0227 */ 0228 protected $_inCharLineLength = 0; 0229 0230 /** 0231 * Maximum in character line length 0232 * 0233 * @var integer 0234 */ 0235 protected $_inCharLineLengthLimit = 0; 0236 0237 /** 0238 * Current char 0239 * 0240 * @var array 0241 */ 0242 protected $_currentChar = null; 0243 0244 /** 0245 * Current output line 0246 * 0247 * @var array 0248 */ 0249 protected $_outputLine; 0250 0251 /** 0252 * Current output 0253 * 0254 * @var string 0255 */ 0256 protected $_output; 0257 0258 /** 0259 * Option keys to skip when calling setOptions() 0260 * 0261 * @var array 0262 */ 0263 protected $_skipOptions = array( 0264 'options', 0265 'config', 0266 ); 0267 0268 /** 0269 * Instantiate the FIGlet with a specific font. If no font is given, the 0270 * standard font is used. You can also supply multiple options via 0271 * the $options variable, which can either be an array or an instance of 0272 * Zend_Config. 0273 * 0274 * @param array|Zend_Config $options Options for the output 0275 */ 0276 public function __construct($options = null) 0277 { 0278 // Set options 0279 if (is_array($options)) { 0280 $this->setOptions($options); 0281 } else if ($options instanceof Zend_Config) { 0282 $this->setConfig($options); 0283 } 0284 0285 // If no font was defined, load default font 0286 if (!$this->_fontLoaded) { 0287 $this->_loadFont(dirname(__FILE__) . '/Figlet/zend-framework.flf'); 0288 } 0289 } 0290 0291 /** 0292 * Set options from array 0293 * 0294 * @param array $options Configuration for Zend_Text_Figlet 0295 * @return Zend_Text_Figlet 0296 */ 0297 public function setOptions(array $options) 0298 { 0299 foreach ($options as $key => $value) { 0300 if (in_array(strtolower($key), $this->_skipOptions)) { 0301 continue; 0302 } 0303 0304 $method = 'set' . ucfirst($key); 0305 if (method_exists($this, $method)) { 0306 $this->$method($value); 0307 } 0308 } 0309 return $this; 0310 } 0311 0312 /** 0313 * Set options from config object 0314 * 0315 * @param Zend_Config $config Configuration for Zend_Text_Figlet 0316 * @return Zend_Text_Figlet 0317 */ 0318 public function setConfig(Zend_Config $config) 0319 { 0320 return $this->setOptions($config->toArray()); 0321 } 0322 0323 /** 0324 * Set a font to use 0325 * 0326 * @param string $font Path to the font 0327 * @return Zend_Text_Figlet 0328 */ 0329 public function setFont($font) 0330 { 0331 $this->_loadFont($font); 0332 return $this; 0333 } 0334 0335 /** 0336 * Set handling of paragraphs 0337 * 0338 * @param boolean $handleParagraphs Wether to handle paragraphs or not 0339 * @return Zend_Text_Figlet 0340 */ 0341 public function setHandleParagraphs($handleParagraphs) 0342 { 0343 $this->_handleParagraphs = (bool) $handleParagraphs; 0344 return $this; 0345 } 0346 0347 /** 0348 * Set the justification. 0 stands for left aligned, 1 for centered and 2 0349 * for right aligned. 0350 * 0351 * @param integer $justification Justification of the output text 0352 * @return Zend_Text_Figlet 0353 */ 0354 public function setJustification($justification) 0355 { 0356 $this->_justification = min(3, max(0, (int) $justification)); 0357 return $this; 0358 } 0359 0360 /** 0361 * Set the output width 0362 * 0363 * @param integer $outputWidth Output with which should be used for word 0364 * wrapping and justification 0365 * @return Zend_Text_Figlet 0366 */ 0367 public function setOutputWidth($outputWidth) 0368 { 0369 $this->_outputWidth = max(1, (int) $outputWidth); 0370 return $this; 0371 } 0372 0373 /** 0374 * Set right to left mode. For writing from left to right, use 0375 * Zend_Text_Figlet::DIRECTION_LEFT_TO_RIGHT. For writing from right to left, 0376 * use Zend_Text_Figlet::DIRECTION_RIGHT_TO_LEFT. 0377 * 0378 * @param integer $rightToLeft Right-to-left mode 0379 * @return Zend_Text_Figlet 0380 */ 0381 public function setRightToLeft($rightToLeft) 0382 { 0383 $this->_rightToLeft = min(1, max(0, (int) $rightToLeft)); 0384 return $this; 0385 } 0386 0387 /** 0388 * Set the smush mode. 0389 * 0390 * Use one of the constants of Zend_Text_Figlet::SM_*, you may combine them. 0391 * 0392 * @param integer $smushMode Smush mode to use for generating text 0393 * @return Zend_Text_Figlet 0394 */ 0395 public function setSmushMode($smushMode) 0396 { 0397 $smushMode = (int) $smushMode; 0398 0399 if ($smushMode < -1) { 0400 $this->_smushOverride = self::SMO_NO; 0401 } else { 0402 if ($smushMode === 0) { 0403 $this->_userSmush = self::SM_KERN; 0404 } else if ($smushMode === -1) { 0405 $this->_userSmush = 0; 0406 } else { 0407 $this->_userSmush = (($smushMode & 63) | self::SM_SMUSH); 0408 } 0409 0410 $this->_smushOverride = self::SMO_YES; 0411 } 0412 0413 $this->_setUsedSmush(); 0414 0415 return $this; 0416 } 0417 0418 /** 0419 * Render a FIGlet text 0420 * 0421 * @param string $text Text to convert to a figlet text 0422 * @param string $encoding Encoding of the input string 0423 * @throws InvalidArgumentException When $text is not a string 0424 * @throws Zend_Text_Figlet_Exception When $text it not properly encoded 0425 * @return string 0426 */ 0427 public function render($text, $encoding = 'UTF-8') 0428 { 0429 if (!is_string($text)) { 0430 throw new InvalidArgumentException('$text must be a string'); 0431 } 0432 0433 if ($encoding !== 'UTF-8') { 0434 $text = iconv($encoding, 'UTF-8', $text); 0435 } 0436 0437 $this->_output = ''; 0438 $this->_outputLine = array(); 0439 0440 $this->_clearLine(); 0441 0442 $this->_outlineLengthLimit = ($this->_outputWidth - 1); 0443 $this->_inCharLineLengthLimit = ($this->_outputWidth * 4 + 100); 0444 0445 $wordBreakMode = 0; 0446 $lastCharWasEol = false; 0447 $textLength = @iconv_strlen($text, 'UTF-8'); 0448 0449 if ($textLength === false) { 0450 // require_once 'Zend/Text/Figlet/Exception.php'; 0451 throw new Zend_Text_Figlet_Exception('$text is not encoded with ' . $encoding); 0452 } 0453 0454 for ($charNum = 0; $charNum < $textLength; $charNum++) { 0455 // Handle paragraphs 0456 $char = iconv_substr($text, $charNum, 1, 'UTF-8'); 0457 0458 if ($char === "\n" && $this->_handleParagraphs && !$lastCharWasEol) { 0459 $nextChar = iconv_substr($text, ($charNum + 1), 1, 'UTF-8'); 0460 if (!$nextChar) { 0461 $nextChar = null; 0462 } 0463 0464 $char = (ctype_space($nextChar)) ? "\n" : ' '; 0465 } 0466 0467 $lastCharWasEol = (ctype_space($char) && $char !== "\t" && $char !== ' '); 0468 0469 if (ctype_space($char)) { 0470 $char = ($char === "\t" || $char === ' ') ? ' ': "\n"; 0471 } 0472 0473 // Skip unprintable characters 0474 $ordChar = $this->_uniOrd($char); 0475 if (($ordChar > 0 && $ordChar < 32 && $char !== "\n") || $ordChar === 127) { 0476 continue; 0477 } 0478 0479 // Build the character 0480 // Note: The following code is complex and thoroughly tested. 0481 // Be careful when modifying! 0482 do { 0483 $charNotAdded = false; 0484 0485 if ($wordBreakMode === -1) { 0486 if ($char === ' ') { 0487 break; 0488 } else if ($char === "\n") { 0489 $wordBreakMode = 0; 0490 break; 0491 } 0492 0493 $wordBreakMode = 0; 0494 } 0495 0496 if ($char === "\n") { 0497 $this->_appendLine(); 0498 $wordBreakMode = false; 0499 } else if ($this->_addChar($char)) { 0500 if ($char !== ' ') { 0501 $wordBreakMode = ($wordBreakMode >= 2) ? 3: 1; 0502 } else { 0503 $wordBreakMode = ($wordBreakMode > 0) ? 2: 0; 0504 } 0505 } else if ($this->_outlineLength === 0) { 0506 for ($i = 0; $i < $this->_charHeight; $i++) { 0507 if ($this->_rightToLeft === 1 && $this->_outputWidth > 1) { 0508 $offset = (strlen($this->_currentChar[$i]) - $this->_outlineLengthLimit); 0509 $this->_putString(substr($this->_currentChar[$i], $offset)); 0510 } else { 0511 $this->_putString($this->_currentChar[$i]); 0512 } 0513 } 0514 0515 $wordBreakMode = -1; 0516 } else if ($char === ' ') { 0517 if ($wordBreakMode === 2) { 0518 $this->_splitLine(); 0519 } else { 0520 $this->_appendLine(); 0521 } 0522 0523 $wordBreakMode = -1; 0524 } else { 0525 if ($wordBreakMode >= 2) { 0526 $this->_splitLine(); 0527 } else { 0528 $this->_appendLine(); 0529 } 0530 0531 $wordBreakMode = ($wordBreakMode === 3) ? 1 : 0; 0532 $charNotAdded = true; 0533 } 0534 } while ($charNotAdded); 0535 } 0536 0537 if ($this->_outlineLength !== 0) { 0538 $this->_appendLine(); 0539 } 0540 0541 return $this->_output; 0542 } 0543 0544 /** 0545 * Puts the given string, substituting blanks for hardblanks. If outputWidth 0546 * is 1, puts the entire string; otherwise puts at most outputWidth - 1 0547 * characters. Puts a newline at the end of the string. The string is left- 0548 * justified, centered or right-justified (taking outputWidth as the screen 0549 * width) if justification is 0, 1 or 2 respectively. 0550 * 0551 * @param string $string The string to add to the output 0552 * @return void 0553 */ 0554 protected function _putString($string) 0555 { 0556 $length = strlen($string); 0557 0558 if ($this->_outputWidth > 1) { 0559 if ($length > ($this->_outputWidth - 1)) { 0560 $length = ($this->_outputWidth - 1); 0561 } 0562 0563 if ($this->_justification > 0) { 0564 for ($i = 1; 0565 ((3 - $this->_justification) * $i + $length + $this->_justification - 2) < $this->_outputWidth; 0566 $i++) { 0567 $this->_output .= ' '; 0568 } 0569 } 0570 } 0571 0572 $this->_output .= str_replace($this->_hardBlank, ' ', $string) . "\n"; 0573 } 0574 0575 /** 0576 * Appends the current line to the output 0577 * 0578 * @return void 0579 */ 0580 protected function _appendLine() 0581 { 0582 for ($i = 0; $i < $this->_charHeight; $i++) { 0583 $this->_putString($this->_outputLine[$i]); 0584 } 0585 0586 $this->_clearLine(); 0587 } 0588 0589 /** 0590 * Splits inCharLine at the last word break (bunch of consecutive blanks). 0591 * Makes a new line out of the first part and appends it using appendLine(). 0592 * Makes a new line out of the second part and returns. 0593 * 0594 * @return void 0595 */ 0596 protected function _splitLine() 0597 { 0598 $gotSpace = false; 0599 for ($i = ($this->_inCharLineLength - 1); $i >= 0; $i--) { 0600 if (!$gotSpace && $this->_inCharLine[$i] === ' ') { 0601 $gotSpace = true; 0602 $lastSpace = $i; 0603 } 0604 0605 if ($gotSpace && $this->_inCharLine[$i] !== ' ') { 0606 break; 0607 } 0608 } 0609 0610 $firstLength = ($i + 1); 0611 $lastLength = ($this->_inCharLineLength - $lastSpace - 1); 0612 0613 $firstPart = ''; 0614 for ($i = 0; $i < $firstLength; $i++) { 0615 $firstPart[$i] = $this->_inCharLine[$i]; 0616 } 0617 0618 $lastPart = ''; 0619 for ($i = 0; $i < $lastLength; $i++) { 0620 $lastPart[$i] = $this->_inCharLine[($lastSpace + 1 + $i)]; 0621 } 0622 0623 $this->_clearLine(); 0624 0625 for ($i = 0; $i < $firstLength; $i++) { 0626 $this->_addChar($firstPart[$i]); 0627 } 0628 0629 $this->_appendLine(); 0630 0631 for ($i = 0; $i < $lastLength; $i++) { 0632 $this->_addChar($lastPart[$i]); 0633 } 0634 } 0635 0636 /** 0637 * Clears the current line 0638 * 0639 * @return void 0640 */ 0641 protected function _clearLine() 0642 { 0643 for ($i = 0; $i < $this->_charHeight; $i++) { 0644 $this->_outputLine[$i] = ''; 0645 } 0646 0647 $this->_outlineLength = 0; 0648 $this->_inCharLineLength = 0; 0649 } 0650 0651 /** 0652 * Attempts to add the given character onto the end of the current line. 0653 * Returns true if this can be done, false otherwise. 0654 * 0655 * @param string $char Character which to add to the output 0656 * @return boolean 0657 */ 0658 protected function _addChar($char) 0659 { 0660 $this->_getLetter($char); 0661 0662 if ($this->_currentChar === null) { 0663 return true; 0664 } 0665 0666 $smushAmount = $this->_smushAmount(); 0667 0668 if (($this->_outlineLength + $this->_currentCharWidth - $smushAmount) > $this->_outlineLengthLimit 0669 || ($this->_inCharLineLength + 1) > $this->_inCharLineLengthLimit) { 0670 return false; 0671 } 0672 0673 $tempLine = ''; 0674 for ($row = 0; $row < $this->_charHeight; $row++) { 0675 if ($this->_rightToLeft === 1) { 0676 $tempLine = $this->_currentChar[$row]; 0677 0678 for ($k = 0; $k < $smushAmount; $k++) { 0679 $position = ($this->_currentCharWidth - $smushAmount + $k); 0680 $tempLine[$position] = $this->_smushem($tempLine[$position], $this->_outputLine[$row][$k]); 0681 } 0682 0683 $this->_outputLine[$row] = $tempLine . substr($this->_outputLine[$row], $smushAmount); 0684 } else { 0685 for ($k = 0; $k < $smushAmount; $k++) { 0686 if (($this->_outlineLength - $smushAmount + $k) < 0) { 0687 continue; 0688 } 0689 0690 $position = ($this->_outlineLength - $smushAmount + $k); 0691 if (isset($this->_outputLine[$row][$position])) { 0692 $leftChar = $this->_outputLine[$row][$position]; 0693 } else { 0694 $leftChar = null; 0695 } 0696 0697 $this->_outputLine[$row][$position] = $this->_smushem($leftChar, $this->_currentChar[$row][$k]); 0698 } 0699 0700 $this->_outputLine[$row] .= substr($this->_currentChar[$row], $smushAmount); 0701 } 0702 } 0703 0704 $this->_outlineLength = strlen($this->_outputLine[0]); 0705 $this->_inCharLine[$this->_inCharLineLength++] = $char; 0706 0707 return true; 0708 } 0709 0710 /** 0711 * Gets the requested character and sets current and previous char width. 0712 * 0713 * @param string $char The character from which to get the letter of 0714 * @return void 0715 */ 0716 protected function _getLetter($char) 0717 { 0718 if (array_key_exists($this->_uniOrd($char), $this->_charList)) { 0719 $this->_currentChar = $this->_charList[$this->_uniOrd($char)]; 0720 $this->_previousCharWidth = $this->_currentCharWidth; 0721 $this->_currentCharWidth = strlen($this->_currentChar[0]); 0722 } else { 0723 $this->_currentChar = null; 0724 } 0725 } 0726 0727 /** 0728 * Returns the maximum amount that the current character can be smushed into 0729 * the current line. 0730 * 0731 * @return integer 0732 */ 0733 protected function _smushAmount() 0734 { 0735 if (($this->_smushMode & (self::SM_SMUSH | self::SM_KERN)) === 0) { 0736 return 0; 0737 } 0738 0739 $maxSmush = $this->_currentCharWidth; 0740 $amount = $maxSmush; 0741 0742 for ($row = 0; $row < $this->_charHeight; $row++) { 0743 if ($this->_rightToLeft === 1) { 0744 $charbd = strlen($this->_currentChar[$row]); 0745 while (true) { 0746 if (!isset($this->_currentChar[$row][$charbd])) { 0747 $leftChar = null; 0748 } else { 0749 $leftChar = $this->_currentChar[$row][$charbd]; 0750 } 0751 0752 if ($charbd > 0 && ($leftChar === null || $leftChar == ' ')) { 0753 $charbd--; 0754 } else { 0755 break; 0756 } 0757 } 0758 0759 $linebd = 0; 0760 while (true) { 0761 if (!isset($this->_outputLine[$row][$linebd])) { 0762 $rightChar = null; 0763 } else { 0764 $rightChar = $this->_outputLine[$row][$linebd]; 0765 } 0766 0767 if ($rightChar === ' ') { 0768 $linebd++; 0769 } else { 0770 break; 0771 } 0772 } 0773 0774 $amount = ($linebd + $this->_currentCharWidth - 1 - $charbd); 0775 } else { 0776 $linebd = strlen($this->_outputLine[$row]); 0777 while (true) { 0778 if (!isset($this->_outputLine[$row][$linebd])) { 0779 $leftChar = null; 0780 } else { 0781 $leftChar = $this->_outputLine[$row][$linebd]; 0782 } 0783 0784 if ($linebd > 0 && ($leftChar === null || $leftChar == ' ')) { 0785 $linebd--; 0786 } else { 0787 break; 0788 } 0789 } 0790 0791 $charbd = 0; 0792 while (true) { 0793 if (!isset($this->_currentChar[$row][$charbd])) { 0794 $rightChar = null; 0795 } else { 0796 $rightChar = $this->_currentChar[$row][$charbd]; 0797 } 0798 0799 if ($rightChar === ' ') { 0800 $charbd++; 0801 } else { 0802 break; 0803 } 0804 } 0805 0806 $amount = ($charbd + $this->_outlineLength - 1 - $linebd); 0807 } 0808 0809 if (empty($leftChar) || $leftChar === ' ') { 0810 $amount++; 0811 } else if (!empty($rightChar)) { 0812 if ($this->_smushem($leftChar, $rightChar) !== null) { 0813 $amount++; 0814 } 0815 } 0816 0817 $maxSmush = min($amount, $maxSmush); 0818 } 0819 0820 return $maxSmush; 0821 } 0822 0823 /** 0824 * Given two characters, attempts to smush them into one, according to the 0825 * current smushmode. Returns smushed character or false if no smushing can 0826 * be done. 0827 * 0828 * Smushmode values are sum of following (all values smush blanks): 0829 * 0830 * 1: Smush equal chars (not hardblanks) 0831 * 2: Smush '_' with any char in hierarchy below 0832 * 4: hierarchy: "|", "/\", "[]", "{}", "()", "<>" 0833 * Each class in hier. can be replaced by later class. 0834 * 8: [ + ] -> |, { + } -> |, ( + ) -> | 0835 * 16: / + \ -> X, > + < -> X (only in that order) 0836 * 32: hardblank + hardblank -> hardblank 0837 * 0838 * @param string $leftChar Left character to smush 0839 * @param string $rightChar Right character to smush 0840 * @return string 0841 */ 0842 protected function _smushem($leftChar, $rightChar) 0843 { 0844 if ($leftChar === ' ') { 0845 return $rightChar; 0846 } 0847 0848 if ($rightChar === ' ') { 0849 return $leftChar; 0850 } 0851 0852 if ($this->_previousCharWidth < 2 || $this->_currentCharWidth < 2) { 0853 // Disallows overlapping if the previous character or the current 0854 // character has a width of one or zero. 0855 return null; 0856 } 0857 0858 if (($this->_smushMode & self::SM_SMUSH) === 0) { 0859 // Kerning 0860 return null; 0861 } 0862 0863 if (($this->_smushMode & 63) === 0) { 0864 // This is smushing by universal overlapping 0865 if ($leftChar === ' ') { 0866 return $rightChar; 0867 } else if ($rightChar === ' ') { 0868 return $leftChar; 0869 } else if ($leftChar === $this->_hardBlank) { 0870 return $rightChar; 0871 } else if ($rightChar === $this->_hardBlank) { 0872 return $rightChar; 0873 } else if ($this->_rightToLeft === 1) { 0874 return $leftChar; 0875 } else { 0876 // Occurs in the absence of above exceptions 0877 return $rightChar; 0878 } 0879 } 0880 0881 if (($this->_smushMode & self::SM_HARDBLANK) > 0) { 0882 if ($leftChar === $this->_hardBlank && $rightChar === $this->_hardBlank) { 0883 return $leftChar; 0884 } 0885 } 0886 0887 if ($leftChar === $this->_hardBlank && $rightChar === $this->_hardBlank) { 0888 return null; 0889 } 0890 0891 if (($this->_smushMode & self::SM_EQUAL) > 0) { 0892 if ($leftChar === $rightChar) { 0893 return $leftChar; 0894 } 0895 } 0896 0897 if (($this->_smushMode & self::SM_LOWLINE) > 0) { 0898 if ($leftChar === '_' && strchr('|/\\[]{}()<>', $rightChar) !== false) { 0899 return $rightChar; 0900 } else if ($rightChar === '_' && strchr('|/\\[]{}()<>', $leftChar) !== false) { 0901 return $leftChar; 0902 } 0903 } 0904 0905 if (($this->_smushMode & self::SM_HIERARCHY) > 0) { 0906 if ($leftChar === '|' && strchr('/\\[]{}()<>', $rightChar) !== false) { 0907 return $rightChar; 0908 } else if ($rightChar === '|' && strchr('/\\[]{}()<>', $leftChar) !== false) { 0909 return $leftChar; 0910 } else if (strchr('/\\', $leftChar) && strchr('[]{}()<>', $rightChar) !== false) { 0911 return $rightChar; 0912 } else if (strchr('/\\', $rightChar) && strchr('[]{}()<>', $leftChar) !== false) { 0913 return $leftChar; 0914 } else if (strchr('[]', $leftChar) && strchr('{}()<>', $rightChar) !== false) { 0915 return $rightChar; 0916 } else if (strchr('[]', $rightChar) && strchr('{}()<>', $leftChar) !== false) { 0917 return $leftChar; 0918 } else if (strchr('{}', $leftChar) && strchr('()<>', $rightChar) !== false) { 0919 return $rightChar; 0920 } else if (strchr('{}', $rightChar) && strchr('()<>', $leftChar) !== false) { 0921 return $leftChar; 0922 } else if (strchr('()', $leftChar) && strchr('<>', $rightChar) !== false) { 0923 return $rightChar; 0924 } else if (strchr('()', $rightChar) && strchr('<>', $leftChar) !== false) { 0925 return $leftChar; 0926 } 0927 } 0928 0929 if (($this->_smushMode & self::SM_PAIR) > 0) { 0930 if ($leftChar === '[' && $rightChar === ']') { 0931 return '|'; 0932 } else if ($rightChar === '[' && $leftChar === ']') { 0933 return '|'; 0934 } else if ($leftChar === '{' && $rightChar === '}') { 0935 return '|'; 0936 } else if ($rightChar === '{' && $leftChar === '}') { 0937 return '|'; 0938 } else if ($leftChar === '(' && $rightChar === ')') { 0939 return '|'; 0940 } else if ($rightChar === '(' && $leftChar === ')') { 0941 return '|'; 0942 } 0943 } 0944 0945 if (($this->_smushMode & self::SM_BIGX) > 0) { 0946 if ($leftChar === '/' && $rightChar === '\\') { 0947 return '|'; 0948 } else if ($rightChar === '/' && $leftChar === '\\') { 0949 return 'Y'; 0950 } else if ($leftChar === '>' && $rightChar === '<') { 0951 return 'X'; 0952 } 0953 } 0954 0955 return null; 0956 } 0957 0958 /** 0959 * Load the specified font 0960 * 0961 * @param string $fontFile Font file to load 0962 * @throws Zend_Text_Figlet_Exception When font file was not found 0963 * @throws Zend_Text_Figlet_Exception When GZIP library is required but not found 0964 * @throws Zend_Text_Figlet_Exception When font file is not readable 0965 * @return void 0966 */ 0967 protected function _loadFont($fontFile) 0968 { 0969 // Check if the font file exists 0970 if (!file_exists($fontFile)) { 0971 // require_once 'Zend/Text/Figlet/Exception.php'; 0972 throw new Zend_Text_Figlet_Exception($fontFile . ': Font file not found'); 0973 } 0974 0975 // Check if gzip support is required 0976 if (substr($fontFile, -3) === '.gz') { 0977 if (!function_exists('gzcompress')) { 0978 // require_once 'Zend/Text/Figlet/Exception.php'; 0979 throw new Zend_Text_Figlet_Exception('GZIP library is required for ' 0980 . 'gzip compressed font files'); 0981 } 0982 0983 $fontFile = 'compress.zlib://' . $fontFile; 0984 $compressed = true; 0985 } else { 0986 $compressed = false; 0987 } 0988 0989 // Try to open the file 0990 $fp = fopen($fontFile, 'rb'); 0991 if ($fp === false) { 0992 // require_once 'Zend/Text/Figlet/Exception.php'; 0993 throw new Zend_Text_Figlet_Exception($fontFile . ': Could not open file'); 0994 } 0995 0996 // If the file is not compressed, lock the stream 0997 if (!$compressed) { 0998 flock($fp, LOCK_SH); 0999 } 1000 1001 // Get magic 1002 $magic = $this->_readMagic($fp); 1003 1004 // Get the header 1005 $numsRead = sscanf(fgets($fp, 1000), 1006 '%*c%c %d %*d %d %d %d %d %d', 1007 $this->_hardBlank, 1008 $this->_charHeight, 1009 $this->_maxLength, 1010 $smush, 1011 $cmtLines, 1012 $rightToLeft, 1013 $this->_fontSmush); 1014 1015 if ($magic !== self::FONTFILE_MAGIC_NUMBER || $numsRead < 5) { 1016 // require_once 'Zend/Text/Figlet/Exception.php'; 1017 throw new Zend_Text_Figlet_Exception($fontFile . ': Not a FIGlet 2 font file'); 1018 } 1019 1020 // Set default right to left 1021 if ($numsRead < 6) { 1022 $rightToLeft = 0; 1023 } 1024 1025 // If no smush2, decode smush into smush2 1026 if ($numsRead < 7) { 1027 if ($smush === 2) { 1028 $this->_fontSmush = self::SM_KERN; 1029 } else if ($smush < 0) { 1030 $this->_fontSmush = 0; 1031 } else { 1032 $this->_fontSmush = (($smush & 31) | self::SM_SMUSH); 1033 } 1034 } 1035 1036 // Correct char height && maxlength 1037 $this->_charHeight = max(1, $this->_charHeight); 1038 $this->_maxLength = max(1, $this->_maxLength); 1039 1040 // Give ourselves some extra room 1041 $this->_maxLength += 100; 1042 1043 // See if we have to override smush settings 1044 $this->_setUsedSmush(); 1045 1046 // Get left to right value 1047 if ($this->_rightToLeft === null) { 1048 $this->_rightToLeft = $rightToLeft; 1049 } 1050 1051 // Get justification value 1052 if ($this->_justification === null) { 1053 $this->_justification = (2 * $this->_rightToLeft); 1054 } 1055 1056 // Skip all comment lines 1057 for ($line = 1; $line <= $cmtLines; $line++) { 1058 $this->_skipToEol($fp); 1059 } 1060 1061 // Fetch all ASCII characters 1062 for ($asciiCode = 32; $asciiCode < 127; $asciiCode++) { 1063 $this->_charList[$asciiCode] = $this->_loadChar($fp); 1064 } 1065 1066 // Fetch all german characters 1067 foreach ($this->_germanChars as $uniCode) { 1068 $char = $this->_loadChar($fp); 1069 1070 if ($char === false) { 1071 fclose($fp); 1072 return; 1073 } 1074 1075 if (trim(implode('', $char)) !== '') { 1076 $this->_charList[$uniCode] = $char; 1077 } 1078 } 1079 1080 // At the end fetch all extended characters 1081 while (!feof($fp)) { 1082 // Get the Unicode 1083 list($uniCode) = explode(' ', fgets($fp, 2048)); 1084 1085 if (empty($uniCode)) { 1086 continue; 1087 } 1088 1089 // Convert it if required 1090 if (substr($uniCode, 0, 2) === '0x') { 1091 $uniCode = hexdec(substr($uniCode, 2)); 1092 } else if (substr($uniCode, 0, 1) === '0' and 1093 $uniCode !== '0' or 1094 substr($uniCode, 0, 2) === '-0') { 1095 $uniCode = octdec($uniCode); 1096 } else { 1097 $uniCode = (int) $uniCode; 1098 } 1099 1100 // Now fetch the character 1101 $char = $this->_loadChar($fp); 1102 1103 if ($char === false) { 1104 fclose($fp); 1105 return; 1106 } 1107 1108 $this->_charList[$uniCode] = $char; 1109 } 1110 1111 fclose($fp); 1112 1113 $this->_fontLoaded = true; 1114 } 1115 1116 /** 1117 * Set the used smush mode, according to smush override, user smsush and 1118 * font smush. 1119 * 1120 * @return void 1121 */ 1122 protected function _setUsedSmush() 1123 { 1124 if ($this->_smushOverride === self::SMO_NO) { 1125 $this->_smushMode = $this->_fontSmush; 1126 } else if ($this->_smushOverride === self::SMO_YES) { 1127 $this->_smushMode = $this->_userSmush; 1128 } else if ($this->_smushOverride === self::SMO_FORCE) { 1129 $this->_smushMode = ($this->_fontSmush | $this->_userSmush); 1130 } 1131 } 1132 1133 /** 1134 * Reads a four-character magic string from a stream 1135 * 1136 * @param resource $fp File pointer to the font file 1137 * @return string 1138 */ 1139 protected function _readMagic($fp) 1140 { 1141 $magic = ''; 1142 1143 for ($i = 0; $i < 4; $i++) { 1144 $magic .= fgetc($fp); 1145 } 1146 1147 return $magic; 1148 } 1149 1150 /** 1151 * Skip a stream to the end of line 1152 * 1153 * @param resource $fp File pointer to the font file 1154 * @return void 1155 */ 1156 protected function _skipToEol($fp) 1157 { 1158 $dummy = fgetc($fp); 1159 while ($dummy !== false && !feof($fp)) { 1160 if ($dummy === "\n") { 1161 return; 1162 } 1163 1164 if ($dummy === "\r") { 1165 $dummy = fgetc($fp); 1166 1167 if (!feof($fp) && $dummy !== "\n") { 1168 fseek($fp, -1, SEEK_SET); 1169 } 1170 1171 return; 1172 } 1173 1174 $dummy = fgetc($fp); 1175 } 1176 } 1177 1178 /** 1179 * Load a single character from the font file 1180 * 1181 * @param resource $fp File pointer to the font file 1182 * @return array 1183 */ 1184 protected function _loadChar($fp) 1185 { 1186 $char = array(); 1187 1188 for ($i = 0; $i < $this->_charHeight; $i++) { 1189 if (feof($fp)) { 1190 return false; 1191 } 1192 1193 $line = rtrim(fgets($fp, 2048), "\r\n"); 1194 1195 if (preg_match('#(.)\\1?$#', $line, $result) === 1) { 1196 $line = str_replace($result[1], '', $line); 1197 } 1198 1199 $char[] = $line; 1200 } 1201 1202 return $char; 1203 } 1204 1205 /** 1206 * Unicode compatible ord() method 1207 * 1208 * @param string $c The char to get the value from 1209 * @return integer 1210 */ 1211 protected function _uniOrd($c) 1212 { 1213 $h = ord($c[0]); 1214 1215 if ($h <= 0x7F) { 1216 $ord = $h; 1217 } else if ($h < 0xC2) { 1218 $ord = 0; 1219 } else if ($h <= 0xDF) { 1220 $ord = (($h & 0x1F) << 6 | (ord($c[1]) & 0x3F)); 1221 } else if ($h <= 0xEF) { 1222 $ord = (($h & 0x0F) << 12 | (ord($c[1]) & 0x3F) << 6 | (ord($c[2]) & 0x3F)); 1223 } else if ($h <= 0xF4) { 1224 $ord = (($h & 0x0F) << 18 | (ord($c[1]) & 0x3F) << 12 | 1225 (ord($c[2]) & 0x3F) << 6 | (ord($c[3]) & 0x3F)); 1226 } else { 1227 $ord = 0; 1228 } 1229 1230 return $ord; 1231 } 1232 }