ANSI: Add support for more codes

Thanks chubby!
This commit is contained in:
terrafrost 2013-02-22 01:50:46 -06:00
parent 6b49b7d108
commit 1231f58aa3

View File

@ -298,12 +298,12 @@ class File_ANSI {
} }
// http://ascii-table.com/ansi-escape-sequences-vt-100.php // http://ascii-table.com/ansi-escape-sequences-vt-100.php
switch ($this->ansi) { switch ($this->ansi) {
case "\x1B[H": case "\x1B[H": // Move cursor to upper left corner
$this->old_x = $this->x; $this->old_x = $this->x;
$this->old_y = $this->y; $this->old_y = $this->y;
$this->x = $this->y = 0; $this->x = $this->y = 0;
break; break;
case "\x1B[J": case "\x1B[J": // Clear screen from cursor down
$this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y)); $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
$this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, '')); $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
@ -314,32 +314,41 @@ class File_ANSI {
array_shift($this->history); array_shift($this->history);
array_shift($this->history_attrs); array_shift($this->history_attrs);
} }
case "\x1B[K": case "\x1B[K": // Clear screen from cursor right
$this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
array_splice($this->attrs[$this->y], $this->x + 1); array_splice($this->attrs[$this->y], $this->x + 1);
break; break;
case "\x1B[2K": // Clear entire line
$this->screen[$this->y] = str_repeat(' ', $this->x);
$this->attrs[$this->y] = $this->attr_row;
break;
case "\x1B[?1h": // set cursor key to application case "\x1B[?1h": // set cursor key to application
case "\x1B[?25h": // show the cursor
break;
case "\x1BE": // Move to next line
$this->_newLine();
$this->x = 0;
break; break;
default: default:
switch (true) { switch (true) {
case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
$this->old_x = $this->x; $this->old_x = $this->x;
$this->old_y = $this->y; $this->old_y = $this->y;
$this->x = $match[2] - 1; $this->x = $match[2] - 1;
$this->y = $match[1] - 1; $this->y = $match[1] - 1;
break; break;
case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
$this->old_x = $this->x; $this->old_x = $this->x;
$x = $match[1] - 1; $x = $match[1] - 1;
break; break;
case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
break; break;
case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
$mods = explode(';', $match[1]); $mods = explode(';', $match[1]);
foreach ($mods as $mod) { foreach ($mods as $mod) {
switch ($mod) { switch ($mod) {
case 0: case 0: // Turn off character attributes
$this->attrs[$this->y][$this->x] = ''; $this->attrs[$this->y][$this->x] = '';
if ($this->bold) $this->attrs[$this->y][$this->x].= '</b>'; if ($this->bold) $this->attrs[$this->y][$this->x].= '</b>';
@ -355,25 +364,25 @@ class File_ANSI {
$this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false; $this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false;
break; break;
case 1: case 1: // Turn bold mode on
if (!$this->bold) { if (!$this->bold) {
$this->attrs[$this->y][$this->x] = '<b>'; $this->attrs[$this->y][$this->x] = '<b>';
$this->bold = true; $this->bold = true;
} }
break; break;
case 4: case 4: // Turn underline mode on
if (!$this->underline) { if (!$this->underline) {
$this->attrs[$this->y][$this->x] = '<u>'; $this->attrs[$this->y][$this->x] = '<u>';
$this->underline = true; $this->underline = true;
} }
break; break;
case 5: case 5: // Turn blinking mode on
if (!$this->blink) { if (!$this->blink) {
$this->attrs[$this->y][$this->x] = '<blink>'; $this->attrs[$this->y][$this->x] = '<blink>';
$this->blink = true; $this->blink = true;
} }
break; break;
case 7: case 7: // Turn reverse video on
$this->reverse = !$this->reverse; $this->reverse = !$this->reverse;
$temp = $this->background; $temp = $this->background;
$this->background = $this->foreground; $this->background = $this->foreground;
@ -384,7 +393,7 @@ class File_ANSI {
} }
$this->color = true; $this->color = true;
break; break;
default: default: // set colors
//$front = $this->reverse ? &$this->background : &$this->foreground; //$front = $this->reverse ? &$this->background : &$this->foreground;
$front = &$this->{ $this->reverse ? 'background' : 'foreground' }; $front = &$this->{ $this->reverse ? 'background' : 'foreground' };
//$back = $this->reverse ? &$this->foreground : &$this->background; //$back = $this->reverse ? &$this->foreground : &$this->background;
@ -436,25 +445,7 @@ class File_ANSI {
$this->x = 0; $this->x = 0;
break; break;
case "\n": case "\n":
//if ($this->y < $this->max_y) { $this->_newLine();
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
break; break;
case "\x0F": // shift case "\x0F": // shift
break; break;
@ -479,6 +470,36 @@ class File_ANSI {
} }
} }
/**
* Add a new line
*
* Also update the $this->screen and $this->history buffers
*
* @access private
*/
function _newLine()
{
//if ($this->y < $this->max_y) {
// $this->y++;
//}
while ($this->y >= $this->max_y) {
$this->history = array_merge($this->history, array(array_shift($this->screen)));
$this->screen[] = '';
$this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
$this->attrs[] = $this->attr_row;
if (count($this->history) >= $this->max_history) {
array_shift($this->history);
array_shift($this->history_attrs);
}
$this->y--;
}
$this->y++;
}
/** /**
* Returns the current screen without preformating * Returns the current screen without preformating
* *