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