Fix Page::class and rendering
This commit is contained in:
parent
02a3963a12
commit
9f0fa0a8ec
@ -7,10 +7,6 @@ use Illuminate\Support\Collection;
|
|||||||
|
|
||||||
class Font
|
class Font
|
||||||
{
|
{
|
||||||
private const DEBUG = FALSE;
|
|
||||||
|
|
||||||
protected const MSG_WIDTH = 79;
|
|
||||||
|
|
||||||
private string $text = '';
|
private string $text = '';
|
||||||
private int $width = 0;
|
private int $width = 0;
|
||||||
private int $height = 0;
|
private int $height = 0;
|
||||||
@ -31,6 +27,7 @@ class Font
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Message text, goes after header, and if a logo, to the right of it
|
* Message text, goes after header, and if a logo, to the right of it
|
||||||
|
* @note Text can have color codes added: eg: ANSI::ansi_code([1,37])."text"
|
||||||
*
|
*
|
||||||
* @param string $text
|
* @param string $text
|
||||||
*/
|
*/
|
||||||
@ -132,75 +129,6 @@ class Font
|
|||||||
return $result.($ansi ? ANSI::ansi_color(0x0e) : '');
|
return $result.($ansi ? ANSI::ansi_color(0x0e) : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This function will format text to static::MSG_WIDTH, as well as adding the logo.
|
|
||||||
* It is up to the text to be spaced appropriately to wrap around the icon.
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
* @param ANSI|null $logo
|
|
||||||
* @param bool $right
|
|
||||||
* @param int $step
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function format_msg(string $text,ANSI $logo=NULL,int $step=1,bool $right=FALSE): string
|
|
||||||
{
|
|
||||||
$result = '';
|
|
||||||
$result_height = 0;
|
|
||||||
$current_pos = 0;
|
|
||||||
|
|
||||||
while ($current_pos < strlen($text)) {
|
|
||||||
$result_line = ''; // Line being created
|
|
||||||
$lc = 0; // Line length count (without ANSI)
|
|
||||||
|
|
||||||
$buffer = $step ? $logo->width->skip(intdiv($result_height,$step)*$step)->take($step)->max() : 1;
|
|
||||||
|
|
||||||
// Add our logo
|
|
||||||
if ($result_height <= $logo->height-1) {
|
|
||||||
$line = ANSI::bin_to_ansi([$logo->line($result_height)],FALSE);
|
|
||||||
$lc = $logo->line_width($logo->line_raw($result_height),FALSE);
|
|
||||||
$result_line = str_repeat(' ',ANSI::LOGO_OFFSET_WIDTH)
|
|
||||||
.$line
|
|
||||||
.str_repeat(' ',ANSI::LOGO_BUFFER_WIDTH+($right ? 0 : $buffer-$lc));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for a return
|
|
||||||
$return_pos = strpos($text,"\r",$current_pos);
|
|
||||||
|
|
||||||
// We have a return
|
|
||||||
if ($return_pos !== FALSE) {
|
|
||||||
$subtext = substr($text,$current_pos,$return_pos-$current_pos);
|
|
||||||
|
|
||||||
// If the reset of the string will fit on the current line
|
|
||||||
} elseif (strlen($text)-$current_pos < static::MSG_WIDTH-$lc) {
|
|
||||||
$subtext = substr($text,$current_pos);
|
|
||||||
|
|
||||||
// Get the next lines worth of chars
|
|
||||||
} else {
|
|
||||||
$subtext = substr($text,$current_pos,static::MSG_WIDTH-$buffer);
|
|
||||||
|
|
||||||
// Include the text up to the last space
|
|
||||||
if (substr($text,$current_pos+strlen($subtext),1) !== ' ')
|
|
||||||
$subtext = substr($text,$current_pos,strrpos($subtext,' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
$result .= $result_line.
|
|
||||||
str_repeat(' ',($right ? static::MSG_WIDTH-$lc-strlen($subtext)+((! $lc) ? (ANSI::LOGO_OFFSET_WIDTH+ANSI::LOGO_BUFFER_WIDTH) : 0) : 0))
|
|
||||||
.$subtext."\r\n";
|
|
||||||
$current_pos += strlen($subtext)+1;
|
|
||||||
$result_height++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In case our text is shorter than the logo
|
|
||||||
for (;$result_height<$logo->height;$result_height++) {
|
|
||||||
$result .= str_repeat(' ',ANSI::LOGO_OFFSET_WIDTH)
|
|
||||||
.ANSI::bin_to_ansi([$logo->line($result_height)],FALSE)
|
|
||||||
.str_repeat(' ',ANSI::LOGO_BUFFER_WIDTH)
|
|
||||||
."\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The height of this font (based on the 1st char)
|
* The height of this font (based on the 1st char)
|
||||||
*
|
*
|
||||||
@ -210,171 +138,4 @@ class Font
|
|||||||
{
|
{
|
||||||
return count(Arr::get(static::FONT,'a'));
|
return count(Arr::get(static::FONT,'a'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert text into a graphical font
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
* @param Collection $width
|
|
||||||
* @param int $height
|
|
||||||
* @param int $step
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function fontText(string $text,Collection $width,int $height,int $step): string
|
|
||||||
{
|
|
||||||
return self::text_to_font($text,$width,$height,$step);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert text to this font
|
|
||||||
* This function will pad the text to fit around the icon, so that the icon+font fils to self::MSG_WIDTH
|
|
||||||
*
|
|
||||||
* @param string $text
|
|
||||||
* @param Collection $icon_width Width to make the font
|
|
||||||
* @param int $icon_height Minimal width for this height, then full width (self::MSG_WIDTH)
|
|
||||||
* @param int $step The grouping of lines (normally font height) around the icon
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected static function text_to_font(string $text,Collection $icon_width,int $icon_height,int $step): string
|
|
||||||
{
|
|
||||||
$chars = collect(); // Characters needed for this $text
|
|
||||||
$font_height = 0; // Max height of text using font
|
|
||||||
|
|
||||||
// Trim any leading/trailing spaces
|
|
||||||
$text = trim(strtolower($text));
|
|
||||||
|
|
||||||
// Work out the characters we need
|
|
||||||
foreach (array_unique(str_split($text)) as $c) {
|
|
||||||
if (($c === ' ') || (! $x=Arr::get(static::FONT,$c))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$chars->put($c,$x);
|
|
||||||
$font_height = (($y=count($x)) > $font_height) ? $y : $font_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self::DEBUG) dump(['uniquechars'=>$chars->count(),'font_height'=>$font_height]);
|
|
||||||
if (self::DEBUG) dump(['drawing'=>$text,'textlen'=>strlen($text),'logo_width'=>$icon_width,'logo_height'=>$icon_height]);
|
|
||||||
|
|
||||||
$result = ''; // Our result
|
|
||||||
$current_pos = 0; // Our current position through $text
|
|
||||||
$result_height = 0; // Our current line height
|
|
||||||
$line_pos = 0; // Our current character position for this line of the font
|
|
||||||
|
|
||||||
while ($current_pos < strlen($text)) {
|
|
||||||
if (self::DEBUG) dump(sprintf('current position %d of %d',$current_pos,strlen($text)));
|
|
||||||
|
|
||||||
for ($line=0;$line<$font_height;$line++) {
|
|
||||||
if ($line === 0) {
|
|
||||||
$line_icon_width = $icon_width
|
|
||||||
->skip(intdiv($result_height,$step)*$step)
|
|
||||||
->take($step)
|
|
||||||
->max();
|
|
||||||
|
|
||||||
if ($line_icon_width)
|
|
||||||
$line_icon_width += ANSI::LOGO_OFFSET_WIDTH+ANSI::LOGO_BUFFER_WIDTH;
|
|
||||||
|
|
||||||
$line_width = self::MSG_WIDTH-$line_icon_width; // Width we are working towards, initially $icon_width until height then its self::MSG_WIDTH
|
|
||||||
}
|
|
||||||
|
|
||||||
$line_result = ''; // Our current line of font
|
|
||||||
if (self::DEBUG) dump(sprintf('- current line %d of %d',$line+1,$font_height));
|
|
||||||
|
|
||||||
// If we are mid way through rendering a font, and have already finished with the height offset, we'll need to fill with blanks
|
|
||||||
if (($line_width !== self::MSG_WIDTH) && ($result_height > $icon_height-1))
|
|
||||||
$line_result .= str_repeat(' ',$line_icon_width);
|
|
||||||
|
|
||||||
$line_pos = $current_pos;
|
|
||||||
$next_space_pos = $current_pos;
|
|
||||||
$next_next_space_width = 0; // What our width will be after the next next space
|
|
||||||
$next_next_space_pos = 0; // The position of the next space after the next one
|
|
||||||
$next_next_space_chars = 0; // The number of chars between the next space and the next next space
|
|
||||||
$current_line_width = 0; // Our current width of the line
|
|
||||||
|
|
||||||
while ($current_line_width < $line_width) {
|
|
||||||
if (self::DEBUG) dump(sprintf(' - current width %d of %d, and we are working on char %d',$current_line_width,$line_width,$line_pos));
|
|
||||||
$find_space_pos = $line_pos;
|
|
||||||
|
|
||||||
// Find our next char
|
|
||||||
if (self::DEBUG) dump(sprintf(' - find our next space from %d after %d',$find_space_pos,$next_space_pos));
|
|
||||||
|
|
||||||
$next_space_chars = 0;
|
|
||||||
if ($next_space_pos <= $line_pos) {
|
|
||||||
if (! $next_next_space_pos) {
|
|
||||||
while (($find_space_pos < strlen($text)) && (($c=substr($text,$find_space_pos++,1)) !== ' ')) {
|
|
||||||
$x = count(Arr::get($chars->get($c),$line));
|
|
||||||
if (self::DEBUG) dump(sprintf(' + char is [%s] (%x) and will take %d chars',$c,ord($c),$x));
|
|
||||||
$next_space_chars += $x;
|
|
||||||
}
|
|
||||||
|
|
||||||
$next_space_pos = $find_space_pos;
|
|
||||||
$next_next_space_pos = $find_space_pos;
|
|
||||||
$next_next_space_width = $current_line_width+$next_space_chars;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$next_space_pos = $next_next_space_pos;
|
|
||||||
$next_space_chars = $next_next_space_chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find our next next space, which we'll use to decide whether we need to include a space when we find one
|
|
||||||
$next_next_space_chars = 0;
|
|
||||||
while (($next_next_space_pos < strlen($text)) && (($c=substr($text,$next_next_space_pos++,1)) !== ' ')) {
|
|
||||||
$next_next_space_chars += count(Arr::get($chars->get($c),$line,[]));
|
|
||||||
if (self::DEBUG) dump(sprintf(' + char is [%s] (%x) and will take us to %d',$c,ord($c),$next_next_space_chars));
|
|
||||||
}
|
|
||||||
|
|
||||||
$next_next_space_width = $current_line_width+$next_space_chars+$next_next_space_chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self::DEBUG)
|
|
||||||
dump(sprintf(' - our next space is: [%s] (%x) at %d in %d chars, taking %d chars (taking our width to %d)',$c,ord($c),$find_space_pos,$find_space_pos-$line_pos,$next_space_chars,$current_line_width+$next_space_chars));
|
|
||||||
|
|
||||||
// We are only spaces, so we can return to the next line
|
|
||||||
if ($current_line_width+$next_space_chars > $line_width) {
|
|
||||||
if (self::DEBUG) dump(' = next char should go onto new line');
|
|
||||||
|
|
||||||
// Only go to a new line if we already have chars
|
|
||||||
if ($current_line_width)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$c = substr($text,$line_pos,1);
|
|
||||||
if (($c === ' ') || (! $font_chars=$chars->get($c))) {
|
|
||||||
// Ignore this space if we are at the beginning of the line
|
|
||||||
if ($current_line_width && ($next_next_space_width < $line_width)) {
|
|
||||||
$line_result .= $c;
|
|
||||||
$current_line_width++;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (self::DEBUG) dump(sprintf('adding char [%s] which is [%s]',$c,join('|',Arr::get($font_chars,$line))));
|
|
||||||
|
|
||||||
foreach ($x=Arr::get($font_chars,$line) as $char)
|
|
||||||
$line_result .= chr($char);
|
|
||||||
|
|
||||||
$current_line_width += count($x);
|
|
||||||
}
|
|
||||||
|
|
||||||
$line_pos++;
|
|
||||||
if (self::DEBUG) dump(sprintf(' = line width [%d of %d] and we are on char [%d] our space is [%d]',$current_line_width,$line_width,$line_pos,$find_space_pos));
|
|
||||||
|
|
||||||
if ($line_pos === strlen($text)) {
|
|
||||||
if (self::DEBUG) dump(sprintf(' = we are finished, as we are on char %d on line %d',$line_pos,$line));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$result_height++;
|
|
||||||
$result .= $line_result."\r";
|
|
||||||
}
|
|
||||||
|
|
||||||
$current_pos = $line_pos;
|
|
||||||
if (self::DEBUG) dump(sprintf('= new line starting with char [%d] - our width is [%d] and we are on line [%d]',$current_pos,$line_width,$result_height));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self::DEBUG)
|
|
||||||
dd(['result'=>$result]);
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -14,45 +14,111 @@ use Illuminate\Support\Arr;
|
|||||||
*/
|
*/
|
||||||
class Page
|
class Page
|
||||||
{
|
{
|
||||||
protected const MSG_WIDTH = 78;
|
// If false, no debug, if null, show padding, if true, show debug
|
||||||
|
private ?bool $DEBUG = NULL;
|
||||||
|
|
||||||
|
/** @var int Max width of message */
|
||||||
|
public const MSG_WIDTH = 78;
|
||||||
|
/** @var int Chars to add between logo and header/text */
|
||||||
private const LOGO_OFFSET_WIDTH = 1;
|
private const LOGO_OFFSET_WIDTH = 1;
|
||||||
|
|
||||||
|
/** @var bool Do we add an "\n" when rendering */
|
||||||
|
private bool $crlf;
|
||||||
|
/** @var Font Our header text */
|
||||||
private Font $header;
|
private Font $header;
|
||||||
|
/** @var string Text to go below the header */
|
||||||
private string $header_foot = '';
|
private string $header_foot = '';
|
||||||
|
/** @var bool If the header will be right aligned */
|
||||||
private bool $header_right;
|
private bool $header_right;
|
||||||
|
/** @var int Character to show after the header + header_footer */
|
||||||
private int $header_underline = 0;
|
private int $header_underline = 0;
|
||||||
|
|
||||||
|
/** @var Font Left box content, that goes below the logo */
|
||||||
private Font $left_box;
|
private Font $left_box;
|
||||||
|
/** @var bool If there is no logo, should the left box start below the header */
|
||||||
|
private bool $left_box_below_header = FALSE;
|
||||||
|
|
||||||
|
/** @var ANSI ANSI logo to display */
|
||||||
private ANSI $logo;
|
private ANSI $logo;
|
||||||
private int $step = 0;
|
/** @var int Buffer of chars between logo/left box and text, 0 means retain max width */
|
||||||
|
private int $step;
|
||||||
|
|
||||||
|
/** @var int The current cursor position when rendering */
|
||||||
|
private int $x;
|
||||||
|
/** @var int The current line when rendering */
|
||||||
|
private int $y;
|
||||||
|
|
||||||
|
private const MAX_LEFTBOX_WIDTH = 28;
|
||||||
|
|
||||||
private string $text = '';
|
private string $text = '';
|
||||||
private bool $text_right = FALSE;
|
private bool $text_right = FALSE;
|
||||||
|
|
||||||
public function __construct(bool $crlf=FALSE)
|
public function __construct(bool $crlf=FALSE,?bool $debug=FALSE)
|
||||||
{
|
{
|
||||||
$this->header = new Font;
|
$this->header = new Font;
|
||||||
$this->logo = new ANSI;
|
$this->logo = new ANSI;
|
||||||
$this->left_box = new Font;
|
$this->left_box = new Font;
|
||||||
|
|
||||||
$this->crlf = $crlf;
|
$this->crlf = $crlf;
|
||||||
$this->text = '';
|
$this->DEBUG = $debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __get($key)
|
public function __get($key)
|
||||||
{
|
{
|
||||||
switch ($key) {
|
switch ($key) {
|
||||||
|
// Total height of the header, including footer+underline
|
||||||
|
case 'drawing_header':
|
||||||
|
return $this->y < $this->header_height;
|
||||||
|
|
||||||
|
case 'drawing_headcontent':
|
||||||
|
return $this->y < $this->header->height;
|
||||||
|
|
||||||
|
case 'drawing_headfoot':
|
||||||
|
//return ($this->y < $this->header_height) && $this->header_foot;
|
||||||
|
return ($this->y === $this->header->height) && $this->header_foot;
|
||||||
|
|
||||||
|
case 'drawing_headunderline':
|
||||||
|
return ($this->y === $this->header->height+($this->header_foot ? 1:0)) && $this->header_underline;
|
||||||
|
|
||||||
|
case 'drawing_leftbox':
|
||||||
|
return ($this->y >= $this->left_box_start) && ($this->y < $this->left_box_start+$this->left_box->height) && (! $this->drawing_logo);
|
||||||
|
|
||||||
|
case 'drawing_logo':
|
||||||
|
return $this->y < $this->logo->height;
|
||||||
|
|
||||||
// Height of the header
|
// Height of the header
|
||||||
case 'header_height':
|
case 'header_height':
|
||||||
return $this->header->height+($this->header_foot ? 1 : 0)+($this->header_underline ? 1 : 0);
|
return max($this->left_box_below_header ? 0 : $this->left_box->height+self::LOGO_OFFSET_WIDTH,$this->header->height+($this->header_foot ? 1 : 0)+($this->header_underline ? 1 : 0));
|
||||||
|
|
||||||
|
// Our header width
|
||||||
|
case 'header_width':
|
||||||
|
return max($this->header->width,strlen($this->header_foot));
|
||||||
|
|
||||||
// The width of the left column
|
// The width of the left column
|
||||||
case 'left_width':
|
case 'left_width':
|
||||||
return $this->logo->width->max() ?: $this->left_box->width;
|
return max($this->logo->width->max(),$this->left_box->width) + self::LOGO_OFFSET_WIDTH*2;
|
||||||
|
|
||||||
// The height of the left column
|
// The height of the left column
|
||||||
case 'left_height':
|
case 'left_height':
|
||||||
return $this->logo->height+$this->left_box->height+self::LOGO_OFFSET_WIDTH;
|
if ($this->left_box->height && $this->left_box_below_header) {
|
||||||
|
// If the logo is smaller than the header, then its the height header+left box
|
||||||
|
// Otherwise its the height of the logo+spacer+left box height+space
|
||||||
|
if ($this->logo->height < $this->header_height) {
|
||||||
|
return $this->header_height+$this->left_box->height + self::LOGO_OFFSET_WIDTH;
|
||||||
|
} else {
|
||||||
|
return $this->logo->height + self::LOGO_OFFSET_WIDTH + $this->left_box->height + self::LOGO_OFFSET_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
return ($this->logo->height ? $this->logo->height+self::LOGO_OFFSET_WIDTH : 0) + ($this->left_box->height ? $this->left_box->height+self::LOGO_OFFSET_WIDTH : 0);
|
||||||
|
|
||||||
|
case 'left_box_start':
|
||||||
|
if ($this->left_box_below_header) {
|
||||||
|
return max($this->logo->height+self::LOGO_OFFSET_WIDTH,$this->header_height);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return max(($this->logo->height ? $this->logo->height+self::LOGO_OFFSET_WIDTH : 0),0);
|
||||||
|
}
|
||||||
|
|
||||||
// The right width
|
// The right width
|
||||||
case 'right_width':
|
case 'right_width':
|
||||||
@ -87,14 +153,16 @@ class Page
|
|||||||
* Content that can go below logo, to the left of the text, if text $logo_left_border is TRUE
|
* Content that can go below logo, to the left of the text, if text $logo_left_border is TRUE
|
||||||
*
|
*
|
||||||
* @param Font $text
|
* @param Font $text
|
||||||
|
* @param bool $below_header
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function addLeftBoxContent(Font $text): void
|
public function addLeftBoxContent(Font $text,bool $below_header=TRUE): void
|
||||||
{
|
{
|
||||||
if ($this->left_width && ($text->width > $this->left_width))
|
if ($text->width > self::MAX_LEFTBOX_WIDTH)
|
||||||
throw new \Exception(sprintf('Leftbox content greater than icon width'));
|
throw new \Exception(sprintf('Leftbox content greater than %d',self::MAX_LEFTBOX_WIDTH));
|
||||||
|
|
||||||
$this->left_box = $text;
|
$this->left_box = $text;
|
||||||
|
$this->left_box_below_header = $below_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,100 +196,137 @@ class Page
|
|||||||
*/
|
*/
|
||||||
public function render(): string
|
public function render(): string
|
||||||
{
|
{
|
||||||
$result = '';
|
$this->x = 0;
|
||||||
$result_height = 0;
|
$this->y = 0;
|
||||||
$current_pos = 0;
|
$result = ''; // The output
|
||||||
$text_length = strlen($this->text);
|
|
||||||
$this->step = 0; // @todo temp
|
$current_pos = 0; // Current position of the text being rendered
|
||||||
$text_current_color = NULL;
|
$text_length = strlen($this->text); // Length of text we need to place in the message
|
||||||
|
$this->step = 0; // If step is 0, our left_width is fixed until the end of the left_height,
|
||||||
|
// otherwise, its a buffer of chars between the left item and the text
|
||||||
|
$text_current_color = NULL; // Current text color
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
$result_line = ''; // Line being created
|
$result_line = ''; // Line being created
|
||||||
$lc = 0; // Line length count (without ANSI control codes)
|
|
||||||
|
|
||||||
// The buffer represents how many spaces need to pad between the left_width and whatever is drawn on the left
|
|
||||||
if (! $this->step) {
|
|
||||||
if (($this->left_height > $this->header_height) || ($result_height < $this->header_height-1))
|
|
||||||
$buffer = $this->left_width+($this->left_width ? self::LOGO_OFFSET_WIDTH*2 : 0);
|
|
||||||
else
|
|
||||||
$buffer = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$buffer = 0;
|
|
||||||
/*
|
/*
|
||||||
// @todo
|
// The buffer represents how many spaces need to pad between the left_width and whatever is drawn on the left
|
||||||
$buffer = $this->step
|
if ($this->step) {
|
||||||
? $this->logo->width->skip(intdiv($result_height,$this->step)*$this->step)->take($this->step)->max()
|
// If we have a logo + left text box, then the min width is the max width of the left text box, until after we pass the max width
|
||||||
: 1;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->left_width) {
|
// If we only have a logo and a header, we step after the header
|
||||||
// Add our logo
|
|
||||||
if ($result_height < $this->logo->height) {
|
|
||||||
$line = ANSI::bin_to_ansi([$this->logo->line($result_height)],FALSE);
|
|
||||||
$lc = $this->logo->line_width($this->logo->line_raw($result_height),FALSE);
|
|
||||||
|
|
||||||
$result_line = str_repeat(' ',self::LOGO_OFFSET_WIDTH)
|
// If we only have a text box and a header above, we step after the header
|
||||||
.$line
|
|
||||||
.str_repeat(' ',$buffer-$lc-($this->left_width ? self::LOGO_OFFSET_WIDTH : 0));
|
|
||||||
|
|
||||||
} elseif (self::LOGO_OFFSET_WIDTH && $this->logo->height && ($result_height === $this->logo->height) && $this->left_box->height) {
|
// If we only have a text box, and header below, we step after passing max width
|
||||||
$result_line = str_repeat(' ',$buffer);
|
|
||||||
|
|
||||||
} elseif ($result_height < $this->left_height-($this->logo->height ? 0 : self::LOGO_OFFSET_WIDTH)) {
|
$buffer = $this->step;
|
||||||
$line = $this->left_box->render_line($result_height-($this->logo->height ? self::LOGO_OFFSET_WIDTH : 0)-$this->logo->height);
|
|
||||||
$lc = $this->left_box->width;
|
|
||||||
|
|
||||||
$result_line = str_repeat(' ',($this->left_box->width ? self::LOGO_OFFSET_WIDTH : 0))
|
|
||||||
.$line
|
|
||||||
.str_repeat(' ',($this->left_box->width ? $buffer-$lc-($this->left_width ? self::LOGO_OFFSET_WIDTH : 0) : (($current_pos < $text_length) ? $buffer : 0)));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ($current_pos < $text_length)
|
$buffer = 0;
|
||||||
$result_line = str_repeat(' ',$buffer);
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
$buffer = 0;
|
||||||
|
|
||||||
|
if ($this->DEBUG)
|
||||||
|
dump([
|
||||||
|
'line'=>$this->y,
|
||||||
|
'drawing_logo'=>$this->drawing_logo,
|
||||||
|
'drawing_header'=>$this->drawing_header,
|
||||||
|
'drawing_headcontent'=>$this->drawing_headcontent,
|
||||||
|
'drawing_headfoot'=>$this->drawing_headfoot,
|
||||||
|
'drawing_headunderline'=>$this->drawing_headunderline,
|
||||||
|
'header_height'=>$this->header_height,
|
||||||
|
'drawing_leftbox'=>$this->drawing_leftbox,
|
||||||
|
'left_height'=>$this->left_height,
|
||||||
|
'left_box_height'=>$this->left_box->height,
|
||||||
|
'logo_height'=>$this->logo->height,
|
||||||
|
'left_width'=>$this->left_width,
|
||||||
|
'left_box_start'=>$this->left_box_start,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$size = 0;
|
||||||
|
// We are drawing our logo and/or header
|
||||||
|
if ($this->drawing_logo) {
|
||||||
|
$line = ANSI::bin_to_ansi([$this->logo->line($this->y)],FALSE);
|
||||||
|
$size = $this->logo->line_width($this->logo->line_raw($this->y),FALSE);
|
||||||
|
|
||||||
|
$result_line = str_repeat((is_null($this->DEBUG) ? 'l' : ' '),self::LOGO_OFFSET_WIDTH)
|
||||||
|
.$line
|
||||||
|
.str_repeat((is_null($this->DEBUG) ? 'L' : ' '),self::LOGO_OFFSET_WIDTH);
|
||||||
|
|
||||||
|
$this->x += $size+self::LOGO_OFFSET_WIDTH*2;
|
||||||
|
|
||||||
|
} elseif ($this->drawing_leftbox) {
|
||||||
|
$line = $this->left_box->render_line($this->y-$this->left_box_start);
|
||||||
|
$size = $this->left_box->width;
|
||||||
|
|
||||||
|
$result_line = str_repeat((is_null($this->DEBUG) ? 'b' : ' '),self::LOGO_OFFSET_WIDTH)
|
||||||
|
.$line
|
||||||
|
.str_repeat((is_null($this->DEBUG) ? 'B' : ' '),self::LOGO_OFFSET_WIDTH);
|
||||||
|
|
||||||
|
$this->x += $size+self::LOGO_OFFSET_WIDTH*2;
|
||||||
|
|
||||||
|
// For when there is a line between the logo and left box
|
||||||
|
} elseif (($this->y < $this->left_height) && ((! $this->left_box_below_header) || $this->logo->height)) {
|
||||||
|
$size = $this->left_box->width;
|
||||||
|
|
||||||
|
$result_line .= str_repeat((is_null($this->DEBUG) ? 'X' : ' '),self::LOGO_OFFSET_WIDTH*2+$this->left_box->width);
|
||||||
|
|
||||||
|
$this->x += $this->left_box->width+self::LOGO_OFFSET_WIDTH*2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add our header
|
if (($this->y < $this->left_height) && ((! $this->left_box_below_header) || $this->logo->height))
|
||||||
if ($result_height <= $this->header->height-1) {
|
$buffer = $this->left_width-$size-self::LOGO_OFFSET_WIDTH*2;
|
||||||
$result_line .= str_repeat(' ',$this->header_right ? self::MSG_WIDTH-($this->left_width ? self::LOGO_OFFSET_WIDTH*2 : 0)-$this->left_width-$this->header->width : 0)
|
|
||||||
.$this->header->render_line($result_height);
|
// Our step buffer
|
||||||
|
$result_line .= str_repeat((is_null($this->DEBUG) ? '+' : ' '),$buffer);
|
||||||
|
$this->x += $buffer;
|
||||||
|
|
||||||
|
if ($this->drawing_header) {
|
||||||
|
if ($this->drawing_headcontent) {
|
||||||
|
// If the header is on the right, we may need to pad it
|
||||||
|
if ($this->header_right) {
|
||||||
|
// Pad the header with any right justification
|
||||||
|
$result_line .= str_repeat((is_null($this->DEBUG) ? 'H' : ' '),self::MSG_WIDTH-$this->x-$this->header->width)
|
||||||
|
.$this->header->render_line($this->y);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$result_line .= $this->header->render_line($this->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add our header footer
|
} elseif ($this->drawing_headfoot) {
|
||||||
if ($x=ANSI::line_width($this->header_foot,FALSE)) {
|
if ($x=ANSI::line_width($this->header_foot,FALSE)) {
|
||||||
if ($result_height === $this->header->height) {
|
$result_line .=
|
||||||
$result_line .= str_repeat(' ',($this->header_right ? self::MSG_WIDTH-($this->left_width ? self::LOGO_OFFSET_WIDTH*2 : 0)-$this->left_width-$x : 0))
|
str_repeat((is_null($this->DEBUG) ? 'f' : ' '),$this->header_right ? (self::MSG_WIDTH-$this->x-$x) : ($this->left_box_below_header ? 0 : $this->left_width+$buffer-$this->x))
|
||||||
.ANSI::text_to_ansi($this->header_foot);
|
.ANSI::text_to_ansi($this->header_foot);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
} elseif ($this->drawing_headunderline) {
|
||||||
// Add our header underline
|
// Add our header underline
|
||||||
if ($this->header_underline) {
|
$result_line .= str_repeat(chr($this->header_underline),self::MSG_WIDTH-$this->x);
|
||||||
if ($result_height === $this->header->height+($this->header_foot ? 1 : 0)) {
|
|
||||||
$result_line .= str_repeat(chr($this->header_underline),self::MSG_WIDTH-$buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We are drawing the text
|
||||||
|
} else {
|
||||||
$subtext = '';
|
$subtext = '';
|
||||||
$subtext_ansi = '';
|
$subtext_ansi = '';
|
||||||
$subtext_length = 0;
|
$subtext_length = 0;
|
||||||
|
|
||||||
|
// If we have some text to render
|
||||||
if ($current_pos < $text_length) {
|
if ($current_pos < $text_length) {
|
||||||
if ($result_height >= $this->header_height) {
|
|
||||||
// Look for a return
|
// Look for a return
|
||||||
$return_pos = strpos($this->text,"\r",$current_pos);
|
$return_pos = strpos($this->text,"\r",$current_pos);
|
||||||
|
|
||||||
// We have a return
|
// We have a return
|
||||||
if ($return_pos !== FALSE) {
|
if ($return_pos !== FALSE) {
|
||||||
// If the remaining text is within our width, we'll use it all.
|
// If the remaining text is within our width, we'll use it all.
|
||||||
if ($return_pos-$current_pos < self::MSG_WIDTH-$buffer) {
|
if ($return_pos-$current_pos < self::MSG_WIDTH-$this->x-$buffer) {
|
||||||
$subtext = substr($this->text,$current_pos,$return_pos-$current_pos);
|
$subtext = substr($this->text,$current_pos,$return_pos-$current_pos);
|
||||||
|
|
||||||
// Look for the space.
|
// Look for the space.
|
||||||
} else {
|
} else {
|
||||||
$space_pos = strrpos(substr($this->text,$current_pos,($return_pos-$current_pos > static::MSG_WIDTH-$this->left_width ? static::MSG_WIDTH-$this->left_width : $return_pos-$current_pos)),' ');
|
$space_pos = strrpos(substr($this->text,$current_pos,static::MSG_WIDTH-$this->x-$buffer),' ');
|
||||||
$subtext = substr($this->text,$current_pos,$space_pos);
|
$subtext = substr($this->text,$current_pos,$space_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +334,7 @@ class Page
|
|||||||
} elseif ($text_length-$current_pos < static::MSG_WIDTH-$buffer) {
|
} elseif ($text_length-$current_pos < static::MSG_WIDTH-$buffer) {
|
||||||
$subtext = substr($this->text,$current_pos);
|
$subtext = substr($this->text,$current_pos);
|
||||||
|
|
||||||
// Get the next lines worth of chars
|
// Get the next lines worth of chars, breaking on a space
|
||||||
} else {
|
} else {
|
||||||
$subtext = $this->text_substr(substr($this->text,$current_pos),static::MSG_WIDTH-$buffer);
|
$subtext = $this->text_substr(substr($this->text,$current_pos),static::MSG_WIDTH-$buffer);
|
||||||
|
|
||||||
@ -239,7 +344,6 @@ class Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
$current_pos += strlen($subtext)+1;
|
$current_pos += strlen($subtext)+1;
|
||||||
}
|
|
||||||
|
|
||||||
if ($subtext) {
|
if ($subtext) {
|
||||||
$subtext_length = ANSI::line_width($subtext,FALSE);
|
$subtext_length = ANSI::line_width($subtext,FALSE);
|
||||||
@ -254,24 +358,30 @@ class Page
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($result_line || $subtext) {
|
if ($result_line || $subtext) {
|
||||||
$result .= $result_line.
|
$result_line .=
|
||||||
($subtext_ansi
|
($subtext_ansi
|
||||||
? str_repeat(' ',
|
? str_repeat(($this->DEBUG ? 'F' : ' '),
|
||||||
($this->text_right && ($result_height > $this->header_height-1) ? static::MSG_WIDTH-$subtext_length-$buffer : 0)).$subtext_ansi
|
($this->text_right && ($this->y > $this->header_height-1) ? static::MSG_WIDTH-$subtext_length-$buffer : 0)).$subtext_ansi
|
||||||
: '');
|
: '');
|
||||||
|
|
||||||
$result .= $this->crlf ? "\n\r" : "\r";
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$result_height++;
|
$result_line .= $this->crlf ? "\n\r" : "\r";
|
||||||
|
|
||||||
if (($result_height > $this->logo->height) &&
|
$this->y++;
|
||||||
($result_height > $this->left_height) &&
|
$this->x = 0;
|
||||||
($current_pos >= $text_length))
|
|
||||||
{
|
//$result_line .= ".........+.........+.........+.........+.........+.........+.........+.........+\r\n";
|
||||||
|
$result .= $result_line;
|
||||||
|
|
||||||
|
if ($this->DEBUG)
|
||||||
|
echo $result_line;
|
||||||
|
|
||||||
|
// If we are processed our logo, left box and text, we are done
|
||||||
|
if (($this->y >= $this->left_height) && ($current_pos >= $text_length))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user