chiark / gitweb /
trim-ps script to make files print faster
[trains.git] / layout / layout
index 0d2db4bab8f6e4b4dab4ae19945894fae8239400..d20102316e4e885b4956c60bcc3c9ce069f8f079 100755 (executable)
@@ -25,12 +25,12 @@ our @eopts;
 our @segments= ('/');
 our %subsegcmap;
 
-our $drawers= 'arsclmnog';
-our %chdraw_emap= qw(A ARScg
-                    R aRscg
-                    S aRScg
-                    C arsCg
-                    c Arscg
+our $drawers= 'arscldmnog';
+our %chdraw_emap= qw(A ARScgd
+                    R aRscgD
+                    S aRScgd
+                    C arsCgd
+                    c Arscgd
                     r arcs
                     L LMg
                     l l
@@ -157,14 +157,19 @@ our $psu_sleeperlen= 17;
 our $psu_sleeperlw= 15;
 our $psu_raillw= 1.0;
 our $psu_thinlw= 1.0;
-our $psu_subseglw= 15.0;
+our %psu_subseglw;
+$psu_subseglw{'e'}= 20.0;
+$psu_subseglw{'m'}= 15.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.0;
 our $lmu_txtboxlw= 1;
 
 our $olu_left= 10 * $scale;
@@ -625,11 +630,14 @@ sub parametric__o_pt ($) {
 
 our $segused_incurrent;
 our $segused_currentpt;
+our $segmentpart_counter=0;
+our $segused_restorecounter;
 
 sub segment_used__print ($) {
     my ($pt) = @_;
-    if ($segused_incurrent > 0) {
+    if ($segused_incurrent > 0 && $segused_restorecounter==1) {
        o("%L segmentpart ".
+         $segmentpart_counter++." ".
          $ctx->{Layer}{Level}.$ctx->{Layer}{Kind}." ".
          $segments[0]." ".
          $segused_incurrent." ".
@@ -655,6 +663,17 @@ sub segment_used__len ($$) {
     o("% segments @segments\n");
 }
     
+sub segment_state_save () {
+    return [ 0, $segused_incurrent, $segused_currentpt,
+            $segmentpart_counter, @segments ];
+}
+sub segment_state_restore ($) {
+    my ($r) = @_;
+    ($segused_restorecounter, $segused_incurrent, $segused_currentpt,
+     $segmentpart_counter, @segments) = @$r;
+    $r->[0]++;
+}
+
 sub segment_used_begin ($) {
     $segused_incurrent= 0;
     $segused_currentpt= $_[0];
@@ -670,10 +689,10 @@ sub segment_used_end ($$) {
 }
 sub parametric_segment ($$$$$) {
     my ($p0,$p1,$lenperp,$minradius,$calcfn) = @_;
-    # makes $p (global) go from $p0 to $p1  ($p1>$p0)
+    # makes $param (global) go from $p0 to $p1  ($p1>$p0)
     # $lenperp is the length of one unit p, ie the curve
     # must have a uniform `density' in parameter space
-    # $calcfn is invoked with $p set and should return a loc
+    # $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]/;
@@ -687,54 +706,61 @@ sub parametric_segment ($$$$$) {
 print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
     $draw= current_draw();
     if ($draw =~ m/G/) {
-       my ($pt,$going,$red,$csegbare,$movfeat,$movstroke,$used_last);
-       $going=0;
-       o("% segments @segments\n");
-       o("    $psu_subseglw setlinewidth\n");
-       $param=$p0;
-       $pt= &$calcfn;
-       segment_used_begin($pt);
-       for (;;) {
-           $movstroke= "      stroke\n";
-           $csegbare= $segments[0];
-           $csegbare =~ s/^\-//;
-           if ($subsegcmapreq) {
-               if (!exists $subsegcmap{$csegbare}) {
-                   print "$csegbare\n" or die $!;
-                   $subsegcmap{$csegbare}++;
-               }
-           } else {
-               $movfeat= $csegbare =~ s,(/\D+)(\d+)$,$1, ? $2 : 'f';
-               if ($subsegmovfeatpos ne $movfeat) {
-                   $movstroke= "%     no-stroke\n";
+       my ($pt,$going,$red,$csegbare,$movfeat,$movstroke);
+       my ($used_last,$me,$segsave);
+       $segsave= segment_state_save();
+       foreach $me (qw(e m)) {
+           segment_state_restore($segsave);
+           $going=0;
+           o("% segments @segments\n");
+           $param=$p0;
+           $pt= &$calcfn;
+           segment_used_begin($pt);
+           for (;;) {
+               $movstroke= "      cmapreq-stroke\n";
+               $csegbare= $segments[0];
+               $csegbare =~ s/^\-//;
+               if ($subsegcmapreq) {
+                   if (!exists $subsegcmap{$csegbare}) {
+                       print "$csegbare\n" or die $!;
+                       $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";
+                   }
                }
-               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 /= 255.0;
-               $red= sprintf("%f", $red);
-               o("    $red $subsegcmap{$csegbare} setrgbcolor\n");
-           }
-           o_path_begin();
-           parametric__o_pt($pt);
+               o_path_begin();
+               parametric__o_pt($pt);
        
-           $param += $ppu;
-           last if $param>=$p1;
+               $param += $ppu;
+               last if $param>=$p1;
+               $pt= &$calcfn;
+               segment_used_middle($psu_ulen,$pt);
+               parametric__o_pt($pt);
+               o($movstroke);
+           }
+           $used_last= $p1-($param-$ppu);
+           $param=$p1;
            $pt= &$calcfn;
-           segment_used_middle($psu_ulen,$pt);
+           segment_used_end($used_last * $lenperp, $pt);
            parametric__o_pt($pt);
            o($movstroke);
        }
-       $used_last= $p1-($param-$ppu);
-       $param=$p1;
-       $pt= &$calcfn;
-       segment_used_end($used_last * $lenperp, $pt);
-       parametric__o_pt($pt);
-        o($movstroke);
     }
     if ($draw =~ m/C/) {
        my ($pt);
@@ -747,6 +773,18 @@ 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});
+       $len= sprintf "%.0f", $lenperp * abs($p1-$p0);
+       ol("      gsave\n".
+          "        $pt->{X} $pt->{Y} translate\n".
+          "        $ad rotate\n".
+          "        lf setfont  0 $lmu_lenboxoff moveto  ($len) show\n".
+          "      grestore\n");
+    }
     return unless $draw =~ m/[ARS]/;
     for ($pa= $p0; $pa<$p1; $pa=$pb) {
        $pb= $pa + $ppu;
@@ -1036,7 +1074,10 @@ sub cmd_join {
 
 sub line ($$$) {
     my ($from,$to,$len) = @_;
-    parametric_segment(0.0, 1.0, abs($len) + 1e-6, undef, sub {
+    if ($len < 0) {
+       ($from,$to,$len) = ($to,$from,-$len);
+    }
+    parametric_segment(0.0, 1.0, $len + 1e-6, undef, sub {
        ev_lincomb({}, $from, $to, $param);
     });
 }
@@ -1434,19 +1475,8 @@ dv("cmd__do $ctx @al ",'$ctx',$ctx);
                   "      $lmu_marklw setlinewidth stroke\n");
            }
            if ($draw =~ m/L/) {
-               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("      $lmu_txtboxlw $lmu_txtboxh $lmu_txtboxpadx".
+                  " $lmu_txtboxoff ($id) label_in_box\n");
            }
            ol("      grestore\n");
        }
@@ -1537,6 +1567,28 @@ 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 $!;