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