/* * File: abclib.c * Part of the ABClock package * (c) Peter Kleiweg * * 2000/08/15: version 1.0 * 2000/08/06: version 0.9 * 2000/08/04: version 0.1 * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, * or (at your option) any later version. * */ #include #include #include #include "abclib.h" int ABC_size, ABC_xsize = 0, ABC_ysize = 0, ABC_hsize, ABC_msize, ABC_mwidth, ABC_mskip, ABC_hpart, ABC_mpart, ABC_border, ABC_bborder, ABC_edge, ABC_a1, ABC_a2, ABC_a3, ABC_z1, ABC_z2, ABC_z3, ABC_m1, ABC_m2, ABC_m3, ABC_block_x, ABC_block_y; void ABC_sizes (int width, int height, int border), ABC_top (int x, float f), ABC_bottom (int x, float f), ABC_left (int y, float f), ABC_right (int y, float f); #define ABC_RECT(x1, y1, x2, y2) (ABC_Rect \ (ABC_block_x + x1, ABC_block_y + y1, \ ABC_block_x + x2, ABC_block_y + y2)) void ABC_sizes (int width, int height, int border) { int tsize; if (width < ABC_MINSIZE || height < ABC_MINSIZE) { fputs ("ABClib: too small\n", stderr); exit (1); } if (border > 0 && (width - 2 * border < ABC_MINSIZE || height - 2 * border < ABC_MINSIZE) ) { fputs ("ABClib: border too large for size\n", stderr); exit (1); } if (width == ABC_xsize && height == ABC_ysize && (border == ABC_border || (border < 0 && ABC_border < 0)) ) return; ABC_xsize = width; ABC_ysize = height; ABC_border = border; ABC_size = (ABC_xsize < ABC_ysize) ? ABC_xsize : ABC_ysize; if (ABC_border < 0) { ABC_bborder = ABC_size / 60; if (ABC_bborder == 0 && ABC_size > ABC_MINSIZE + 1) ABC_bborder = 1; } else ABC_bborder = ABC_border; tsize = ABC_size - 2 * ABC_bborder; ABC_edge = (tsize + 20) / 30; ABC_mpart = 5 * ((tsize + 9) / 15); ABC_mskip = (ABC_mpart + 5) / 15; ABC_mwidth = ABC_mpart / 5 - ABC_mskip; tsize = ABC_size - 2 * ABC_bborder - ABC_mpart; ABC_hsize = (tsize - 2 * ABC_edge) / 3; ABC_hpart = 3 * ABC_hsize + 2 * ABC_edge; tsize = ABC_hpart + ABC_mpart; ABC_msize = (ABC_hpart - 2 * (ABC_hpart / 5)) / 3; if ((ABC_msize % 2) != (ABC_hpart % 2)) ABC_msize--; while (ABC_msize < (ABC_hpart - 3 * ABC_msize) / 2) ABC_msize += 2; ABC_a1 = ABC_edge; ABC_z1 = ABC_edge + ABC_hsize - 1; ABC_a2 = ABC_edge + ABC_hsize; ABC_z2 = ABC_edge + 2 * ABC_hsize - 1; ABC_a3 = ABC_edge + 2 * ABC_hsize; ABC_z3 = ABC_edge + 3 * ABC_hsize - 1; ABC_m1 = 0; ABC_m2 = (ABC_hpart - ABC_msize) / 2; ABC_m3 = ABC_hpart - ABC_msize; } /* * put minutes f at (x, top) */ void ABC_top (int x, float f) { int i, m1, m, y; f = fabs (f); f = 5.0 - f; y = 2 * ABC_edge + 3 * ABC_hsize + ABC_mskip; for (i = 0; i < 5; i++) { if ((m = (int) (ABC_msize * f + .5)) > ABC_msize) m = ABC_msize; if (m < 1) return; m1 = (ABC_msize - m) / 2; ABC_RECT (x + m1, y, x + m1 + m - 1, y + ABC_mwidth - 1); f -= 1.0; y += (ABC_mskip + ABC_mwidth); } } /* * put minutes f at (x, bottom) */ void ABC_bottom (int x, float f) { int i, m, m1, y; f = fabs (f); f = 5.0 - f; y = - ABC_mskip - ABC_mwidth; for (i = 0; i < 5; i++) { if ((m = (int) (ABC_msize * f + .5)) > ABC_msize) m = ABC_msize; if (m < 1) return; m1 = (ABC_msize - m) / 2; ABC_RECT (x + m1, y, x + m1 + m - 1, y + ABC_mwidth - 1); f -= 1.0; y -= (ABC_mskip + ABC_mwidth); } } /* * put minutes at (right, y) */ void ABC_right (int y, float f) { int i, m, m1, x; f = fabs (f); f = 5.0 - f; x = 2 * ABC_edge + 3 * ABC_hsize + ABC_mskip; for (i = 0; i < 5; i++) { if ((m = (int) (ABC_msize * f + .5)) > ABC_msize) m = ABC_msize; if (m < 1) return; m1 = (ABC_msize - m) / 2; ABC_RECT (x, y + m1, x + ABC_mwidth - 1, y + m1 + m - 1); f -= 1.0; x += (ABC_mskip + ABC_mwidth); } } /* * put minutes at (left, y) */ void ABC_left (int y, float f) { int i, m, m1, x; f = fabs (f); f = 5.0 - f; x = - ABC_mskip - ABC_mwidth; for (i = 0; i < 5; i++) { if ((m = (int) (ABC_msize * f + .5)) > ABC_msize) m = ABC_msize; if (m < 1) return; m1 = (ABC_msize - m) / 2; ABC_RECT (x, y + m1, x + ABC_mwidth - 1, y + m1 + m - 1); f -= 1.0; x -= (ABC_mskip + ABC_mwidth); } } void ABC_Make (int hour, int min, int sec, int width, int height, int border) { float f, x, y, xm, ym; int i; ABC_sizes (width, height, border); if ((hour %= 12) < 0) hour += 12; if ((min %= 60) < 0) min += 60; if ((sec %= 60) < 0) sec += 60; /* set color to background */ ABC_SetColor (0); /* clear image */ ABC_block_x = ABC_block_y = 0; ABC_RECT (0, 0, ABC_xsize - 1, ABC_ysize - 1); /* determine where to put the square, to leave room for minutes */ if ((xm = ABC_hpart + 2 * ABC_mpart + 2 * ABC_bborder - ABC_xsize) < 0) xm = 0; if ((ym = ABC_hpart + 2 * ABC_mpart + 2 * ABC_bborder - ABC_ysize) < 0) ym = 0; if (min < 5 || min >= 55) { if ((f = min) > 5) f -= 60.0; f += ((float) sec) / 60.0; x = - f / 5.0 * xm; } else if (min < 25) x = -xm; else if (min < 35) { f = ((float) sec) / 60.0 + (float) min; x = (f - 30.0) / 5.0 * xm; } else x = xm; if (min < 10 || min >= 50) y = -ym; else if (min < 20) { f = ((float) sec) / 60.0 + (float) min; y = (f - 15.0) / 5.0 * ym; } else if (min < 40) y = ym; else { f = ((float) sec) / 60.0 + (float) min; y = (45.0 - f) / 5.0 * ym; } ABC_block_x = (x + ((float) (ABC_xsize - ABC_hpart))) / 2.0 + .5; ABC_block_y = (y + ((float) (ABC_ysize - ABC_hpart))) / 2.0 + .5; /* set color to square border */ ABC_SetColor (2); /* paint square border */ ABC_RECT (0, 0, 2 * ABC_edge + 3 * ABC_hsize - 1, 2 * ABC_edge + 3 * ABC_hsize - 1); /* set color to inside square */ ABC_SetColor (1); /* paint inside square */ ABC_RECT (ABC_edge, ABC_edge, ABC_edge + 3 * ABC_hsize - 1, ABC_edge + 3 * ABC_hsize - 1); /* set color to hours */ ABC_SetColor (3); /* paint hours */ f = ((float) hour) + ((float) min) / 60.0 + ((float) sec) / 3600.0; switch (hour) { case 0: i = (int) (f * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a2, ABC_a2 + i, ABC_z2, ABC_z3); ABC_RECT (ABC_a3, ABC_a3, ABC_z2 + i, ABC_z3); break; case 1: i = (int) ((f - 1.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a2 + i, ABC_a3, ABC_z3, ABC_z3); ABC_RECT (ABC_a3, ABC_a3 - i, ABC_z3, ABC_z2); break; case 2: i = (int) ((f - 2.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a3, ABC_a2, ABC_z3, ABC_z3 - i); ABC_RECT (ABC_a3 - i, ABC_a2, ABC_z2, ABC_z2); break; case 3: i = (int) ((f - 3.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a2 + i, ABC_a2, ABC_z3, ABC_z2); ABC_RECT (ABC_a3, ABC_a2 - i, ABC_z3, ABC_z2); break; case 4: i = (int) ((f - 4.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a3, ABC_a1, ABC_z3, ABC_z2 - i); ABC_RECT (ABC_a3 - i, ABC_a1, ABC_z2, ABC_z1); break; case 5: i = (int) ((f - 5.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a2, ABC_a1, ABC_z3 - i, ABC_z1); ABC_RECT (ABC_a2, ABC_a2, ABC_z2, ABC_z1 + i); break; case 6: i = (int) ((f - 6.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a2, ABC_a1, ABC_z2, ABC_z2 - i); ABC_RECT (ABC_a2 - i, ABC_a1, ABC_z1, ABC_z1); break; case 7: i = (int) ((f - 7.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a1, ABC_a1, ABC_z2 - i, ABC_z1); ABC_RECT (ABC_a1, ABC_a2, ABC_z1, ABC_z1 + i); break; case 8: i = (int) ((f - 8.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a1, ABC_a1 + i, ABC_z1, ABC_z2); ABC_RECT (ABC_a2, ABC_a2, ABC_z1 + i, ABC_z2); break; case 9: i = (int) ((f - 9.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a1, ABC_a2, ABC_z2 - i, ABC_z2); ABC_RECT (ABC_a1, ABC_a3, ABC_z1, ABC_z2 + i); break; case 10: i = (int) ((f - 10.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a1, ABC_a2 + i, ABC_z1, ABC_z3); ABC_RECT (ABC_a2, ABC_a3, ABC_z1 + i, ABC_z3); break; case 11: i = (int) ((f - 11.0) * ((float) ABC_hsize) + .5); ABC_RECT (ABC_a1 + i, ABC_a3, ABC_z2, ABC_z3); ABC_RECT (ABC_a2, ABC_a3 - i, ABC_z2, ABC_z3); break; } /* set color to minutes */ ABC_SetColor (4); /* paint minutes */ f = ((float) min) + ((float) sec) / 60.0; if (min >= 55 || min < 5) ABC_top (ABC_m2, (min < 5) ? f : (f - 60.0)); if (min < 10) ABC_top (ABC_m3, f - 5.0); if (min >= 5 && min < 15) ABC_right (ABC_m3, f - 10.0); if (min >= 10 && min < 20) ABC_right (ABC_m2, f - 15.0); if (min >= 15 && min < 25) ABC_right (ABC_m1, f - 20.0); if (min >= 20 && min < 30) ABC_bottom (ABC_m3, f - 25.0); if (min >= 25 && min < 35) ABC_bottom (ABC_m2, f - 30.0); if (min >= 30 && min < 40) ABC_bottom (ABC_m1, f - 35.0); if (min >= 35 && min < 45) ABC_left (ABC_m1, f - 40.0); if (min >= 40 && min < 50) ABC_left (ABC_m2, f - 45.0); if (min >= 45 && min < 55) ABC_left (ABC_m3, f - 50.0); if (min >= 50) ABC_top (ABC_m1, f - 55.0); }