1 /*
2 * File: abclib.c
3 * Part of the ABClock package
4 * (c) Peter Kleiweg
5 *
6 * 2000/08/15: version 1.0
7 * 2000/08/06: version 0.9
8 * 2000/08/04: version 0.1
9 *
10 * This is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2,
13 * or (at your option) any later version.
14 *
15 */
16
17 #include <math.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 #include "abclib.h"
22
23 int
24 ABC_size,
25 ABC_xsize = 0,
26 ABC_ysize = 0,
27 ABC_hsize,
28 ABC_msize,
29 ABC_mwidth,
30 ABC_mskip,
31 ABC_hpart,
32 ABC_mpart,
33 ABC_border,
34 ABC_bborder,
35 ABC_edge,
36 ABC_a1,
37 ABC_a2,
38 ABC_a3,
39 ABC_z1,
40 ABC_z2,
41 ABC_z3,
42 ABC_m1,
43 ABC_m2,
44 ABC_m3,
45 ABC_block_x,
46 ABC_block_y;
47
48 void
49 ABC_sizes (int width, int height, int border),
50 ABC_top (int x, float f),
51 ABC_bottom (int x, float f),
52 ABC_left (int y, float f),
53 ABC_right (int y, float f);
54
55 #define ABC_RECT(x1, y1, x2, y2) (ABC_Rect \
56 (ABC_block_x + x1, ABC_block_y + y1, \
57 ABC_block_x + x2, ABC_block_y + y2))
58
ABC_sizes(int width,int height,int border)59 void ABC_sizes (int width, int height, int border)
60 {
61 int
62 tsize;
63
64 if (width < ABC_MINSIZE || height < ABC_MINSIZE) {
65 fputs ("ABClib: too small\n", stderr);
66 exit (1);
67 }
68
69 if (border > 0 &&
70 (width - 2 * border < ABC_MINSIZE ||
71 height - 2 * border < ABC_MINSIZE)
72 ) {
73 fputs ("ABClib: border too large for size\n", stderr);
74 exit (1);
75 }
76
77 if (width == ABC_xsize &&
78 height == ABC_ysize &&
79 (border == ABC_border || (border < 0 && ABC_border < 0))
80 )
81 return;
82
83 ABC_xsize = width;
84 ABC_ysize = height;
85 ABC_border = border;
86
87 ABC_size = (ABC_xsize < ABC_ysize) ? ABC_xsize : ABC_ysize;
88 if (ABC_border < 0) {
89 ABC_bborder = ABC_size / 60;
90 if (ABC_bborder == 0 && ABC_size > ABC_MINSIZE + 1)
91 ABC_bborder = 1;
92 } else
93 ABC_bborder = ABC_border;
94
95 tsize = ABC_size - 2 * ABC_bborder;
96 ABC_edge = (tsize + 20) / 30;
97 ABC_mpart = 5 * ((tsize + 9) / 15);
98 ABC_mskip = (ABC_mpart + 5) / 15;
99 ABC_mwidth = ABC_mpart / 5 - ABC_mskip;
100 tsize = ABC_size - 2 * ABC_bborder - ABC_mpart;
101 ABC_hsize = (tsize - 2 * ABC_edge) / 3;
102 ABC_hpart = 3 * ABC_hsize + 2 * ABC_edge;
103 tsize = ABC_hpart + ABC_mpart;
104 ABC_msize = (ABC_hpart - 2 * (ABC_hpart / 5)) / 3;
105 if ((ABC_msize % 2) != (ABC_hpart % 2))
106 ABC_msize--;
107 while (ABC_msize < (ABC_hpart - 3 * ABC_msize) / 2)
108 ABC_msize += 2;
109
110 ABC_a1 = ABC_edge;
111 ABC_z1 = ABC_edge + ABC_hsize - 1;
112 ABC_a2 = ABC_edge + ABC_hsize;
113 ABC_z2 = ABC_edge + 2 * ABC_hsize - 1;
114 ABC_a3 = ABC_edge + 2 * ABC_hsize;
115 ABC_z3 = ABC_edge + 3 * ABC_hsize - 1;
116
117 ABC_m1 = 0;
118 ABC_m2 = (ABC_hpart - ABC_msize) / 2;
119 ABC_m3 = ABC_hpart - ABC_msize;
120 }
121
122 /*
123 * put minutes f at (x, top)
124 */
ABC_top(int x,float f)125 void ABC_top (int x, float f)
126 {
127 int
128 i,
129 m1,
130 m,
131 y;
132
133 f = fabs (f);
134 f = 5.0 - f;
135 y = 2 * ABC_edge + 3 * ABC_hsize + ABC_mskip;
136 for (i = 0; i < 5; i++) {
137 if ((m = (int) (ABC_msize * f + .5)) > ABC_msize)
138 m = ABC_msize;
139 if (m < 1)
140 return;
141 m1 = (ABC_msize - m) / 2;
142 ABC_RECT (x + m1, y, x + m1 + m - 1, y + ABC_mwidth - 1);
143 f -= 1.0;
144 y += (ABC_mskip + ABC_mwidth);
145 }
146 }
147
148 /*
149 * put minutes f at (x, bottom)
150 */
ABC_bottom(int x,float f)151 void ABC_bottom (int x, float f)
152 {
153 int
154 i,
155 m,
156 m1,
157 y;
158
159 f = fabs (f);
160 f = 5.0 - f;
161 y = - ABC_mskip - ABC_mwidth;
162 for (i = 0; i < 5; i++) {
163 if ((m = (int) (ABC_msize * f + .5)) > ABC_msize)
164 m = ABC_msize;
165 if (m < 1)
166 return;
167 m1 = (ABC_msize - m) / 2;
168 ABC_RECT (x + m1, y, x + m1 + m - 1, y + ABC_mwidth - 1);
169 f -= 1.0;
170 y -= (ABC_mskip + ABC_mwidth);
171 }
172 }
173
174 /*
175 * put minutes at (right, y)
176 */
ABC_right(int y,float f)177 void ABC_right (int y, float f)
178 {
179 int
180 i,
181 m,
182 m1,
183 x;
184
185 f = fabs (f);
186 f = 5.0 - f;
187 x = 2 * ABC_edge + 3 * ABC_hsize + ABC_mskip;
188 for (i = 0; i < 5; i++) {
189 if ((m = (int) (ABC_msize * f + .5)) > ABC_msize)
190 m = ABC_msize;
191 if (m < 1)
192 return;
193 m1 = (ABC_msize - m) / 2;
194 ABC_RECT (x, y + m1, x + ABC_mwidth - 1, y + m1 + m - 1);
195 f -= 1.0;
196 x += (ABC_mskip + ABC_mwidth);
197 }
198 }
199
200 /*
201 * put minutes at (left, y)
202 */
ABC_left(int y,float f)203 void ABC_left (int y, float f)
204 {
205 int
206 i,
207 m,
208 m1,
209 x;
210
211 f = fabs (f);
212 f = 5.0 - f;
213 x = - ABC_mskip - ABC_mwidth;
214 for (i = 0; i < 5; i++) {
215 if ((m = (int) (ABC_msize * f + .5)) > ABC_msize)
216 m = ABC_msize;
217 if (m < 1)
218 return;
219 m1 = (ABC_msize - m) / 2;
220 ABC_RECT (x, y + m1, x + ABC_mwidth - 1, y + m1 + m - 1);
221 f -= 1.0;
222 x -= (ABC_mskip + ABC_mwidth);
223 }
224 }
225
ABC_Make(int hour,int min,int sec,int width,int height,int border)226 void ABC_Make (int hour, int min, int sec, int width, int height, int border)
227 {
228 float
229 f,
230 x,
231 y,
232 xm,
233 ym;
234 int
235 i;
236
237 ABC_sizes (width, height, border);
238
239 if ((hour %= 12) < 0)
240 hour += 12;
241 if ((min %= 60) < 0)
242 min += 60;
243 if ((sec %= 60) < 0)
244 sec += 60;
245
246 /* set color to background */
247 ABC_SetColor (0);
248
249 /* clear image */
250 ABC_block_x = ABC_block_y = 0;
251 ABC_RECT (0, 0, ABC_xsize - 1, ABC_ysize - 1);
252
253 /* determine where to put the square, to leave room for minutes */
254
255 if ((xm = ABC_hpart + 2 * ABC_mpart + 2 * ABC_bborder - ABC_xsize) < 0)
256 xm = 0;
257 if ((ym = ABC_hpart + 2 * ABC_mpart + 2 * ABC_bborder - ABC_ysize) < 0)
258 ym = 0;
259
260 if (min < 5 || min >= 55) {
261 if ((f = min) > 5)
262 f -= 60.0;
263 f += ((float) sec) / 60.0;
264 x = - f / 5.0 * xm;
265 } else if (min < 25)
266 x = -xm;
267 else if (min < 35) {
268 f = ((float) sec) / 60.0 + (float) min;
269 x = (f - 30.0) / 5.0 * xm;
270 } else
271 x = xm;
272
273 if (min < 10 || min >= 50)
274 y = -ym;
275 else if (min < 20) {
276 f = ((float) sec) / 60.0 + (float) min;
277 y = (f - 15.0) / 5.0 * ym;
278 } else if (min < 40)
279 y = ym;
280 else {
281 f = ((float) sec) / 60.0 + (float) min;
282 y = (45.0 - f) / 5.0 * ym;
283 }
284
285 ABC_block_x = (x + ((float) (ABC_xsize - ABC_hpart))) / 2.0 + .5;
286 ABC_block_y = (y + ((float) (ABC_ysize - ABC_hpart))) / 2.0 + .5;
287
288 /* set color to square border */
289 ABC_SetColor (2);
290
291 /* paint square border */
292 ABC_RECT (0,
293 0,
294 2 * ABC_edge + 3 * ABC_hsize - 1,
295 2 * ABC_edge + 3 * ABC_hsize - 1);
296
297 /* set color to inside square */
298 ABC_SetColor (1);
299
300 /* paint inside square */
301 ABC_RECT (ABC_edge,
302 ABC_edge,
303 ABC_edge + 3 * ABC_hsize - 1,
304 ABC_edge + 3 * ABC_hsize - 1);
305
306 /* set color to hours */
307 ABC_SetColor (3);
308
309 /* paint hours */
310 f = ((float) hour) + ((float) min) / 60.0 + ((float) sec) / 3600.0;
311 switch (hour) {
312 case 0:
313 i = (int) (f * ((float) ABC_hsize) + .5);
314 ABC_RECT (ABC_a2, ABC_a2 + i, ABC_z2, ABC_z3);
315 ABC_RECT (ABC_a3, ABC_a3, ABC_z2 + i, ABC_z3);
316 break;
317 case 1:
318 i = (int) ((f - 1.0) * ((float) ABC_hsize) + .5);
319 ABC_RECT (ABC_a2 + i, ABC_a3, ABC_z3, ABC_z3);
320 ABC_RECT (ABC_a3, ABC_a3 - i, ABC_z3, ABC_z2);
321 break;
322 case 2:
323 i = (int) ((f - 2.0) * ((float) ABC_hsize) + .5);
324 ABC_RECT (ABC_a3, ABC_a2, ABC_z3, ABC_z3 - i);
325 ABC_RECT (ABC_a3 - i, ABC_a2, ABC_z2, ABC_z2);
326 break;
327 case 3:
328 i = (int) ((f - 3.0) * ((float) ABC_hsize) + .5);
329 ABC_RECT (ABC_a2 + i, ABC_a2, ABC_z3, ABC_z2);
330 ABC_RECT (ABC_a3, ABC_a2 - i, ABC_z3, ABC_z2);
331 break;
332 case 4:
333 i = (int) ((f - 4.0) * ((float) ABC_hsize) + .5);
334 ABC_RECT (ABC_a3, ABC_a1, ABC_z3, ABC_z2 - i);
335 ABC_RECT (ABC_a3 - i, ABC_a1, ABC_z2, ABC_z1);
336 break;
337 case 5:
338 i = (int) ((f - 5.0) * ((float) ABC_hsize) + .5);
339 ABC_RECT (ABC_a2, ABC_a1, ABC_z3 - i, ABC_z1);
340 ABC_RECT (ABC_a2, ABC_a2, ABC_z2, ABC_z1 + i);
341 break;
342 case 6:
343 i = (int) ((f - 6.0) * ((float) ABC_hsize) + .5);
344 ABC_RECT (ABC_a2, ABC_a1, ABC_z2, ABC_z2 - i);
345 ABC_RECT (ABC_a2 - i, ABC_a1, ABC_z1, ABC_z1);
346 break;
347 case 7:
348 i = (int) ((f - 7.0) * ((float) ABC_hsize) + .5);
349 ABC_RECT (ABC_a1, ABC_a1, ABC_z2 - i, ABC_z1);
350 ABC_RECT (ABC_a1, ABC_a2, ABC_z1, ABC_z1 + i);
351 break;
352 case 8:
353 i = (int) ((f - 8.0) * ((float) ABC_hsize) + .5);
354 ABC_RECT (ABC_a1, ABC_a1 + i, ABC_z1, ABC_z2);
355 ABC_RECT (ABC_a2, ABC_a2, ABC_z1 + i, ABC_z2);
356 break;
357 case 9:
358 i = (int) ((f - 9.0) * ((float) ABC_hsize) + .5);
359 ABC_RECT (ABC_a1, ABC_a2, ABC_z2 - i, ABC_z2);
360 ABC_RECT (ABC_a1, ABC_a3, ABC_z1, ABC_z2 + i);
361 break;
362 case 10:
363 i = (int) ((f - 10.0) * ((float) ABC_hsize) + .5);
364 ABC_RECT (ABC_a1, ABC_a2 + i, ABC_z1, ABC_z3);
365 ABC_RECT (ABC_a2, ABC_a3, ABC_z1 + i, ABC_z3);
366 break;
367 case 11:
368 i = (int) ((f - 11.0) * ((float) ABC_hsize) + .5);
369 ABC_RECT (ABC_a1 + i, ABC_a3, ABC_z2, ABC_z3);
370 ABC_RECT (ABC_a2, ABC_a3 - i, ABC_z2, ABC_z3);
371 break;
372 }
373
374 /* set color to minutes */
375 ABC_SetColor (4);
376
377 /* paint minutes */
378 f = ((float) min) + ((float) sec) / 60.0;
379 if (min >= 55 || min < 5)
380 ABC_top (ABC_m2, (min < 5) ? f : (f - 60.0));
381 if (min < 10)
382 ABC_top (ABC_m3, f - 5.0);
383 if (min >= 5 && min < 15)
384 ABC_right (ABC_m3, f - 10.0);
385 if (min >= 10 && min < 20)
386 ABC_right (ABC_m2, f - 15.0);
387 if (min >= 15 && min < 25)
388 ABC_right (ABC_m1, f - 20.0);
389 if (min >= 20 && min < 30)
390 ABC_bottom (ABC_m3, f - 25.0);
391 if (min >= 25 && min < 35)
392 ABC_bottom (ABC_m2, f - 30.0);
393 if (min >= 30 && min < 40)
394 ABC_bottom (ABC_m1, f - 35.0);
395 if (min >= 35 && min < 45)
396 ABC_left (ABC_m1, f - 40.0);
397 if (min >= 40 && min < 50)
398 ABC_left (ABC_m2, f - 45.0);
399 if (min >= 45 && min < 55)
400 ABC_left (ABC_m3, f - 50.0);
401 if (min >= 50)
402 ABC_top (ABC_m1, f - 55.0);
403 }
404