Created
January 10, 2016 07:29
-
-
Save kurahaupo/ee67381bc1ca58b6b2ba to your computer and use it in GitHub Desktop.
Xterm Colour test pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use 5.008; | |
use strict; | |
use warnings; | |
use Getopt::Long qw(:config bundling); | |
use POSIX qw( floor ); | |
use utf8; | |
my $as_list; | |
my $as_orig; | |
my $compact; | |
my $define_colours = 0; | |
my $gamma = 0; | |
my $numeric_ordering; | |
my $show_ansi = 1; | |
my $show_cube = 1; | |
my $show_gray = 1; | |
my $show_help; | |
my $show_hex; | |
my $show_sys = 1; | |
my $transpose; | |
my $use_padding; | |
sub N($) { my $r = \@_; if ($r->[0] && ref $r->[0] eq 'CODE') { sub { $r->[0]->( $_[0], ! $_[1] ) } } else { sub { $r->[0] = ! $_[1] } } } | |
sub ALL(@) { my $r = \@_; sub { $_ = $_[1] for @$r } } | |
GetOptions | |
'A|hide-ansi!' => N$show_ansi, | |
'a|show-ansi|ansi!' => \$show_ansi, | |
'f|full!' => N$compact, | |
'b|brief!' => \$compact, | |
'C|hide-cube!' => N$show_cube, | |
'c|show-cube|cube!' => \$show_cube, | |
'D!' => N$define_colours, | |
'd|define-colours!' => \$define_colours, | |
'G|hide-gray!' => N$show_gray, | |
'g|show-gray|gray!' => \$show_gray, | |
'l|as-list|list' => \$as_list, | |
'o|as-orig|orig' => \$as_orig, | |
'p|padding' => \$use_padding, | |
'r|t|transpose:+' => \$transpose, | |
'S|hide-sys!' => N$show_sys, | |
's|show-sys|sys!' => \$show_sys, | |
'V|hide-all' => N ALL($show_sys, $show_ansi, $show_cube, $show_gray), | |
'v|show-all|all' => ALL($show_sys, $show_ansi, $show_cube, $show_gray), | |
'x|show-hex|hex!' => \$show_hex, | |
'X|hide-hex|decimal!' => N$show_hex, | |
'Z|Γ|linear' => N$gamma, | |
'z|γ|gamma=f' => \$gamma, | |
'h|help' => sub { print <<EndOfHelp; exit 0; } or exit 64; | |
\e[0m******************************* | |
* XTERM 256-colour Test Chart * | |
******************************* | |
Usage: $0 [-w] [-l|-r] [-s] [-tN] | |
-d (-D) do (don't) send colour definitions to terminal | |
-z -γ gamma correction factor | |
-l list display | |
-p extra spaces padding | |
-rN -tN rotate (transpose) N∈{0,1,2,3,4,5} | |
-zGAMMA use gamma-corrected scale rather than standard offset linear | |
-Z use standard offset linear rather than gamme-corrected scale | |
Cube colour range: | |
16 = black | |
231 = white | |
Grayscale colour range: | |
232 = very dark gray | |
255 = very light gray | |
EndOfHelp | |
defined $transpose && $as_list and die "Can't use both --transpose and --as-list\n"; | |
$transpose ||= 0; | |
my $num_fmt = $show_hex ? '%2x' : '%-3u'; | |
sub round($) { floor(0.5+$_[0]) } | |
my @scale6 = map { $_*51 } 0 .. 5; | |
my @scale24 = map { round($_ * 255 / 25) } 1 .. 24; | |
if (!$gamma) { | |
# scales used by original xterm-colourtest | |
@scale6 = map { $_ && 55 + $_ * 40 } 0 .. 5; # 00 5f 87 af d7 ff | |
@scale24 = map { 8 + $_ * 10 } 0 .. 23; # 08 12 1c 26 30 3a 44 4e 58 62 6c 76 80 8a 94 9e a8 b2 bc c6 d0 da e4 ee | |
} elsif ($gamma != 1) { | |
$_ = round(($_ / 255) ** $gamma * 255) for @scale6, @scale24; | |
} | |
sub byte2triple($) { | |
use integer; | |
my ($v) = @_; | |
$v < 0 && die "Value '$v' too low"; | |
$v < 8 && return map { $_ ? 0xcc : 0x00 } $v & 1, $v & 2, $v & 4; | |
$v-= 8; | |
$v < 8 && return map { $_ ? 0xff : 0x88 } $v & 1, $v & 2, $v & 4; | |
$v-= 8; | |
$v < 216 && return map { $scale6[$_] } $v / 36, $v / 6 % 6, $v % 6; | |
$v-= 216; | |
$v < 24 && return (($scale24[$v]) x 3); | |
die "Value '$v' too high"; | |
} | |
sub triple2byte($$$) { | |
my ($R,$G,$B) = @_; | |
my @T = grep { $_ >= 16 && $_ <= 255 } | |
16, | |
16+int(($R-75)/40)*36+int(($G-75)/40)*6+int(($G-75)/40), | |
int(232+($R+$G+$B-9)/30), | |
231; | |
my @D = map { | |
my ($rr,$gg,$bb) = byte2triple $_; | |
($R-$rr)**2 + ($G-$gg)**2 + ($B-$bb)**2; | |
} @T; | |
my @O = sort { $D[$a] <=> $D[$b] } 0 .. $#D; | |
return $T[$O[0]]; | |
} | |
sub byte2cell($) { | |
! $compact ? sprintf "$num_fmt:%02x/%02x/%02x\e[39;49;0m%s", | |
$_[0], | |
byte2triple $_[0], | |
$use_padding ? ' ' : '' | |
: sprintf "$num_fmt%s", $_[0], $use_padding ? ' ' : '' | |
} | |
sub is_dark($) { | |
my ($v) = @_; | |
my ($R,$G,$B) = byte2triple $v; | |
# weigh green more strongly when deciding on inversion | |
return $R + 3 * $G + $B < 255 * 5 / 2.5; # half of max brightness | |
} | |
sub printcell($) { | |
my ($v) = @_; | |
printf "\e[%u;48;5;%um%s\e[39;49;0m", | |
is_dark $v ? 37 : 30, | |
$v, | |
byte2cell $v; | |
} | |
if ($define_colours) { | |
for my $byte ( 0 .. 255 ) { | |
printf "\e]4;%u;rgb:%2.2x/%2.2x/%2.2x\e\\", $byte, byte2triple $byte; | |
} | |
} | |
my ($colour_stride_1, $colour_stride_2, $colour_stride_3) = @{[ | |
[ 36, 6, 1 ], [ 1, 6, 36 ], | |
[ 1, 36, 6 ], [ 6, 36, 1 ], | |
[ 6, 1, 36 ], [ 36, 1, 6 ], | |
]->[$transpose % 6] }; | |
my ($grayscale_stride_1, $grayscale_stride_2) = @{[ | |
[ 6, 1 ], | |
[ 1, 4 ], | |
]->[ !$compact && $transpose / 6 % 2 ]}; | |
if ( $as_list ) { | |
if ($show_ansi) { | |
for my $v ( 0 .. 15 ) { | |
printf "\e[7;%u;%u%sm%s\e[39;49;0m\n", | |
30+($v&7), | |
is_dark $v ? 47 : 40, | |
$v & 8 ? ';1' : '', | |
byte2cell $v; | |
} | |
} | |
my @C; | |
push @C, 0 .. 15 if $show_sys; | |
push @C, 16 .. 231 if $show_cube; | |
push @C, 232 .. 255 if $show_gray; | |
for my $v ( @C ) { | |
printcell $v; | |
print "\n"; | |
} | |
} elsif ( $as_orig ) { | |
# This is the original colour-test layout | |
if ($show_ansi) { | |
print "ANSI colours:\n"; | |
for my $colour ( 0 .. 7 ) { printf "\e[4%1\$um%1\$-2s", $colour } print "\e[49;0m\n"; | |
for my $colour ( 0 .. 7 ) { printf "\e[1;7;3%1\$um%1\$-2s", $colour } print "\e[49;0m\n\n"; | |
} | |
if ($show_sys) { | |
print "Standard colours:\n"; | |
for my $colour ( 0 .. 15 ) { printf "\e[48;5;%um ", $colour; ($colour&7)==7 && print "\e[49;0m\n"; } | |
print "\n"; | |
} | |
if ($show_cube) { | |
# now the colour cube | |
print "Colour cube, 6x6x6: [$colour_stride_1 $colour_stride_2 $colour_stride_3]\n"; | |
for my $d0 ( 0 .. 5 ) { | |
for my $d1 ( 0 .. 5) { | |
for my $d2 ( 0 .. 5) { | |
my $colour = 16 + $d1 * $colour_stride_1 + $d0 * $colour_stride_2 + $d2 * $colour_stride_3; | |
print "\e[48;5;${colour}m "; | |
} | |
print "\e[49;0m "; | |
} | |
print "\n"; | |
} | |
} | |
if ($show_gray) { | |
# now the grayscale ramp | |
print "Grayscale ramp:\n"; | |
for my $colour ( 232 .. 255 ) { | |
print "\e[48;5;${colour}m "; | |
} | |
print "\e[0m\n"; | |
} | |
} else { | |
if ($show_ansi) { | |
print "ANSI colours:\n"; | |
for my $v ( 0 .. 15 ) { | |
printf "\e[7;%u;%u%sm%s\e[39;49;0m", | |
30+($v&7), | |
is_dark $v ? 47 : 40, | |
$v & 8 ? ';1' : '', | |
byte2cell $v; | |
$as_list || !($v+1 & ($compact?7:3)) and print "\n"; | |
} | |
print "\n"; | |
} | |
if ($show_sys) { | |
print "Standard colours:\n"; | |
for my $v ( 0 .. 15 ) { | |
printf "\e[%u;48;5;%um%s", is_dark $v ? 37 : 30, $v, byte2cell $v; | |
$as_list || !($v+1 & ($compact?7:3)) and print "\e[39;49;0m\n"; | |
} | |
print "\n"; | |
} | |
if ($show_cube) { | |
print "Colour cube, 6x6x6: [$colour_stride_1 $colour_stride_2 $colour_stride_3]\n"; | |
for my $d1 ( 0 .. 5 ) { | |
for my $d2 ( 0 .. 5 ) { | |
for my $d3 ( 0 .. 5 ) { | |
my $v = 16 + $d1 * $colour_stride_1 + $d2 * $colour_stride_2 + $d3 * $colour_stride_3; | |
printcell $v; | |
#my $z = is_dark $v; | |
#printf "\e[%u;48;5;%um%s", $z ? 37 : 30, $v, byte2cell $v; | |
#print "\e[39;49;0m"; | |
$as_list and print "\n"; | |
} | |
! $as_list and print $compact ? " " : "\n"; | |
} | |
print "\n"; | |
} | |
print "\n"; | |
} | |
if ($show_gray) { | |
print "Gray-scale:\n"; | |
if ( $as_list || $compact ) { | |
for my $v ( 232 .. 255 ) { | |
my $z = is_dark $v; | |
printf "\e[%u;48;5;%um%s\e[39;49;0m", $z ? 37 : 30, $v, byte2cell $v; | |
} | |
} else { | |
for my $d1 ( 0 .. 3 ) { | |
for my $d2 ( 0 .. 5 ) { | |
my $v = 232 + $d1 * $grayscale_stride_1 + $d2 * $grayscale_stride_2; | |
printcell $v; | |
#my $z = is_dark $v; | |
#printf "\e[%u;48;5;%um%s", $z ? 37 : 30, $v, byte2cell $v; | |
#print "\e[39;49;0m"; | |
$as_list and print "\n"; | |
} | |
! $as_list && ! $compact and print "\n"; | |
} | |
print "\n"; | |
} | |
} | |
} | |
print "\e[39;49;0m\n"; | |
exit; | |
__END__ | |
CSI codes: | |
0 - plain | |
1 - bold | |
2 | |
3 | |
4 - underline | |
5 - blink | |
6 | |
7 - inverse | |
8 - hidden | |
22 - not bold | |
24 - not underline | |
25 - not blink | |
27 - not inverse | |
30-37 basic foreground colours | |
38;5;X extended foreground colour | |
39 default foreground colour | |
40-37 basic background colours | |
48;5;X extended background colour | |
49 default background colour | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment