home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Text / Figlet.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  13.1 KB  |  451 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */
  4. // +----------------------------------------------------------------------+
  5. // | PHP version 4                                                        |
  6. // +----------------------------------------------------------------------+
  7. // | Copyright (c) 1997-2002 The PHP Group                                |
  8. // +----------------------------------------------------------------------+
  9. // | This source file is subject to version 2.0 of the PHP license,       |
  10. // | that is bundled with this package in the file LICENSE, and is        |
  11. // | available at through the world-wide-web at                           |
  12. // | http://www.php.net/license/2_02.txt.                                 |
  13. // | If you did not receive a copy of the PHP license and are unable to   |
  14. // | obtain it through the world-wide-web, please send a note to          |
  15. // | license@php.net so we can mail you a copy immediately.               |
  16. // +----------------------------------------------------------------------+
  17. // | Authors: Evgeny Stepanischev <se@lixil.ru>                           |
  18. // +----------------------------------------------------------------------+
  19. // Project home page (Russian): http://bolk.exler.ru/files/figlet/
  20. //
  21. // $Id: Figlet.php,v 1.1 2006/12/20 15:43:25 cweiske Exp $
  22.  
  23. require_once 'PEAR.php';
  24.  
  25. class Text_Figlet
  26. {
  27.     /**
  28.      * Height of a letter
  29.      *
  30.      * @var integer
  31.      *
  32.      * @access protected
  33.      */
  34.     var $height;
  35.  
  36.     /**
  37.      * Letter baseline
  38.      *
  39.      * @var integer
  40.      *
  41.      * @access protected
  42.      */
  43.     var $oldlayout;
  44.  
  45.     /**
  46.      * Flag - RTL (right to left) or LTR (left to right) text direction
  47.      *
  48.      * @var integer
  49.      *
  50.      * @access protected
  51.      */
  52.     var $rtol;
  53.  
  54.     /**
  55.      * Information about special 'hardblank' character
  56.      *
  57.      * @var integer
  58.      *
  59.      * @access protected
  60.      */
  61.     var $hardblank;
  62.  
  63.     /**
  64.      * Is used for keeping font
  65.      *
  66.      * @var array
  67.      *
  68.      * @access protected
  69.      */
  70.     var $font;
  71.  
  72.     /**
  73.      * Flag is true if smushing occured in letters printing cycle
  74.      *
  75.      * @var integer
  76.      *
  77.      * @access protected
  78.      */
  79.     var $smush_flag;
  80.  
  81.  
  82.  
  83.     /**
  84.      * Load user font. Must be invoked first.
  85.      * Automatically tries the Text_Figlet font data directory
  86.      *  as long as no path separator is in the filename.
  87.      *
  88.      * @param string $filename font file name
  89.      * @param bool $loadgerman (optional) load German character set or not
  90.      * @access public
  91.      * @return mixed PEAR_Error or true for success
  92.      */
  93.     function loadFont($filename, $loadgerman = true)
  94.     {
  95.         $this->font = array();
  96.         if (!file_exists($filename)) {
  97.             //if it does not exist, try the Text_Figlet data directory
  98.             require_once 'PEAR/Config.php';
  99.             $fontdir = PEAR_Config::singleton()->get('data_dir')
  100.                  . '/Text_Figlet/fonts/';
  101.             //only for filenames without path separators
  102.             if (strpos($filename, '/') === false
  103.                 && file_exists($fontdir . $filename)
  104.             ) {
  105.                 $filename = $fontdir . $filename;
  106.             } else {
  107.                 return PEAR::raiseError(
  108.                     'Figlet font file "' . $filename . '" cannot be found',
  109.                     1
  110.                 );
  111.             }
  112.         }
  113.  
  114.         // If Gzip compressed font
  115.         if (substr($filename, -3, 3) == '.gz') {
  116.             $filename   = 'compress.zlib://' . $filename;
  117.             $compressed = true;
  118.  
  119.             if (!function_exists('gzcompress')) {
  120.                 return PEAR::raiseError(
  121.                     'Cannot load gzip compressed fonts since'
  122.                     . ' gzcompress() is not available.',
  123.                     3
  124.                 );
  125.             }
  126.         } else {
  127.             $compressed = false;
  128.         }
  129.  
  130.         if (!($fp = fopen($filename, 'rb'))) {
  131.             return PEAR::raiseError('Cannot open figlet font file ' . $filename, 2);
  132.         }
  133.  
  134.  
  135.         if (!$compressed) {
  136.             flock($fp, LOCK_SH);
  137.         }
  138.  
  139. //            flf2a$ 6 5 20 15 3 0 143 229
  140. //              |  | | | |  |  | |  |   |
  141. //             /  /  | | |  |  | |  |   \
  142. //    Signature  /  /  | |  |  | |   \   Codetag_Count
  143. //      Hardblank  /  /  |  |  |  \   Full_Layout
  144. //           Height  /   |  |   \  Print_Direction
  145. //           Baseline   /    \   Comment_Lines
  146. //            Max_Length      Old_Layout
  147.  
  148.  
  149.         $header = explode(' ', fgets($fp, 2048));
  150.  
  151.         if (substr($header[0], 0, 5) <> 'flf2a') {
  152.             return PEAR::raiseError('Unknown FIGlet font format.', 4);
  153.         }
  154.  
  155.         @list ($this->hardblank, $this->height,,,
  156.         $this->oldlayout, $cmt_count, $this->rtol) = $header;
  157.  
  158.         $this->hardblank = substr($this->hardblank, -1, 1);
  159.  
  160.         for ($i = 0; $i < $cmt_count; $i++) {
  161.             fgets($fp, 2048);
  162.         }
  163.  
  164.         // ASCII charcters
  165.         for ($i = 32; $i < 127; $i++) {
  166.             $this->font[$i] = $this->_char($fp);
  167.         }
  168.  
  169.         foreach (array(91, 92, 93, 123, 124, 125, 126) as $i) {
  170.             if ($loadgerman) {
  171.                 $letter = $this->_char($fp);
  172.  
  173.                 // Invalid character but main font is loaded and I can use it
  174.                 if ($letter === false) {
  175.                     fclose($fp);
  176.                     return true;
  177.                 }
  178.  
  179.                 // Load if it is not blank only
  180.                 if (trim(implode('', $letter)) <> '')
  181.                 $this->font[$i] = $letter;
  182.             } else {
  183.                 $this->_skip($fp);
  184.             }
  185.         }
  186.  
  187.         // Extented characters
  188.         for ($n = 0; !feof($fp); $n++) {
  189.             list ($i) = explode(' ', rtrim(fgets($fp, 1024)), 2);
  190.             if ($i == '') {
  191.                 continue;
  192.             }
  193.  
  194.             // If comment
  195.             if (preg_match('/^\-0x/i', $i)) {
  196.                 $this->_skip($fp);
  197.             } else {
  198.                 // If Unicode
  199.                 if (preg_match('/^0x/i', $i)) {
  200.                     $i = hexdec(substr($i, 2));
  201.                 } else {
  202.                 // If octal
  203.                     if ($i{0} === '0' && $i !== '0' || substr($i, 0, 2) == '-0') {
  204.                         $i = octdec($i);
  205.                     }
  206.                 }
  207.  
  208.                 $letter = $this->_char($fp);
  209.  
  210.                 // Invalid character but main font is loaded and I can use it
  211.                 if ($letter === FALSE) {
  212.                     fclose($fp);
  213.                     return true;
  214.                 }
  215.  
  216.                 $this->font[$i] = $letter;
  217.             }
  218.         }
  219.  
  220.         fclose($fp);
  221.         return true;
  222.     }
  223.  
  224.  
  225.  
  226.     /**
  227.     * Print string using font loaded by LoadFont method
  228.     *
  229.     * @param string $str string for printing
  230.     * @param bool $inhtml (optional) output mode - HTML (true) or plain text (false)
  231.     * @access public
  232.     * @return string contains 
  233.     */
  234.     function lineEcho($str, $inhtml = false)
  235.     {
  236.         $out = array();
  237.  
  238.         for ($i = 0; $i<strlen($str); $i++) {
  239.             // Pseudo Unicode support
  240.             if (substr($str, $i, 2) == '%u') {
  241.                 $lt = hexdec(substr($str, $i+2, 4));
  242.                 $i += 6;
  243.             } else {
  244.                 $lt = ord($str{$i});
  245.             }
  246.  
  247.             $hb = preg_quote($this->hardblank, '/');
  248.             $sp = "$hb\\x00\\s";
  249.  
  250.             // If chosen character not found try to use default
  251.             // If default character is not defined skip it
  252.  
  253.             if (!isset($this->font[$lt])) {
  254.                 if (isset($this->font[0])) {
  255.                     $lt = 0;
  256.                 } else {
  257.                     continue;
  258.                 }
  259.             }
  260.  
  261.             for ($j = 0; $j<$this->height; $j++) {
  262.                 $line = $this->font[$lt][$j];
  263.  
  264.                 // Replace hardblanks
  265.                 if (isset($out[$j])) {
  266.                     if ($this->rtol)
  267.                     $out[$j] = $line . $out[$j]; else
  268.                     $out[$j].= $line;
  269.                 } else {
  270.                     $out[$j] = $line;
  271.                 }
  272.             }
  273.  
  274.             if ($this->oldlayout > -1 && $i) {
  275.                 // Calculate minimal distance between two last letters
  276.  
  277.                 $mindiff = -1;
  278.  
  279.                 for ($j = 0; $j<$this->height; $j++) {
  280.                     if (preg_match("/\S(\s*\\x00\s*)\S/", $out[$j], $r)) {
  281.                         $mindiff = $mindiff == -1 ? strlen($r[1]) : min($mindiff, strlen($r[1]));
  282.                     }
  283.                 }
  284.  
  285.                 // Remove spaces between two last letter
  286.                 // dec mindiff for exclude \x00 symbol
  287.  
  288.                 if (--$mindiff > 0) {
  289.                     for ($j = 0; $j<$this->height; $j++) {
  290.                         if (preg_match("/\\x00(\s{0,{$mindiff}})/", $out[$j], $r)) {
  291.                             $b = $mindiff - ($l = strlen($r[1]));
  292.                             $out[$j] = preg_replace("/\s{0,$b}\\x00\s{{$l}}/", "\0", $out[$j], 1);
  293.  
  294.                         }
  295.                     }
  296.                 }
  297.                 // Smushing
  298.  
  299.                 $this->smush_flag = 0;
  300.  
  301.                 for ($j = 0; $j<$this->height; $j++) {
  302.                     $out[$j] = 
  303.                     preg_replace_callback
  304.                     ("#([^$sp])\\x00([^$sp])#", array(&$this, '_rep'), $out[$j]);
  305.                 }
  306.  
  307.                 // Remove one space if smushing
  308.                 // and remove all \x00 except tail whenever
  309.  
  310.                 if ($this->smush_flag) {
  311.                     $pat = array("/\s\\x00(?!$)|\\x00\s/", "/\\x00(?!$)/");
  312.                     $rep = array('', '');
  313.                 } else {
  314.                     $pat = "/\\x00(?!$)/";
  315.                     $rep = '';
  316.                 }
  317.  
  318.                 for ($j = 0; $j<$this->height; $j++) {
  319.                     $out[$j] = preg_replace($pat, $rep, $out[$j]);
  320.                 }
  321.             }
  322.         }
  323.  
  324.         $trans = array("\0" => '', $this->hardblank => ' ');
  325.         $str = strtr(implode("\n", $out), $trans);
  326.  
  327.         if ($inhtml) {
  328.             return '<nobr>'.
  329.                    nl2br(str_replace(' ', ' ', htmlspecialchars($str))).
  330.                    '</nobr>';
  331.         }
  332.  
  333.         return $str;
  334.     }
  335.  
  336.  
  337.  
  338.     /**
  339.     * It is preg_replace callback function that makes horizontal letter smushing
  340.     *
  341.     * @param array $r
  342.     * @return string
  343.     * @access private
  344.     */
  345.     function _rep($r)
  346.     {
  347.         if ($this->oldlayout & 1 && $r[1] == $r[2]) {
  348.             $this->smush_flag = 1;
  349.             return $r[1];
  350.         }
  351.  
  352.         if ($this->oldlayout & 2) {
  353.             $symb = '|/\\[]{}()<>';
  354.  
  355.             if ($r[1] == '_' && strpos($symb, $r[2]) !== FALSE ||
  356.                 $r[2] == '_' && strpos($symb, $r[1]) !== FALSE) {
  357.                 $this->smush_flag = 1;
  358.                 return $r[1];
  359.             }
  360.         }
  361.  
  362.         if ($this->oldlayout & 4) {
  363.             $classes = '|/\\[]{}()<>';
  364.  
  365.             if (($left = strpos($classes, $r[1])) !== FALSE) {
  366.                 if (($right = strpos($classes, $r[2])) !== FALSE) {
  367.                     $this->smush_flag = 1;
  368.                     return $right > $left ? $r[2] : $r[1];
  369.                 }
  370.             }
  371.         }
  372.  
  373.         if ($this->oldlayout & 8) {
  374.             $t = array('[' => ']', ']' => '[', '{' => '}', '}' => '{',
  375.             '(' => ')', ')' => '(');
  376.  
  377.             if (isset($t[$r[2]]) && $r[1] == $t[$r[2]]) {
  378.                 $this->smush_flag = 1;
  379.                 return '|';
  380.             }
  381.         }
  382.  
  383.         if ($this->oldlayout & 16) {
  384.             $t = array("/\\" => '|', "\\/" => 'Y', '><' => 'X');
  385.  
  386.             if (isset($t[$r[1].$r[2]])) {
  387.                 $this->smush_flag = 1;
  388.                 return $t[$r[1].$r[2]];
  389.             }
  390.         }
  391.  
  392.         if ($this->oldlayout & 32) {
  393.             if ($r[1] == $r[2] && $r[1] == $this->hardblank) {
  394.                 $this->smush_flag = 1;
  395.                 return $this->hardblank;
  396.             }
  397.         }
  398.  
  399.         return $r[1]."\00".$r[2];
  400.     }
  401.  
  402.  
  403.  
  404.     /**
  405.     * Function loads one character in the internal array from file
  406.     *
  407.     * @param resource $fp handle of font file
  408.     * @return mixed lines of the character or false if foef occured
  409.     * @access private
  410.     */
  411.     function _char(&$fp)
  412.     {
  413.         $out = array();
  414.  
  415.         for ($i = 0; $i < $this->height; $i++) {
  416.             if (feof($fp)) {
  417.                 return false;
  418.             }
  419.  
  420.             $line = rtrim(fgets($fp, 2048), "\r\n");
  421.             if (preg_match('/(.){1,2}$/', $line, $r)) {
  422.                 $line = str_replace($r[1], '', $line);
  423.             }
  424.  
  425.             $line .= "\x00";
  426.  
  427.             $out[] = $line;
  428.         }
  429.  
  430.         return $out;
  431.     }
  432.  
  433.  
  434.  
  435.     /**
  436.     * Function for skipping one character in a font file
  437.     *
  438.     * @param resource $fp handle of font file
  439.     * @return bool always return true
  440.     * @access private
  441.     */
  442.     function _skip(&$fp)
  443.     {
  444.         for ($i = 0; $i<$this->height && !feof($fp); $i++) {
  445.             fgets($fp, 2048);
  446.         }
  447.  
  448.         return true;
  449.     }
  450. }
  451. ?>