use strict;
no strict 'subs';
+our $file_lineno= 0;
+our $file_filename;
+
our $scale= 7.0;
our $page_x= 0;
our $page_y= 0;
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
r arcs
L LMg
l l
+ D D
+ d d
M Mnog
N MNog
O MNOg
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;
sub ol ($) { $ol .= $_[0]; }
sub oflushpage () {
return if $subsegcmapreq;
+
print $o, $ol, " showpage\n"
or die $!;
$o=$ol='';
sub segment_used__len ($$) {
my ($used,$pt) = @_;
- $segused_incurrent++;
+ $segused_incurrent += $used;
return if @segments < 3;
$segments[1] -= $used;
# $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;
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");
$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;
parametric__o_pt($pt);
o($movstroke);
}
+ o("grestore\n");
}
if ($draw =~ m/C/) {
my ($pt);
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;
}
}
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 ($$$$$) {
}
}
+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
}
}
+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);
" $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);
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".
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 $!;
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+/, $_;
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();