chiark / gitweb /
wip
[quacks.git] / overflow-tube.ps.pl
1 #!/usr/bin/perl -w
2 # Books of Pumpkins, etc.  Extensions to Quacks of Quedlinburg
3 #  SPDX-License-Identifier: GPL-3.0-or-later OR CC-BY-SA-4.0
4 # Copyright 2020-2022 Ian Jackson
5
6 use strict;
7
8 BEGIN { unshift @INC, '.'; }
9 use Quacks;
10
11 sub o {
12   local $_;
13   for (@_) { $ps_framing .= $_ }
14 }
15
16 ps_start(<<END);
17 %90 rotate
18 %0 -210 translate
19 END
20
21 my $x_cut = 27;
22 my $y_cutd = 10;
23
24 my $nrepis = 4;
25
26 my $paper_x = 210;
27
28 my $spacing = 23;
29 my $colspacing = 23;
30 my $vhalf = sqrt( $spacing ** 2 - ($colspacing*0.5) ** 2 );
31
32 my $y_cut = 2.75 * $spacing;
33
34 my $x_pl_zero = $paper_x*0.5 - 3*$colspacing;
35 my $y_pl_zero = $y_cut + $spacing - $y_cutd* 0.5 * $x_cut/$colspacing;
36
37 my $y_top = $y_pl_zero + $y_cutd + $spacing*1.25;
38
39 sub some_cut_line($) {
40   <<END;
41 gsave
42   0.5 setgray
43   $_[0]
44 grestore
45 END
46 }
47
48
49 o <<GS, some_cut_line(<<GR), <<END;
50 /cut_line {
51 GS
52                               newpath
53   $x_cut 0                    moveto
54   $x_cut $y_cut               lineto
55   0      $y_cut $y_cutd add   lineto
56   0      $y_top               lineto
57                               stroke
58 GR
59 } def
60 END
61
62 o <<END;
63     /Helvetica-Bold findfont 6.5 scalefont setfont
64 END
65
66 sub places ($) {
67   my ($repi) = @_;
68   my $data = <<END;
69     -1-L*H -1
70         -1  0   34 14
71         -H  V   34 14 1
72          0  0   34 15
73          0 -1   35 15
74          0 -2   35 16
75          H -2-V 35 16 1
76          1 -2   36 16
77          1 -1   37 16
78      1+R*H  0
79 END
80   my $line;
81   my $line_word = 'moveto';
82
83   my $o = '';
84
85   $o .= <<END;
86     gsave
87 END
88   foreach (split /\n/, $data) {
89     s{\#.*}{};
90     next unless m/\S/;
91     s{^\s*}{};
92     s{L}{ ($repi == 0         ? 1 : 0) }ge;
93     s{R}{ ($repi == $nrepis-1 ? 1 : 0) }ge;
94     s{H}{ 0.5 }ge;
95     s{V}{ $vhalf / $spacing }ge;
96     my ($x,$y,$money,$veeps,$ruby) = map { eval $_ } split /\s+/;
97     $ruby ||= 0;
98     $x *= $colspacing;
99     $y *= $spacing;
100     $x += $x_pl_zero;
101     $y += $y_pl_zero;
102
103     $line .= " $x $y $line_word";
104     $line_word = 'lineto';
105     next unless defined $money;
106
107     $money += 4 * $repi;
108     $veeps += 2 * $repi;
109
110     my $sqx = 4.1;
111     my $sqy = 3.2;
112
113     $o .= <<END;
114 % place $x $y $money $veeps $ruby
115 gsave
116   $x $y translate
117   gsave ${\ chip($anychip, 0) } grestore
118   -4 1 moveto ($money) show
119
120   gsave
121     -1.5 -3.0 translate
122
123     gsave
124       newpath  -$sqx -$sqy moveto
125                -$sqx  $sqy lineto
126                 $sqx  $sqy lineto
127                 $sqx -$sqy lineto closepath
128
129        gsave 1 setgray fill grestore
130        0.5 setlinewidth
131        stroke
132     grestore
133
134     0 0 moveto
135     ($veeps) dup  stringwidth pop -0.5 mul -2.5 rmoveto  show
136   grestore
137
138 END
139
140     $o .= <<END if $ruby;
141  gsave
142    6 -1 translate
143    0.8 dup scale
144    ${ \ruby() }
145  grestore
146 END
147
148     $o .= <<END;
149 grestore
150 END
151   }
152   $o .= <<END;
153     grestore
154 END
155
156   (" newpath $line stroke ", $o)
157 }
158
159 sub repis () {
160   for my $places_i (qw(0 1)) {
161     for my $repi (0..$nrepis-1) {
162       o(<<END);
163 % repi $places_i $repi
164 gsave
165   $repi $colspacing 2 mul mul  0 translate
166 END
167
168       o( (places($repi))[$places_i] );
169       o(<<END);
170 grestore
171 END
172     }
173   }
174 }
175
176 sub set () {
177   o(<<END);
178     cut_line
179     gsave
180       $paper_x $x_cut sub  0 translate
181       cut_line
182     grestore
183 END
184   o some_cut_line <<END;
185                                  newpath
186     0                    $y_top  moveto
187     $paper_x $x_cut sub  $y_top  lineto
188                                  stroke
189 END
190
191   repis();
192
193   o <<END;
194     gsave
195       $paper_x $x_cut sub  $y_top 7 sub translate
196
197       gsave
198         arrowlen 2 add neg  0 translate
199         ${\ arrow_any("arrowlen 0 moveto  -30 0 rlineto") }
200       grestore
201
202       -40 0 translate
203       /Helvetica-Bold findfont 6.5 scalefont setfont
204
205      0 0 moveto
206      (+8) show
207     grestore
208 END
209 }
210
211 set();
212 o <<END;
213 gsave 0 $y_top translate
214 END
215 set();
216 o <<END;
217 grestore
218 END
219
220 print $ps_framing or die $!;