chiark / gitweb /
0ca63cd2eef265a66ae9d4ae82448a38f400e763
[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 $x_cutd = 1;
23 my $x_cut2 = 38;
24 my $y_cut2 = 24;
25 my $y_cutd = 10;
26
27 my $coverup_x = 5;
28 my $coverup_y = 89;
29
30 my $cutd_slope = ($x_cut2-$x_cut)/$x_cut;
31 my $y_cut2d = $y_cutd * $cutd_slope;
32 my $y_cutdd = $x_cutd * $cutd_slope;
33
34 my $nrepis = 4;
35
36 my $paper_x = 210;
37
38 my $spacing = 23;
39 my $colspacing = 23;
40 my $vhalf = sqrt( $spacing ** 2 - ($colspacing*0.5) ** 2 );
41
42 my $y_cut = 2.75 * $spacing;
43
44 my $x_pl_zero = $paper_x*0.5 - 3*$colspacing;
45 my $y_pl_zero = $y_cut + $spacing - $y_cutd* 0.5 * $x_cut/$colspacing;
46
47 my $y_top = $y_pl_zero + $y_cutd + $spacing*1.25;
48
49 our $veep_bg = " 0.95 0.90 0.67 setrgbcolor ";
50
51 our $x_cut_rhs = $paper_x - $x_cut;
52
53 sub some_cut_line($) {
54   <<END;
55 gsave
56   0.25 setlinewidth
57   $_[0]
58 grestore
59 END
60 }
61
62
63 o <<GS, some_cut_line(<<GR), <<END;
64 /cut_line {
65 GS
66                                           newpath
67   $x_cut2     0                           moveto
68   $x_cut2     $y_cut2                     lineto
69   $x_cut $x_cutd add     $y_cut2   $y_cut2d add      lineto
70   $x_cut $x_cutd add      $y_cut   $y_cutdd add      lineto
71   0           $y_cut    $y_cutd add       lineto
72   0           $y_top                      lineto
73                                           stroke
74 GR
75 } def
76 END
77
78 my $veep_font = "/Helvetica-Bold findfont 6.5 scalefont setfont";
79 my $money_font = "/Helvetica-BoldOblique findfont 6.5 scalefont setfont";
80
81 o <<END;
82 $money_font
83 END
84
85 sub veepsq ($) {
86   my ($veeps) = @_;
87
88   my $sqx = 4.1;
89   my $sqy = 3.2;
90
91   <<END;
92   gsave
93     -1.5 -3.0 translate
94
95     gsave
96       newpath  -$sqx -$sqy moveto
97                -$sqx  $sqy lineto
98                 $sqx  $sqy lineto
99                 $sqx -$sqy lineto closepath
100
101        gsave 
102              $veep_bg
103              fill
104        grestore
105        0.19 0.35 0.25 setrgbcolor
106        0.5 setlinewidth
107        stroke
108     grestore
109
110     $veep_font
111     0 0 moveto
112     ($veeps) dup  stringwidth pop -0.5 mul -2.5 rmoveto  show
113   grestore
114 END
115 }
116
117 sub places ($) {
118   my ($repi) = @_;
119   my $data = <<END;
120     -1-L*H -1
121         -1  0   34 14
122         -H  V   34 14 1
123          0  0   34 15
124          0 -1   35 15
125          0 -2   35 16
126          H -2-V 35 16 1
127          1 -2   36 16
128          1 -1   37 16
129      1+R*H  0
130 END
131   my $line;
132   my $line_word = 'moveto';
133
134   my $o = '';
135
136   $o .= <<END;
137     gsave
138 END
139   foreach (split /\n/, $data) {
140     s{\#.*}{};
141     next unless m/\S/;
142     s{^\s*}{};
143     s{L}{ ($repi == 0         ? 1 : 0) }ge;
144     s{R}{ ($repi == $nrepis-1 ? 1 : 0) }ge;
145     s{H}{ 0.5 }ge;
146     s{V}{ $vhalf / $spacing }ge;
147     my ($x,$y,$money,$veeps,$ruby) = map { eval $_ } split /\s+/;
148     $ruby ||= 0;
149     $x *= $colspacing;
150     $y *= $spacing;
151     $x += $x_pl_zero;
152     $y += $y_pl_zero;
153
154     $line .= " $x $y $line_word";
155     $line_word = 'lineto';
156     next unless defined $money;
157
158     $money += 4 * $repi;
159     $veeps += 2 * $repi;
160
161     $o .= <<END;
162 % place $x $y $money $veeps $ruby
163 gsave
164   $x $y translate
165   gsave
166     newpath
167     0 0 chip 0.5 mul 0 360 arc
168     gsave 0.5 setlinewidth $black stroke grestore
169     0.80 0.89 0.63 setrgbcolor fill
170   grestore
171
172   -4.7 1 moveto ($money) show
173
174   ${\ veepsq($veeps) }
175 END
176
177     $o .= <<END if $ruby;
178  gsave
179    6 -1 translate
180    0.8 dup scale
181    ${ \ruby() }
182  grestore
183 END
184
185     $o .= <<END;
186 grestore
187 END
188   }
189   $o .= <<END;
190     grestore
191 END
192
193   $line = <<END;
194   newpath
195     0.66 0.85 0.75 setrgbcolor
196     4 setlinewidth
197   $line
198   stroke
199 END
200
201   ($line, $o)
202 }
203
204 sub repis () {
205   for my $places_i (qw(0 1)) {
206     for my $repi (0..$nrepis-1) {
207       o(<<END);
208 % repi $places_i $repi
209 gsave
210   $repi $colspacing 2 mul mul  0 translate
211 END
212
213       o( (places($repi))[$places_i] );
214       o(<<END);
215 grestore
216 END
217     }
218   }
219 }
220
221 sub set () {
222   o(<<END);
223     cut_line
224     gsave
225       $x_cut_rhs 0 translate
226       cut_line
227     grestore
228 END
229   o some_cut_line <<END;
230                                  newpath
231     0                    $y_top  moveto
232     $x_cut_rhs           $y_top  lineto
233                                  stroke
234 END
235
236   repis();
237
238   o <<END;
239     gsave
240       $coverup_x $coverup_y translate
241       /Times-Roman findfont 4.0 scalefont setfont
242       0 8 moveto  (cover) show
243       2 4.5 moveto  (up) show
244       0 0 moveto
245       /Helvetica-Bold-Italic findfont 3.5 scalefont setfont (35) show
246       1 0 rmoveto
247       /Helvetica-Bold findfont 3.5 scalefont setfont (15) show
248     grestore
249
250     gsave
251       $paper_x $x_cut sub  $y_top 7 sub translate
252
253       gsave
254         arrowlen 2 add neg  0 translate
255         ${\ arrow_any("arrowlen 0 moveto  -30 0 rlineto") }
256       grestore
257
258       -40 0 translate
259       /Helvetica-Bold findfont 6.5 scalefont setfont
260
261      -4.5 0 moveto
262      $money_font
263      (+16) show
264
265      4 -2 translate
266      ${\ veepsq('+8') }
267
268      4 4.5 moveto
269      /Times-Roman findfont 4.5 scalefont setfont
270      (per next page) show
271
272     grestore
273 END
274 }
275
276 set();
277 o <<END;
278 gsave 0 $y_top translate
279 END
280 set();
281 o <<END;
282 grestore
283 END
284
285 print $ps_framing or die $!;