termcol: generic h/s/v table generator function
[sheet.git] / termcol.plp
index 1e5e2870cea46240c538919fe1416bf0222c6680..d945079bbab1cbec8b9af2f5a7ab7062707c700d 100644 (file)
@@ -28,10 +28,11 @@ print
 
 <div class="section">
 <:
-use Shiar_Sheet::Colour '1.01';
+use Shiar_Sheet::Colour '1.03';
+use List::Util qw( min max );
 
 sub colcell {
-       my $name = shift;
+       my $name = shift or return "<td colspan=3>\n";
        my $col = Shiar_Sheet::Colour->new(@_);
        my $minhex = $col->rgb24;
        my $css     = '#' . $col->rgb48;
@@ -251,27 +252,68 @@ print "</table>\n\n";
 <div class="section">
 <h2>256-colour space</h2>
 <:
-for my $r (0 .. 5) {
-       print '<table>';
-       for my $g (0 .. 5) {
-               print '<tr>';
-               for my $b (0 .. 5) {
-                       my $index = $r*6*6 + $g*6 + $b + 16;
-                       print colcell($index, map { $_ && $_*40 + 55 } $r, $g, $b);
+sub coltable_hsv {
+       my ($dim, $rgbval, $greyramp) = @_;
+
+       my $hmax = ($dim + $dim - 1) * 2 + ($dim - 2) * 2 + 3;
+       my $vmax = $dim - 1;
+       my $smax = $dim - 1;
+
+       my %greymap;  # name => value
+       my @colmap;  # saturation => value => hue => [name, r,g,b]
+       my $offset = 16;
+
+       for my $r (0 .. $dim - 1) {
+               for my $g (0 .. $dim - 1) {
+                       for my $b (0 .. $dim - 1) {
+                               my $index = $r*$dim*$dim + $g*$dim + $b + $offset;
+                               my @rgb = map { &$rgbval } $r, $g, $b;
+
+                               my $h = Shiar_Sheet::Colour->new(@rgb)->hue * $hmax;
+                               my $v = int(max(@rgb) / 255 * $vmax);
+                               my $s = abs(min(@rgb) - max(@rgb)) / 255 * $smax;
+
+                               if (!$s) {
+                                       $greymap{$index} = $rgb[0];
+                                       next;
+                               }
+
+                               $v = $vmax - $v;
+                               $s = $smax - $s - $v;
+
+                               $colmap[$s][$v][$h] = [$index, @rgb];
+                       }
                }
        }
-       print "</table>\n";
-}
-print "\n";
 
-       print '<table>';
-for my $row (0, 12) {
-       print '<tr>';
-       print colcell(232+$_, ($_*10 + 8) x 3) for $row .. $row+11;
+       my $out = '<table class=mapped>';
+       $out .= sprintf '<colgroup span=%d>', 3 * @{$_} for @colmap;
+       my $huerow = $colmap[0][0]; # first {$_} map { @{$_} } @colmap;
+       for my $h (grep { $huerow->[$_] } 0 .. $#{$huerow}) {
+               $out .= '<tr>';
+               $out .= colcell(@$_) for map { $_->[$h] } map { @{$_} } @colmap;
+       }
+       $out .= "</table>\n\n";
+
+       $offset += $dim ** 3;
+       $greymap{$offset++} = $_ for @{$greyramp};
+
+       $out .= '<table>';
+       my $col = 0;
+       my $colbreak = keys(%greymap) / 2;  # split into 2 rows
+       for my $num (sort { $greymap{$a} <=> $greymap{$b} } keys %greymap) {
+               $out .= '<tr>' unless $col++ % $colbreak;
+               $out .= colcell($num, ($greymap{$num}) x 3);
+       }
+       $out .= "</table>\n\n";
+
+       return $out;
 }
-       print "</table>\n";
-print "\n";
 
+print coltable_hsv(6,
+       sub { $_ && $_*40 + 55 },
+       [ map { $_ * 10 + 8 } 0 .. 23 ],
+);
 :></div>
 <: } :>
 <hr>