chiark / gitweb /
segment labelling work-in-progress - yet to do are labels and graph colouring
[trains.git] / layout / layout
index ed8ba2f2c41b4507a18b961c817763eb78964489..c8df20a3c5cf69d0cface18d9f424afecad0c696 100755 (executable)
@@ -7,6 +7,9 @@ use IO::File;
 use strict;
 no strict 'subs';
 
+our $file_lineno= 0;
+our $file_filename;
+
 our $scale= 7.0;
 our $page_x= 0;
 our $page_y= 0;
@@ -23,9 +26,11 @@ our $ps_page_ymul= 538.583;
 
 our @eopts;
 our @segments= ('/');
+our @ident_strings= ();
 our %subsegcmap;
+our %segcmap;
 
-our $drawers= 'arscldmnog';
+our $drawers= 'arqscldmnog';
 our %chdraw_emap= qw(A ARScgd
                     R aRscgD
                     S aRScgd
@@ -34,6 +39,8 @@ our %chdraw_emap= qw(A ARScgd
                     r arcs
                     L LMg
                     l l
+                    D D
+                    d d
                     M Mnog
                     N MNog
                     O MNOg
@@ -160,21 +167,21 @@ our $psu_thinlw= 1.0;
 our %psu_subseglw;
 $psu_subseglw{'e'}= 20.0;
 $psu_subseglw{'m'}= 15.0;
+$psu_subseglw{'q'}= 20.0;
 
 our $lmu_marklw= 4;
 our $lmu_marktpt= 11;
 our $lmu_txtboxtxty= $lmu_marktpt * 0.300;
 our $lmu_txtboxh= $lmu_marktpt * 1.100;
-our $lmu_lenboxh= $lmu_marktpt * 1.100;
 our $lmu_txtboxpadx= $lmu_marktpt * 0.335;
-our $lmu_lenboxpadx= $lmu_marktpt * 0.005;
 our $lmu_txtboxoff= $lmu_marklw / 2;
-our $lmu_lenboxoff= -$lmu_marklw * 1.5;
 our $lmu_txtboxlw= 1;
+our $lmu_lenlabeloffctr= -$lmu_marklw * 1.0;
+our $lmu_lenlabeloff=     $lmu_marklw * 0.5;
 
 our $olu_left= 10 * $scale;
 our $olu_right= 217 * $scale - $olu_left;
-our $olu_bottom= 20 * $scale;
+our $olu_bottom= 25 * $scale;
 our $olu_top= 270 * $scale - $olu_bottom;
 our $olu_gap_x= 30;
 our $olu_gap_y= 60;
@@ -569,6 +576,7 @@ sub o ($) { $o .= $_[0]; }
 sub ol ($) { $ol .= $_[0]; }
 sub oflushpage () {
     return if $subsegcmapreq;
+
     print $o, $ol, "  showpage\n"
        or die $!;
     $o=$ol='';
@@ -650,7 +658,7 @@ sub segment_used__print ($) {
     
 sub segment_used__len ($$) {
     my ($used,$pt) = @_;
-    $segused_incurrent++;
+    $segused_incurrent += $used;
 
     return if @segments < 3;
     $segments[1] -= $used;
@@ -695,7 +703,7 @@ sub parametric_segment ($$$$$) {
     # $calcfn is invoked with $param set and should return a loc
     # (ie, ref to X =>, Y =>, A =>).
     my ($pa,$pb,@ends,$side,$ppu,$e,$v,$tick,$draw,$allwidth);
-    return unless $ctx->{Draw} =~ m/[ARSCG]/;
+    return unless $ctx->{Draw} =~ m/[ARSCGQ]/;
     $ppu= $psu_ulen/$lenperp;
     $allwidth= allwidth($minradius);
     my ($railctr)=($psu_gauge + $psu_raillw)*0.5;
@@ -705,11 +713,12 @@ sub parametric_segment ($$$$$) {
     my ($sleeperend)=($psu_sleeperlen*0.5);
 print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
     $draw= current_draw();
-    if ($draw =~ m/G/) {
+    if ($draw =~ m/[QG]/) {
        my ($pt,$going,$red,$csegbare,$movfeat,$movstroke);
        my ($used_last,$me,$segsave);
+       o("gsave\n");
        $segsave= segment_state_save();
-       foreach $me (qw(e m)) {
+       foreach $me ($draw =~ m/Q/ ? qw(q) : qw(e m)) {
            segment_state_restore($segsave);
            $going=0;
            o("% segments @segments\n");
@@ -726,27 +735,37 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
                        $subsegcmap{$csegbare}++;
                    }
                } else {
-                   $movfeat= $csegbare =~ s,(/\D+)(\d+)$,$1, ? $2 : 'f';
-                   die "unknown subsegment colour for $csegbare\n"
-                       unless exists $subsegcmap{$csegbare};
-                   $red= $pt->{A} / (2*$pi);
-                   $red *= $subsegcmapangscale;
-                   $red += $subsegcmapangscale*2;
-                   $red += $subsegcmapangscale/2 if $segments[0] =~ m/^\-/;
-                   $red %= $subsegcmapangscale;
-                   $red += $subsegcmapangscale if $me eq 'e';
-                   $red= sprintf("%f", $red / 255.0);
-                   $movstroke=
-                       ("    $red $subsegcmap{$csegbare} setrgbcolor\n".
-                        "    $psu_subseglw{$me} setlinewidth stroke\n");
-                   if ($subsegmovfeatpos ne $movfeat ||
-                       ($me eq 'e' && $csegbare =~ m,^/,)) {
-                       $movstroke= "%     no-stroke\n";
+                   if ($draw =~ m/Q/) {
+                       $csegbare =~ m,^[^/]*,;
+#print STDERR "looking for \`$&' $me\n";
+                       $movstroke= $segcmap{$&};
+                       $movstroke= "%     no-colour    "
+                           unless defined $movstroke;
+                   } elsif ($draw =~ m/G/) {
+                       $movfeat= $csegbare =~ s,(/\D+)(\d+)$,$1, ? $2 : 'f';
+                       die "unknown subsegment colour for $csegbare\n"
+                           unless exists $subsegcmap{$csegbare};
+                       $red= $pt->{A} / (2*$pi);
+                       $red *= $subsegcmapangscale;
+                       $red += $subsegcmapangscale*2;
+                       $red += $subsegcmapangscale/2
+                           if $segments[0] =~ m/^\-/;
+                       $red %= $subsegcmapangscale;
+                       $red += $subsegcmapangscale if $me eq 'e';
+                       $red= sprintf("%f", $red / 255.0);
+                       $movstroke= "    $red $subsegcmap{$csegbare}".
+                                   " setrgbcolor\n";
+                       if ($subsegmovfeatpos ne $movfeat ||
+                           ($me eq 'e' && $csegbare =~ m,^/,)) {
+                           $movstroke= "%     no-stroke    ";
+                       }
                    }
+                   $movstroke .=
+                       "    $psu_subseglw{$me} setlinewidth stroke\n";
                }
                o_path_begin();
                parametric__o_pt($pt);
-       
+
                $param += $ppu;
                last if $param>=$p1;
                $pt= &$calcfn;
@@ -761,6 +780,7 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
            parametric__o_pt($pt);
            o($movstroke);
        }
+       o("grestore\n");
     }
     if ($draw =~ m/C/) {
        my ($pt);
@@ -773,21 +793,7 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
        parametric__o_pt(&$calcfn);
        o("      stroke\n");
     }
-    if ($draw =~ m/D/) {
-       my ($pt,$ad,$len);
-       $param= ($p0+$p1)*0.5;
-       $pt= &$calcfn;
-       $ad= ang2deg($pt->{A}) + 90;
-       $len= sprintf "%.0f", $lenperp * abs($p1-$p0);
-       ol("      gsave\n".
-          "        $pt->{X} $pt->{Y} translate\n".
-          "        $ad rotate 0.75 dup scale\n".
-          "        0 $lmu_lenboxh $lmu_lenboxpadx $lmu_lenboxoff".
-          " ($len) label_in_box\n".
-          "      grestore\n");
-    }
-    return unless $draw =~ m/[ARS]/;
-    for ($pa= $p0; $pa<$p1; $pa=$pb) {
+    if ($draw =~ m/[ARS]/) { for ($pa= $p0; $pa<$p1; $pa=$pb) {
        $pb= $pa + $ppu;
        $param= $pa; $ends[0]= @ends ? $ends[1] : &$calcfn;
        $param= $pb; $ends[1]= &$calcfn;
@@ -827,7 +833,22 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
            }
        }
        o("      grestore\n");
-    }
+    } }
+    if ($draw =~ m/D/) {
+       my ($pt,$ad,$len,$off);
+       $param= ($p0+$p1)*0.5;
+       $pt= &$calcfn;
+       $ad= ang2deg($pt->{A});
+       $len= sprintf "%.0f", $lenperp * abs($p1-$p0);
+       $off= $draw =~ m/C/ ? $lmu_lenlabeloff : $lmu_lenlabeloffctr;
+       ol("      gsave\n".
+          "        $pt->{X} $pt->{Y} translate\n".
+          "        $ad rotate\n".
+          "        lf setfont\n".
+          "        0 $off moveto\n".
+          "        ($len) show\n".
+          "      grestore\n");
+    }    
 }
 
 sub arc ($$$$$) {
@@ -1226,6 +1247,12 @@ sub cmd__runobj ($) {
     }
 }
 
+sub cva_segment ($) {
+    my ($sp)=@_;
+    die "invalid segment" if $sp =~ m/[^0-9A-Za-z_]/;
+    return $sp;
+}
+
 sub cva_subsegspec ($) {
     my ($sp)=@_;
     die "invalid subsegment spec" unless
@@ -1307,6 +1334,17 @@ sub cmd_segmap {
     }
 }
 
+sub cmd_segend {
+    @al=();
+};
+
+sub cmd_segcmap {
+    my ($seg,$colour);
+    $seg= can(\&cva_segment);
+    $segcmap{$seg}= "@al";
+    @al= ();
+};
+
 sub layer_draw ($$) {
     my ($k,$l) = @_;
     my ($eo,$cc, $r);
@@ -1476,14 +1514,42 @@ dv("cmd__do $ctx @al ",'$ctx',$ctx);
                   "      $lmu_marklw setlinewidth stroke\n");
            }
            if ($draw =~ m/L/) {
-               ol("      $lmu_txtboxlw $lmu_txtboxh $lmu_txtboxpadx".
-                  " $lmu_txtboxoff ($id) label_in_box\n");
+               ol("      /s ($id) def\n".
+                  "      lf setfont\n".
+                  "      /sx5  s stringwidth pop\n".
+                  "      0.5 mul $lmu_txtboxpadx add def\n".
+                  "      -90 rotate  0 $lmu_txtboxoff translate  newpath\n".
+                  "      sx5 neg  0             moveto\n".
+                  "      sx5 neg  $lmu_txtboxh  lineto\n".
+                  "      sx5      $lmu_txtboxh  lineto\n".
+                  "      sx5      0             lineto closepath\n".
+                  "      gsave  1 setgray fill  grestore\n".
+                  "      $lmu_txtboxlw setlinewidth stroke\n".
+                  "      sx5 neg $lmu_txtboxpadx add  $lmu_txtboxtxty\n".
+                  "      moveto s show\n");
            }
            ol("      grestore\n");
        }
     }
 }
 
+sub cmd_ident {
+    my ($vs, @lt, $inf, $strft);
+    $vs= "@al";
+    $vs= $1 if $vs =~ m/^\$Revision\: ([0-9.]+)\ \$$/;
+    if (!defined $file_filename) {
+       $inf= "$vs (unknown file: $file_lineno)";
+    } elsif (!stat $file_filename ||
+            !(@lt= localtime((stat _)[9]))) {
+       $inf= "$file_filename ($1 $!)";
+    } else {
+       $strft= strftime "%Y-%m-%d %H:%M:%S +%Z", @lt;
+       $inf= "$file_filename ($1 $strft)";
+    }
+    push @ident_strings, $inf;
+    @al= ();
+}
+
 sub cmd_showlibrary {
     my ($obj_id, $y, $x, $ctx_save, $width, $height);
     my ($max_x, $min_x, $max_y, $min_y, $nxty, $obj, $loc, $pat, $got, $glob);
@@ -1558,7 +1624,8 @@ sub cmd__one {
 
 o("%!\n".
   "  /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
-  "  $ps_page_shift 0 translate 90 rotate\n");
+  "  $ps_page_shift 0 translate 90 rotate\n".
+  "  gsave\n");
 
 if ($page_x || $page_y) {
     o("  /Courier-New findfont 15 scalefont setfont\n".
@@ -1568,28 +1635,6 @@ if ($page_x || $page_y) {
 o("  -$ps_page_xmul $page_x mul  -$ps_page_ymul $page_y mul  translate\n".
   "  $ptscale $ptscale scale\n");
 
-o("/label_in_box {\n".
-  '% linewidth $lmu_*boxh $lmu_*padx $lmu_*boxoff (s)'.
-  '  label_in_box  => _'."\n".
-  "  /s exch def\n".
-  "  /boxoff exch def\n".
-  "  /padx exch def\n".
-  "  /boxh exch def\n".
-  "  setlinewidth\n".
-  "  lf setfont\n".
-  "  /sx5  s stringwidth pop\n".
-  "  0.5 mul padx add def\n".
-  "  -90 rotate  0 boxoff translate  newpath\n".
-  "  sx5 neg  0             moveto\n".
-  "  sx5 neg  boxh  lineto\n".
-  "  sx5      boxh  lineto\n".
-  "  sx5      0             lineto closepath\n".
-  "  gsave  1 setgray fill  grestore\n".
-  "  stroke\n".
-  "  sx5 neg padx add  $lmu_txtboxtxty\n".
-  "  moveto s show\n".
-  "} def\n");
-
 newctx();
 
 open DEBUG, ($debug ? ">&2" : ">/dev/null") or die $!;
@@ -1606,6 +1651,14 @@ $ctx->{SegName}= '';
 cmd__one();
 
 while (<>) {
+    $file_lineno++;
+    if (m/^\#line (\d+)$/) { $file_lineno= $1; next; }
+    if (m/^\#line (\d+) (.*)$/) {
+       $file_lineno= $1;
+       $file_filename= $2;
+       $file_filename =~ s/^\"(.*)\"$/$1/;
+       next;
+    }
     next if m/^\s*\#/;
     chomp; s/^\s+//; s/\s+$//;
     @al= split /\s+/, $_;
@@ -1634,24 +1687,32 @@ while (<>) {
     if ($scale < 1.5) {
        my ($tick_x, $tick_y, $ticklen);
        $ticklen= 10;
-       printf("    gsave 0.5 setgray 0.33 setlinewidth\n".
-              "      /regmark {\n".
-              "        newpath moveto\n".
-              "        -%d 0 rmoveto %d 0 rlineto\n".
-              "        -%d -%d rmoveto 0 %d rlineto stroke\n".
-              "      } def\n",
-              $ticklen, $ticklen*2, $ticklen, $ticklen, $ticklen*2)
-           or die $!;
+       o(sprintf
+         "    gsave 0.5 setgray 0.33 setlinewidth\n".
+         "      /regmark {\n".
+         "        newpath moveto\n".
+         "        -%d 0 rmoveto %d 0 rlineto\n".
+         "        -%d -%d rmoveto 0 %d rlineto stroke\n".
+         "      } def\n",
+         $ticklen, $ticklen*2, $ticklen, $ticklen, $ticklen*2);
        for ($tick_x= $min_x; $tick_x < $max_x; $tick_x += 150) {
            for ($tick_y= $min_y; $tick_y < $max_y; $tick_y += 150) {
-               printf("      %f %f regmark\n",
-                      $tick_x, $tick_y)
-                   or die $!;
+               o(sprintf "      %f %f regmark\n", $tick_x, $tick_y);
            }
        }
-       printf("    grestore\n")
-           or die $!;
+       o("    grestore\n");
     }
 }
 
+ol("grestore\n");
+
+if (@ident_strings) {
+    my ($is);
+    $is= join('; ', @ident_strings);
+    $is =~ s/[()\\]/\\$&/g;
+    ol("25 50 moveto".
+       "/Courier-New findfont 6 scalefont setfont\n".
+       " ($is) show\n");
+}
+
 oflushpage();