my $can = PCI::Telnet::GUI::Canvas->new(10,40); $can->fill([ON_YELLOW,BOLD,WHITE],0,0,$can->height,$can->width,HOR); my $c2 = PCI::Telnet::Canvas->new(5,10); $c2->box(0,0,$c2->height-2,$c2->width-2,ON_WHITE,BLACK,1); $can->render_canvas(2,2,$c2); print $can->to_string(20,10), "\n\n"; #### use constant AS_BG => 0; use constant AS_FG => 1; use constant AS_U => 2; use constant AS_BLINK => 3; use constant AS_BOLD => 4; # clone is from the Clone module on CPAN. Tried using Clone::Fast, but it added .05 sec to running time when this function was called ~6000x in .25 seconds. sub _atlayer { #$_[0] = shift; local $_ = clone($_[1]); #$_->{$_} = $_[1]->{$_} foreach keys %{$_[1]}; $_->[AS_BG] = $_[0]->[AS_BG] if !$_->[AS_BG]; $_->[AS_FG] = $_[0]->[AS_FG] if !$_->[AS_FG]; $_->[AS_U] = $_[0]->[AS_U] if $_->[AS_U] < 0; $_->[AS_BOLD] = $_[0]->[AS_BOLD] if $_->[AS_BOLD] < 0; $_->[AS_BLINK] = $_[0]->[AS_BLINK] if $_->[AS_BLINK] < 0; return $_; } #### # iloop is the inner loop of the canvas rendering function. # I put it in a separate sub so that DProf could show it # apart from the main loop - and it gets 79% of the # processing time under one scenario. sub iloop($$$) { my ($line,$arow,$sw,$lat,$blank) = @_; my ($atr,$chr,$col,@a); for $col (0..$sw) { $chr = $line->[$col]; $atr = $arow->[$col]; push @a, _attr($atr) if #!_ateq($lat,$atr); $lat->[AS_BG] ne $atr->[AS_BG] || $lat->[AS_FG] ne $atr->[AS_FG] || $lat->[AS_U] != $atr->[AS_U] || $lat->[AS_BOLD] != $atr->[AS_BOLD] || $lat->[AS_BLINK] != $atr->[AS_BLINK]; push @a, defined $chr ? $chr : $blank; $lat = $atr; } return join '', @a; }