#!/usr/bin/perl -w
use POSIX;
+use IO::Handle;
+use IO::File;
+
use strict;
no strict 'subs';
our $scale= 7.0;
+our $page_x= 0;
+our $page_y= 0;
+our $quiet=0;
+our $debug=0;
+our $output_layer= '*';
+our $subsegcmapreq=0;
+our $subsegmovfeatpos='f';
+our $subsegcmapangscale;
+
+our $ps_page_shift= 615;
+our $ps_page_xmul= 765.354;
+our $ps_page_ymul= 538.583;
+
+our @eopts;
+our @segments= ('/');
+our %subsegcmap;
+
+our $drawers= 'arscldmnog';
+our %chdraw_emap= qw(A ARScgd
+ R aRscgD
+ S aRScgd
+ C arsCgd
+ c Arscgd
+ r arcs
+ L LMg
+ l l
+ M Mnog
+ N MNog
+ O MNOg
+ m mnol
+ G Garsclmno);
+
+while (@ARGV && $ARGV[0] =~ m/^\-/) {
+ last if $ARGV[0] eq '-';
+ $_= shift @ARGV;
+ last if $_ eq '--';
+ s/^\-//;
+ while (length) {
+ if (s/^D(\d+)//) { $debug= $1; }
+ elsif (s/^D//) { $debug++; }
+ elsif (s/^q//) { $quiet=1; }
+ elsif (s/^l(\d+|\*)//) { $output_layer=$1; }
+ elsif (s/^S([0-9.]+)$//) { $scale= $1 * 1.0; }
+ elsif (s/^P(\d+)x(\d+)$//) { $page_x= $1; $page_y= $2; }
+ elsif (s/^GR//) { $subsegcmapreq=1; }
+ elsif (s/^GP(\d+|f)$//) { $subsegmovfeatpos=$1; }
+ elsif (s/^GL(.*)$//) {
+ my ($sscmfn) = $1;
+ my ($sscmf, $datum, $csss, $angbits);
+ local ($_);
+ $sscmf= new IO::File $sscmfn, 'r'
+ or die "$sscmfn: cannot open: $!\n";
+ for (;;) {
+ $!=0; $_= <$sscmf>; die $! unless defined $_;
+ last if m/^E/;
+ next unless m/^C/;
+ m,^C\s+(\w*/(?:[A-Za-z_]+)?)\s+(0x[0-9a-f]+)\s+(\d+)\s*$,
+ or die "$sscmfn:$.: syntax error in subseg cmap\n";
+ ($csss,$datum,$angbits)= ($1,$2,$3);
+ if (!defined $subsegcmapangscale) {
+ $subsegcmapangscale= 1<<$angbits;
+ } else {
+ die "angbits varies" if $subsegcmapangscale != 1<<$angbits;
+ }
+ $datum= hex($datum);
+ if ($datum & 0x0ff) {
+ die "sorry, cannot put any movfeatpos or segment in red";
+ }
+ $subsegcmap{$csss}= sprintf("%.6f %.6f",
+ (($datum >> 8) & 0xff)/255.0,
+ (($datum >> 16) & 0xff)/255.0);
+ }
+ $sscmf->error and die "$sscmfn: error reading: $!\n";
+ close $sscmf;
+ } elsif (s/^(e)
+ ((?:[a-z]|\*|\?|\[[a-z][-a-z]*\])*?)
+ (\~?) (\d*) (\=*|\-+|\++) (\d*|\*)
+ ([a-z]+)$//ix) {
+ my ($ee,$g,$n,$d,$c,$v,$cc) = ($1,$2,$3,$4,$5,$6,$7);
+ my ($eo, $invert, $lfn, $ccc, $sense,$limit);
+ $g =~ s/\?/\./g; $g =~ s/\*/\.\*/g;
+ die '-[eE]GND[=]* not allowed' if $v eq '*' && length $d;
+ $d= $output_layer if !length $d;
+ $d= 5 if $d eq '*';
+ $invert= length $n;
+ $c= '=' if !length $c;
+ if (length $v && $v ne '*') {
+ die '-[eE]GN[D]CCV not allowed' if length $c > 1;
+ $c= $c x $v;
+ }
+ if ($c =~ m/^[-+]/) {
+ die '-[eE]GN+/-* not allowed' if $v eq '*';
+ $sense= ($&.'1') + 0;
+ $limit= ($sense * $d) + length($c) - 1;
+ $lfn= sub {
+ ($output_layer eq '*' ? $d
+ : $_[0]) * $sense >= $limit
+ xor $invert;
+ };
+ } elsif ($v eq '*') {
+ $lfn= sub { !$invert; };
+ } else {
+ $limit= length($c) - 1;
+ $lfn= sub {
+#my ($lfn_result)=(
+ ($output_layer eq '*' ? 1
+ : abs($_[0] - $d) <= $limit)
+ xor $invert
+#)
+ ;
+#print STDERR "output layer $output_layer; asking re $_[0] rel $d lim $limit invert $invert result $lfn_result\n";
+#$lfn_result;
+ };
+ }
+ $ccc= '';
+ foreach $c (split //, $cc) {
+ if ($ee eq 'e') {
+ die "bad -e option $c" unless defined $chdraw_emap{$c};
+ $ccc .= $chdraw_emap{$c};
+ } else {
+ die "bad -E option $c" unless $c =~ m/[$drawers]/i;
+ $ccc .= $c;
+ }
+ }
+ $eo->{GlobRe}= $g;
+ $eo->{LayerCheck}= $lfn;
+ $eo->{DrawMods}= $ccc;
+#print STDERR "created eo $eo re $eo->{GlobRe} n=$n d=$d v=$v c=$c limit=$limit cc=$cc\n";
+ push @eopts, $eo;
+ } elsif (m/^S/) {
+ die "-S option must come right at the start and have numeric arg";
+ } else {
+ die "unknown option -$_";
+ }
+ }
+}
+
our $ptscale= 72/25.4 / $scale;
our $psu_ulen= 4.5;
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;
our $lmu_marklw= 4;
our $lmu_marktpt= 11;
our $lmu_txtboxpadx= $lmu_marktpt * 0.335;
our $lmu_txtboxoff= $lmu_marklw / 2;
our $lmu_txtboxlw= 1;
+our $lmu_lenlabeloff= -$lmu_marklw * 1.0;
our $olu_left= 10 * $scale;
our $olu_right= 217 * $scale - $olu_left;
our $olu_bottom= 20 * $scale;
our $olu_top= 270 * $scale - $olu_bottom;
our $olu_gap_x= 30;
-our $olu_gap_y= 30;
+our $olu_gap_y= 60;
our $olu_textheight= 15;
our $olu_textallowperc= $lmu_marktpt * 5.0/11;
our $pi= atan2(0,-1);
-our $output_layer= '*';
sub allwidth2 ($) {
my ($radius)= @_;
# Data structures:
# $ctx->{CmdLog}= undef } not in defobj
# $ctx->{CmdLog}[]= [ command args ] } in defobj
-# $ctx->{LocsMade}[]{Id}= $id
-# $ctx->{LocsMade}[]{Neg}= $id
+# $ctx->{Parent}= $parent_ctx or undef
+# $ctx->{LocsMade}[]{Id}= $id
+# $ctx->{LocsMade}[]{Neg}= 1 or 0
# $ctx->{Loc}{$id}{X}
# $ctx->{Loc}{$id}{Y}
# $ctx->{Loc}{$id}{A}
+# $ctx->{Loc}{$id}{LayerKind}
# $ctx->{Trans}{X} # transformation. is ev representing
# $ctx->{Trans}{Y} # new origin. (is applied at _input_
# $ctx->{Trans}{A} # not at plot-time)
# $ctx->{Trans}{R} # but multiply all y coords by this!
# $ctx->{Draw} # sequence of one or more chrs from uc $drawers
-# # or X meaning never draw anything (eg in defobj)
+# # possibly including X meaning never draw
+# # anything now (eg in defobj)
+# $ctx->{DrawMap} # =$fn s.t.
+# # &$fn($drawchrs_spec_by_layer_cmdline)
+# # = $drawchrs_we_should_use_due_to_obj_etc
+# $ctx->{SegName} # initial segment name (at start of object or file)
+# # or nonexistent if in object in unknown segment
+# # may have leading `-'
+# $ctx->{SegMapN}{$s}= $o
+# $ctx->{SegMapNM}{$s}= $o
+# $ctx->{SavedSegment} # exists iff segment command used, is a $csss
# $ctx->{Layer}{Level}
# $ctx->{Layer}{Kind}
#
# $eopts[]{GlobRe} # regexp for K
# $eopts[]{LayerCheck} # =$fn where &$fn($l) is true iff layer matches
# $eopts[]{DrawMods} # modifier chars for drawing
+#
+# @segments= ( $csss0, $dist0, $csss1, $dist1, ..., $csssn )
+# # here each csss may have preceding `-'
+#
+# $subsegcmap{$csss} = "$green $blue"
+# # $csss is canonical subseg spec; always has '/'
our $ctx;
our %objs;
-our @eopts;
our @al; # current cmd
our $o='';
our $ol='';
-our $param; # for parametric_curve
-our $debug=0;
+our $param; # for parametric_segment
# ev_... functions
#
$neg = $sp =~ s/^\-//;
$id=cva_idstr($sp);
die "duplicate $id" if exists $ctx->{Loc}{$id};
- exists $ctx->{Loc}{$id}{X};
- push @{ $ctx->{LocsMade} }, { Id => $id, Neg => $neg };
+ $ctx->{Loc}{$id}{LayerKind}= $ctx->{Layer}{Kind};
+ push @{ $ctx->{LocsMade} }, {
+ Id => $id,
+ Neg => $neg,
+ };
return $ctx->{Loc}{$id};
}
sub cva_cmd ($) { return cva_idstr($_[0]); }
sub o ($) { $o .= $_[0]; }
sub ol ($) { $ol .= $_[0]; }
sub oflushpage () {
+ return if $subsegcmapreq;
print $o, $ol, " showpage\n"
or die $!;
$o=$ol='';
sub o_path_stroke ($) {
my ($width)=@_;
o(" $width setlinewidth stroke\n");
-}
+}
+sub o_path_strokeonly () {
+ o(" stroke\n");
+}
sub o_line ($$$) {
my ($a,$b,$width)=@_;
o_path_stroke($width);
}
+sub current_draw () {
+ my ($r);
+ $r= $ctx->{Draw} =~ m/X/ ? '' : $ctx->{Draw};
+ $r;
+}
+
sub psu_coords ($$$) {
my ($ends,$inunit,$across)=@_;
# $ends->[0]{X} etc.; $inunit 0 to 1 (but go to 1.5);
o_path_point("$pt->{X} $pt->{Y}");
}
+our $segused_incurrent;
+our $segused_currentpt;
+our $segmentpart_counter=0;
+our $segused_restorecounter;
+
+sub segment_used__print ($) {
+ my ($pt) = @_;
+ if ($segused_incurrent > 0 && $segused_restorecounter==1) {
+ o("%L segmentpart ".
+ $segmentpart_counter++." ".
+ $ctx->{Layer}{Level}.$ctx->{Layer}{Kind}." ".
+ $segments[0]." ".
+ $segused_incurrent." ".
+ loc2dbg($segused_currentpt)." ".
+ loc2dbg($pt)."\n");
+ }
+ $segused_incurrent= undef;
+ $segused_currentpt= undef;
+}
+
+sub segment_used__len ($$) {
+ my ($used,$pt) = @_;
+ $segused_incurrent++;
+
+ return if @segments < 3;
+ $segments[1] -= $used;
+ return if $segments[1] > 0;
+
+ segment_used__print($pt);
+ segment_used_begin($pt);
+
+ @segments= @segments[2..$#segments];
+ 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];
+}
+sub segment_used_middle ($$) {
+ my ($used,$pt) = @_;
+ segment_used__len($used,$pt);
+}
+sub segment_used_end ($$) {
+ my ($used,$pt) = @_;
+ segment_used__len($used,$pt);
+ segment_used__print($pt);
+}
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/[ARSC]/;
+ return unless $ctx->{Draw} =~ m/[ARSCG]/;
$ppu= $psu_ulen/$lenperp;
$allwidth= allwidth($minradius);
my ($railctr)=($psu_gauge + $psu_raillw)*0.5;
my ($sleeperctr)=($psu_ulen*0.5);
my ($sleeperend)=($psu_sleeperlen*0.5);
print DEBUG "ps $p0 $p1 $lenperp ($ppu)\n";
- $draw= $ctx->{Draw};
+ $draw= current_draw();
+ if ($draw =~ m/G/) {
+ 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";
+ }
+ }
+ o_path_begin();
+ parametric__o_pt($pt);
+
+ $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_end($used_last * $lenperp, $pt);
+ parametric__o_pt($pt);
+ o($movstroke);
+ }
+ }
if ($draw =~ m/C/) {
my ($pt);
o(" $psu_thinlw setlinewidth\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_lenlabeloff moveto ($len) show\n".
+ " grestore\n");
+ }
return unless $draw =~ m/[ARS]/;
for ($pa= $p0; $pa<$p1; $pa=$pb) {
$pb= $pa + $ppu;
o("r_j=$rj r_b=$rb ");
if ($rj * $rb < 0) { o(" backwards b\n"); next; }
if (abs($rj) < $minradius) { o(" too-small\n"); next; }
+ o("ok\n");
$j->{A}= $ap->{A};
$c->{A}= 0;
$path= [{ T => Line, A => $ap, B => $j, L => $aja },
elsif ($1 eq 'end') { $cs= $bends[$#bends]; }
else { $cs=0; map { $cs += $_ } @bends; }
$cs= -$cs if $2 eq 'left';
- } elsif ($crit =~ m/^(\!?)(twoarcs|arcline|cross|loop)$/) {
+ } elsif ($crit =~ m/^(\!?)(twoarcs|arcs?line|cross|loop)$/) {
$cs= !!(grep { $2 eq $_ } @$skl) != ($1 eq '!');
} else {
die "unknown sort criterion $crit";
sub line ($$$) {
my ($from,$to,$len) = @_;
- parametric_segment(0.0, 1.0, abs($len), 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);
});
}
my ($ctx_save) = @_;
$ctx= {
Trans => { X => 0.0, Y => 0.0, A => 0.0, R => 1.0 },
- InRunObj => ""
+ InRunObj => "",
+ DrawMap => sub { $_[0]; },
+ SegMapN => { },
+ SegMapNM => { }
};
- %{ $ctx->{Layer} }= %{ $ctx_save->{Layer} }
- if defined $ctx_save;
+ if (defined $ctx_save) {
+ %{ $ctx->{Layer} }= %{ $ctx_save->{Layer} };
+ $ctx->{Parent}= $ctx_save;
+ }
}
our $defobj_save;
newctx($defobj_save);
$ctx->{CmdLog}= [ ];
$ctx->{InDefObj}= $id;
- $ctx->{Draw}= 'X';
+ $ctx->{Draw}= $defobj_save->{Draw}.'X';
+ $ctx->{DrawMap}= sub { ''; };
$ctx->{Layer}= { Level => 5, Kind => '' };
}
}
}
-sub cmd_layer {
- my ($kl, $k,$l, $eo,$cc);
- $kl= can(\&cva_identity);
- $kl =~ m/^([A-Za-z_]*)(\d*|\=)$/ or die "invalid layer spec";
- ($k,$l)=($1,$2);
- $l= $ctx->{Layer}{Level} if $l =~ m/^\=?$/;
- $ctx->{Layer}{Kind}= $l;
- $ctx->{Layer}{Level}= $l;
- return if $ctx->{Draw} =~ m/X/;
- if ($output_layer ne '*' && $l != $output_layer) {
- $ctx->{Draw} = '';
- } elsif ($k eq '') {
- $ctx->{Draw}= 'RLMN';
+sub cva_subsegspec ($) {
+ my ($sp)=@_;
+ die "invalid subsegment spec" unless
+ $sp =~ m,^(\-?)([0-9A-Za-z_]*)(?:/(?:([A-Za-z_]+)(\d+))?)?$,;
+ my ($sign,$segname,$movfeat,$movconf)=($1,$2,$3,$4);
+
+ if (!exists $ctx->{SegName}) {
+ $segname= '';
+ $sign= '';
+ } else {
+ my ($map_ctx);
+
+ $ctx->{SegName} =~ m/^\-?/ or die;
+ $sign .= $&;
+ $segname= $'.$segname;
+
+ for ($map_ctx= $ctx;
+ defined $map_ctx;
+ $map_ctx= $map_ctx->{Parent}) {
+ if (defined $movfeat &&
+ exists $map_ctx->{SegMapNM}{"$segname/$movfeat"}) {
+ $movfeat= $map_ctx->{SegMapNM}{"$segname/$movfeat"};
+ }
+ if (exists $map_ctx->{SegMapN}{$segname}) {
+ $map_ctx->{SegMapN}{$segname} =~ m/^\-?/ or die;
+ $sign .= $&;
+ $segname= $';
+ }
+ }
+ $sign =~ s/\-\-//g;
+ }
+
+ return $sign.$segname.'/'.
+ (defined $movfeat ? sprintf "%s%d", $movfeat, $movconf : '');
+}
+
+sub cmd_segment {
+ my ($csss,$length);
+ $ctx->{SavedSegment}= pop @segments
+ unless exists $ctx->{SavedSegment};
+ @segments= ();
+ while (@al>1) {
+ $csss= can(\&cva_subsegspec);
+ $length= can(\&cva_len);
+ push @segments, $csss, $length;
+ }
+ $csss= can(\&cva_subsegspec);
+ push @segments, $csss;
+}
+
+sub cva_segmap_s {
+ my ($sp) = @_;
+ $sp =~ m,^\w+(?:/[a-zA-Z_]+)?$,
+ or die "invalid (sub)segment mapping S \`$sp'";
+ return $sp;
+}
+
+sub cva_segmap_n {
+ my ($sp) = @_;
+ $sp =~ m,^\-?\w+$, or die "invalid segment mapping N' \`$sp'";
+ return $sp;
+}
+
+sub cva_segmap_m {
+ my ($sp) = @_;
+ $sp =~ m,^[a-zA-Z_]+$, or die "invalid segment mapping M' \`$sp'";
+ return $sp;
+}
+
+sub cmd_segmap {
+ my ($s,$d);
+ while (@al) {
+ $s= can(\&cva_segmap_s);
+ if ($s =~ m,/,) {
+ $ctx->{SegMapNM}{$s}= can(\&cva_segmap_m);
+ } else {
+ $ctx->{SegMapN}{$s}= can(\&cva_segmap_n);
+ }
+ }
+}
+
+sub layer_draw ($$) {
+ my ($k,$l) = @_;
+ my ($eo,$cc, $r);
+ if ($k eq '') {
+ $r= 'RLMN';
} elsif ($k eq 's') {
- $ctx->{Draw}= '';
+ $r= '';
} elsif ($k eq 'l') {
- $ctx->{Draw}= 'CLMN';
+ $r= 'CLMN';
} else {
- $ctx->{Draw}= 'ARSCLMNO';
+ $r= 'ARSCLMNO';
}
foreach $eo (@eopts) {
+#print STDERR "$. layer $k$l eo $eo re $eo->{GlobRe} then $eo->{DrawMods} now $r\n";
next unless $k =~ m/^$eo->{GlobRe}$/;
+#print STDERR "$. layer $k$l eo re $eo->{GlobRe} match\n";
next unless &{ $eo->{LayerCheck} }($l);
+#print STDERR "$. layer $k$l eo re $eo->{GlobRe} checked\n";
foreach $cc (split //, $eo->{DrawMods}) {
- $ctx->{Draw} =~ s/$cc//ig;
- $ctx->{Draw} .= $cc if $cc =~ m/[A-Z]/;
+ $r =~ s/$cc//ig;
+ $r .= $cc if $cc =~ m/[A-Z]/;
}
}
+#print STDERR "layer $k$l gives $r (before map)\n";
+ $r= &{ $ctx->{DrawMap} }($r);
+ return $r;
+}
+
+sub cmd_layer {
+ my ($kl, $k,$l);
+ $kl= can(\&cva_identity);
+ $kl =~ m/^([A-Za-z_]*)(\d*|\=|\*)$/ or die "invalid layer spec";
+ ($k,$l)=($1,$2);
+ $l= $output_layer if $l eq '*';
+ $l= $ctx->{Layer}{Level} if $l =~ m/^\=?$/;
+ $ctx->{Layer}{Kind}= $k;
+ $ctx->{Layer}{Level}= $l;
+ $ctx->{Draw}= layer_draw($k,$l);
}
sub cmd_part { cmd__obj(Part); }
} else {
$ctx->{InRunObj}= $ctx_save->{InRunObj}."${obj_id}::";
}
- $ctx->{Draw}= $ctx_save->{Draw};
- if ($obj->{Part}) {
- $ctx->{Draw} =~ s/[LMN]//g;
- $ctx->{Draw} =~ s/O/MNO/;
- } else {
- $ctx->{Draw} =~ s/[LM]//g;
- $ctx->{Draw} =~ s/N/MN/;
+ if ($segments[0] =~ m,(.*[^-]+)/,) {
+ $ctx->{SegName}= $1;
}
+ $ctx->{DrawMap}= sub {
+ my ($i) = @_;
+ $i= &{ $ctx_save->{DrawMap} }($i);
+ if ($obj->{Part}) {
+ $i =~ s/[LMN]//g;
+ $i =~ s/O/MNO/;
+ } else {
+ $i =~ s/[LM]//g;
+ $i =~ s/N/MN/;
+ }
+ return $i;
+ };
+ $ctx->{Draw}= &{ $ctx->{DrawMap} }($ctx_save->{Draw});
cmd__runobj($obj_id);
if (defined $part_name) {
$pfx= $part_name.'_';
$pfx= cano(\&cva_idstr,undef);
}
}
+ if (exists $ctx->{SavedSegment}) {
+ @segments= ($ctx->{SavedSegment});
+ }
$ctx_inobj= $ctx;
$ctx= $ctx_save;
if (defined $pfx) {
my ($cmd);
dv("cmd__do $ctx @al ",'$ctx',$ctx);
$cmd= can(\&cva_cmd);
- my ($lm,$id,$loc,$io,$ad);
+ my ($lm,$id,$loc,$io,$ad,$draw,$thendrawre);
$io= defined $ctx->{InDefObj} ? "$ctx->{InDefObj}!" : $ctx->{InRunObj};
o("%L cmd $io $cmd @al\n");
$ctx->{LocsMade}= [ ];
$loc->{A} += $pi if $lm->{Neg};
$ad= ang2deg($loc->{A});
ol("%L point $io$id ".loc2dbg($loc)." ($lm->{Neg})\n");
- if ($ctx->{Draw} =~ m/[LM]/) {
+ $draw= layer_draw($loc->{LayerKind}, $ctx->{Layer}{Level});
+ if ($draw =~ m/[LM]/) {
ol(" gsave\n".
" $loc->{X} $loc->{Y} translate $ad rotate\n");
- if ($ctx->{Draw} =~ m/M/) {
+ if ($draw =~ m/M/) {
ol(" 0 $allwidthmin newpath moveto\n".
" 0 -$allwidthmin lineto\n".
" $lmu_marklw setlinewidth stroke\n");
}
- if ($ctx->{Draw} =~ m/L/) {
+ if ($draw =~ m/L/) {
ol(" /s ($id) def\n".
" lf setfont\n".
" /sx5 s stringwidth pop\n".
cmd__do();
}
-print
- "%!\n".
- " /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
- " 615 0 translate 90 rotate\n".
- " $ptscale $ptscale scale\n"
- or die $!;
-
-newctx();
+o("%!\n".
+ " /lf /Courier-New findfont $lmu_marktpt scalefont def\n".
+ " $ps_page_shift 0 translate 90 rotate\n");
-our $drawers= 'arsclmno';
-our %chdraw_emap= qw(A ARSc
- R aRsc
- S aRSc
- C arsC
- c Arsc
- L LM
- l l
- M Mno
- N MNo
- O MNO
- m mnol);
+if ($page_x || $page_y) {
+ o(" /Courier-New findfont 15 scalefont setfont\n".
+ " 30 30 moveto (${page_x}x${page_y}) show\n");
+}
-our $quiet=0;
+o(" -$ps_page_xmul $page_x mul -$ps_page_ymul $page_y mul translate\n".
+ " $ptscale $ptscale scale\n");
-while (@ARGV && $ARGV[0] =~ m/^\-/) {
- last if $ARGV[0] eq '-';
- $_= shift @ARGV;
- last if $_ eq '--';
- s/^\-//;
- while (length) {
- if (s/^D(\d+)//) { $debug= $1; }
- elsif (s/^D//) { $debug++; }
- elsif (s/^q//) { $quiet=1; }
- elsif (s/^(e)
- ((?:[a-z]|\*|\?|\[[a-z][-a-z]*\])*?)
- (\~?) (\d*) (\=*|\-+|\++) (\d*)
- ([a-z]+)//ix) {
- my ($ee,$g,$n,$d,$c,$v,$cc) = ($1,$2,$3,$4,$5,$6,$7);
- my ($eo, $invert, $lfn, $ccc, $sense,$limit);
- $g =~ s/[?*]/\\$&/g;
- $d= $output_layer if !length $d;
- $d= 5 if $d eq '*';
- $invert= length $n;
- $c= '=' if !length $c;
- if (length $v) {
- die '-[eE]GN[D]CCV not allowed' if length $c > 1;
- $c= $c x $v;
- }
- if ($c =~ m/^[-+]/) {
- $sense= ($c.'1') + 0;
- $limit= ($sense * $d) + length($c) - 1;
- $lfn= sub {
- ($output_layer eq '*' ? $d
- : $_[0]) * $sense >= $limit
- xor $invert;
- };
- } else {
- $limit= length($c) - 1;
- $lfn= sub {
- ($output_layer eq '*' ? 1
- : abs($_[0] - $d) <= $limit)
- xor $invert;
- };
- }
- $ccc= '';
- foreach $c (split //, $cc) {
- if ($ee eq 'e') {
- die "bad -e option $c" unless defined $chdraw_emap{$c};
- $ccc .= $chdraw_emap{$c};
- } else {
- die "bad -E option $c" unless $c =~ m/[$drawers]/i;
- $ccc .= $c;
- }
- }
- $eo->{GlobRe}= $g;
- $eo->{LayerCheck}= $lfn;
- $eo->{DrawMods}= $ccc;
- push @eopts, $eo;
- } else {
- die "unknown option -$_";
- }
- }
-}
+newctx();
open DEBUG, ($debug ? ">&2" : ">/dev/null") or die $!;
}
$ctx->{Draw}= '';
+$ctx->{SegName}= '';
@al= qw(layer 5);
cmd__one();
cmd__one();
}
-oflushpage();
-
{
my ($min_x, $max_x, $min_y, $max_y) = bbox($ctx->{Loc});
my ($bboxstr);
}
if (!$quiet) { print STDERR $bboxstr; }
$bboxstr =~ s/^/\%L bbox /mg;
- print $bboxstr or die $!;
+ o($bboxstr) or die $!;
+
+ 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 $!;
+ 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 $!;
+ }
+ }
+ printf(" grestore\n")
+ or die $!;
+ }
}
+
+oflushpage();