From c7e37c328387f164aabb1430dc1d9788bcdd41d2 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Thu, 26 May 2022 14:19:56 +0200 Subject: Renamed the program to clockimg. --- clockimg.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 clockimg.c (limited to 'clockimg.c') diff --git a/clockimg.c b/clockimg.c new file mode 100644 index 0000000..cb303d4 --- /dev/null +++ b/clockimg.c @@ -0,0 +1,171 @@ +/* + genclockimg + generates a clock face PNG image +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "cairo_jpg.h" + +int main (int argc, const char **argv) +{ + + /* configuration options */ + int img_width; + int img_height; + char *img_filename; + char img_filename_default[] = "out.png\0"; + char *timestr; + + int use_jpeg; + + /* timestamp represeting what time to draw */ + time_t clock_timestamp; + struct tm *clock_localtime; + int h; + int m; + + /* cairo surface and context */ + cairo_surface_t *surface; + cairo_t *context; + + /* popt options table */ + struct poptOption options_table[] = { + {"out", 'o', POPT_ARG_STRING, &img_filename, 0, "output filename", NULL }, + {"width", 'w', POPT_ARG_INT, &img_width, 0, "output image width", NULL }, + {"height", 'h', POPT_ARG_INT, &img_height, 0, "output image height", NULL }, + {"hours", '\0', POPT_ARG_INT, &h, 0, "hour to display", NULL }, + {"minutes", '\0', POPT_ARG_INT, &m, 0, "minutes to display", NULL }, + {"time", 't', POPT_ARG_STRING, ×tr, 0, "time to display as HH:MM", NULL}, + {"jpg", 'j', POPT_ARG_NONE, &use_jpeg, 0, "Write a JPEG file", NULL}, + POPT_AUTOHELP + {NULL, '\0', 0, NULL, 0, NULL, NULL} + }; + /* popt context */ + poptContext options_context; + + /* default filename is out.png */ + img_filename = NULL; + timestr = NULL; + use_jpeg = 0; + + /* default image size is 128x128 */ + img_width = 128; + img_height = 128; + + /* default timestamp is current localtime */ + clock_timestamp = time(NULL); + clock_localtime = localtime(&clock_timestamp); + h = clock_localtime->tm_hour % 12; + m = clock_localtime->tm_min; + + /* parse command line options */ + options_context = poptGetContext(NULL, argc, argv, options_table, 0); + + int result; + while ((result = poptGetNextOpt(options_context)) > 0 ) { + } + if (result < -1) { + /* an error occurred during option processing */ + fprintf(stderr, "%s: %s\n", poptBadOption(options_context, POPT_BADOPTION_NOALIAS),poptStrerror(result)); + exit(1); + } + + if (use_jpeg) { + img_filename_default[4] = 'j'; + img_filename_default[5] = 'p'; + img_filename_default[6] = 'g'; + } + + if (img_filename == NULL) { + img_filename = img_filename_default; + } + + if (timestr != NULL ) { + /* note: clock_localtime is already initialized here */ + strptime(timestr, "%H:%M", clock_localtime); + h = clock_localtime->tm_hour % 12; + m = clock_localtime->tm_min; + } + + /* keep hours and minutes into range */ + h %= 12; + m %= 60; + + /* create the cairo drawing context and an RGBA drawing surface */ + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, img_width, img_height); + context = cairo_create(surface); + + /* draw image */ + cairo_set_source_rgba(context, 0.0, 0.0, 0.0, 1.0); + cairo_rectangle(context, 0, 0, img_width, img_height); + cairo_fill(context); + + int x1 = img_width / 2 -1; + int y1 = img_height / 2 -1; + + float r; + if (img_width < img_height) { + r = img_width / 2; + } else { + r = img_height /2; + } + float angle = 2.0f * M_PI / 12.0f; + + /* draw clock background */ + /* + cairo_set_source_rgba (context, 1.0, 1.0, 1.0, 1.0); + cairo_arc(context, x1, y1, r-4, 0, 2 * M_PI); + cairo_fill(context); + */ + /* draw clock face */ + cairo_set_source_rgba (context, 1.0, 1.0, 1.0, 1.0); + cairo_set_line_width (context, 1); + cairo_arc(context, x1, y1, r-4, 0, 2 * M_PI); + cairo_stroke(context); + + /* draw markers */ + cairo_set_source_rgba (context, 1.0, 1.0, 1.0, 1.0); + cairo_set_line_width (context, 2); + for (int h = 0; h < 12; h++) { + cairo_move_to(context, x1 + (r - 10) * cosf(angle * h), y1 + (r - 10) * sinf(angle * h)); + cairo_line_to(context, x1 + (r - 4) * cosf(angle * h), y1 + (r - 4)* sinf(angle * h)); + } + cairo_stroke(context); + + /* draw handles */ + cairo_set_line_width (context, 4); + + /* hours handle */ + cairo_move_to(context, x1, y1); + cairo_line_to(context, x1 + (r/2 - 4) * sinf(angle * h + angle / 60 * m), y1 - (r/2 - 4) * cosf(angle * h + angle / 60 * m)); + + /* minutes handle */ + cairo_move_to(context, x1, y1); + cairo_line_to(context, x1 + (r - 10) * sinf(M_PI / 30.0f * m ), y1 - (r - 10) * cosf(M_PI / 30.0f * m)); + cairo_stroke(context); + + + /* write image file */ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + if (use_jpeg) { + status = cairo_image_surface_write_to_jpeg(surface, img_filename, 100); + } else { + status = cairo_surface_write_to_png(surface, img_filename); + } + if (status != CAIRO_STATUS_SUCCESS) { + fprintf(stderr, "Error saving %s\n", img_filename); + } + + /* cleanup */ + cairo_surface_destroy(surface); + poptFreeContext(options_context); + + return 0; +} -- cgit v1.2.3