chiark / gitweb /
wip labelling for E
[trains.git] / layout / layout
index c8df20a3c5cf69d0cface18d9f424afecad0c696..87d5c66c33aed1f488b80056642c4a9c97cf611b 100755 (executable)
@@ -30,7 +30,7 @@ our @ident_strings= ();
 our %subsegcmap;
 our %segcmap;
 
-our $drawers= 'arqscldmnog';
+our $drawers= 'arqscldmnoge';
 our %chdraw_emap= qw(A ARScgd
                     R aRscgD
                     S aRScgd
@@ -165,9 +165,12 @@ our $psu_sleeperlw= 15;
 our $psu_raillw= 1.0;
 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_segtpt= 25;
+our $lmu_segtxtoff= -8;
 
 our $lmu_marklw= 4;
 our $lmu_marktpt= 11;
@@ -245,9 +248,21 @@ our $allwidthmin= allwidth(undef);
 #
 #  $subsegcmap{$csss} = "$green $blue"
 #                         # $csss is canonical subseg spec; always has '/'
+#  $segcmap{$bareseg} = "$postscript"
+#
+#  $seggraphends{"$bareseg"}[]{X}
+#  $seggraphends{"$bareseg"}[]{Y}
+#  $seggraphends{"$bareseg"}[]{A}
+#  $seggraphends{"-$bareseg"}[]...
+#  $seggraphend[0]{X}
+#  $seggraphend[0]{Y}
+#  $seggraphend[1]{X}
+#  $seggraphend[1]{Y}
 
 our $ctx;
 our %objs;
+our %seggraphends;
+our @seggraphend;
 our @al; # current cmd
 
 our $o='';
@@ -357,11 +372,22 @@ sub v_add ($;@) {
     # v_add(A,B,...)
     # vector sum of all inputs
     my (@i) = @_;
+#print STDERR "add ".join('|',keys %{$i[0]}),"<\n";
+#map { print STDERR " ".join('|',keys %{$_}),"<\n"; } @i;
     my ($r,$i);
     $r= { X => 0.0, Y => 0.0 };
     foreach $i (@i) { $r->{X} += $i->{X}; $r->{Y} += $i->{Y}; }
     return $r;
-}    
+}
+sub v_mean (;@) {
+    my (@i) = @_;
+#print STDERR "mean ".join('|',keys %{$i[0]}),"<\n";
+#map { print STDERR " ".join('|',keys %{$_}),"<\n"; } @i;
+    my ($r) = v_add($i[0],@i[1..$#i]);
+    $r->{X} /= @i;
+    $r->{Y} /= @i;
+    return $r;
+}
 sub v_subtract ($$) {
     # v_subtract(A,B)
     # returns vector from A to B, ie B - A
@@ -601,6 +627,15 @@ sub o_path_strokeonly () {
     o("      stroke\n");
 }
 
+sub o_transform ($) {
+    my ($pt) = @_;
+    my ($ad);
+    $ad= ang2deg($pt->{A});
+    ol("      gsave\n".
+       "        $pt->{X} $pt->{Y} translate\n".
+       "        $ad rotate\n");
+}
+
 sub o_line ($$$) {
     my ($a,$b,$width)=@_;
     o_path_begin();
@@ -682,13 +717,31 @@ sub segment_state_restore ($) {
     $r->[0]++;
 }
 
+sub segment__check_graphends () {
+    my ($bare,$ge,$i,$key);
+    @seggraphend= ();
+    $segments[0] =~ m/^\-?(\w+)/ or return;
+    $bare= $1;
+    foreach $i (qw(0 1)) {
+       $key= ('', '-')[$i].$bare;
+       $ge= $seggraphends{$key};
+       defined $ge or return;
+#print STDERR "$key @$ge\n";
+#map { print STDERR " ".join('|',keys %{$_}),"<\n"; } @$ge;
+       $seggraphend[$i]= v_mean(@$ge);
+#print STDERR "SGE $i $seggraphend[$i]{X} $seggraphend[$i]{Y}\n";
+    }
+}
+
 sub segment_used_begin ($) {
     $segused_incurrent= 0;
     $segused_currentpt= $_[0];
+    segment__check_graphends();
 }
 sub segment_used_middle ($$) {
     my ($used,$pt) = @_;
     segment_used__len($used,$pt);
+    segment__check_graphends();
 }
 sub segment_used_end ($$) {
     my ($used,$pt) = @_;
@@ -702,8 +755,8 @@ sub parametric_segment ($$$$$) {
     # must have a uniform `density' in parameter space
     # $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/[ARSCGQ]/;
+    my ($pa,$pb,@ends,$side,$ppu,$e,$v,$tick,$draw,$allwidth,%seglabel);
+    return unless $ctx->{Draw} =~ m/[ARSCGQE]/;
     $ppu= $psu_ulen/$lenperp;
     $allwidth= allwidth($minradius);
     my ($railctr)=($psu_gauge + $psu_raillw)*0.5;
@@ -713,9 +766,9 @@ sub parametric_segment ($$$$$) {
     my ($sleeperend)=($psu_sleeperlen*0.5);
 print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
     $draw= current_draw();
-    if ($draw =~ m/[QG]/) {
+    if ($draw =~ m/[QGE]/) {
        my ($pt,$going,$red,$csegbare,$movfeat,$movstroke);
-       my ($used_last,$me,$segsave);
+       my ($used_last,$me,$segsave,$diff);
        o("gsave\n");
        $segsave= segment_state_save();
        foreach $me ($draw =~ m/Q/ ? qw(q) : qw(e m)) {
@@ -759,19 +812,35 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
                            ($me eq 'e' && $csegbare =~ m,^/,)) {
                            $movstroke= "%     no-stroke    ";
                        }
+                   } else {
+                       $movstroke= "!! seglabels-only ";
                    }
                    $movstroke .=
                        "    $psu_subseglw{$me} setlinewidth stroke\n";
                }
-               o_path_begin();
-               parametric__o_pt($pt);
-
+               if ($draw =~ m/[QG]/) {
+                   o_path_begin();
+                   parametric__o_pt($pt);
+               }
                $param += $ppu;
                last if $param>=$p1;
                $pt= &$calcfn;
+               if ($draw =~ m/E/ && @seggraphend==2) {
+                   $diff= v_len(v_subtract($pt, $seggraphend[0])) -
+                          v_len(v_subtract($pt, $seggraphend[1]));
+                   if (abs($diff) < $psu_ulen*3) {
+                       $segments[0] =~ m/^(\-?)(\w+)/;
+                       $seglabel{$2}{X}= $pt->{X};
+                       $seglabel{$2}{Y}= $pt->{Y};
+                       $seglabel{$2}{A}= $pt->{A};
+                       $seglabel{$2}{A} += $pi if length($1);
+                   }
+               }
                segment_used_middle($psu_ulen,$pt);
-               parametric__o_pt($pt);
-               o($movstroke);
+               if ($draw =~ m/[QG]/) {
+                   parametric__o_pt($pt);
+                   o($movstroke);
+               }
            }
            $used_last= $p1-($param-$ppu);
            $param=$p1;
@@ -793,6 +862,20 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
        parametric__o_pt(&$calcfn);
        o("      stroke\n");
     }
+    if ($draw =~ m/E/) {
+       my ($pt,$seg);
+       foreach $seg (keys %seglabel) {
+           $pt= $seglabel{$seg};
+           ol("    gsave\n");
+           o_transform($pt);
+           ol("      /s ($seg) def\n".
+              "      sf setfont\n".
+              "      0 0 moveto\n".
+              "      s stringwidth pop -0.5 mul  $lmu_segtxtoff  moveto\n".
+              "      s show\n".
+              "      grestore\n");
+       }
+    }
     if ($draw =~ m/[ARS]/) { for ($pa= $p0; $pa<$p1; $pa=$pb) {
        $pb= $pa + $ppu;
        $param= $pa; $ends[0]= @ends ? $ends[1] : &$calcfn;
@@ -835,16 +918,14 @@ print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
        o("      grestore\n");
     } }
     if ($draw =~ m/D/) {
-       my ($pt,$ad,$len,$off);
+       my ($pt,$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".
+       ol("      gsave\n");
+       o_transform($pt);
+       ol("        lf setfont\n".
           "        0 $off moveto\n".
           "        ($len) show\n".
           "      grestore\n");
@@ -1249,7 +1330,13 @@ sub cmd__runobj ($) {
 
 sub cva_segment ($) {
     my ($sp)=@_;
-    die "invalid segment" if $sp =~ m/[^0-9A-Za-z_]/;
+    die "invalid segment" if $sp =~ m/\W/;
+    return $sp;
+}
+
+sub cva_segment_n ($) {
+    my ($sp)=@_;
+    die "invalid segment" if $sp =~ m/[^-0-9A-Za-z_]/;
     return $sp;
 }
 
@@ -1321,7 +1408,7 @@ sub cva_segmap_m {
     $sp =~ m,^[a-zA-Z_]+$, or die "invalid segment mapping M' \`$sp'";
     return $sp;
 }
-    
+
 sub cmd_segmap {
     my ($s,$d);
     while (@al) {
@@ -1334,10 +1421,6 @@ sub cmd_segmap {
     }
 }
 
-sub cmd_segend {
-    @al=();
-};
-
 sub cmd_segcmap {
     my ($seg,$colour);
     $seg= can(\&cva_segment);
@@ -1345,6 +1428,14 @@ sub cmd_segcmap {
     @al= ();
 };
 
+sub cmd_segend {
+    my ($from,$sp) = @_;
+    $from= can(\&cva_idex);
+    $sp= can(\&cva_segment_n);
+#print STDERR "setting $from ".join('|',keys %$from),"<\n";
+    push @{ $seggraphends{$sp} }, $from;
+};
+
 sub layer_draw ($$) {
     my ($k,$l) = @_;
     my ($eo,$cc, $r);
@@ -1624,6 +1715,7 @@ sub cmd__one {
 
 o("%!\n".
   "  /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
+  "  /sf /Courier-Bold findfont $lmu_segtpt scalefont def\n".
   "  $ps_page_shift 0 translate 90 rotate\n".
   "  gsave\n");