//calp: printable calendar generator #include #include #include #include #include "draw.h" #include "date.h" #include "color.h" // Metric #define A4_WIDTH 210 #define A4_HEIGHT 297 #define US_LETTER_WIDTH 216 #define US_LETTER_HEIGHT 279 // Font Settings #define FONT_FAMILY "Sans" #define FONT_SIZE_NORMAL 10 #define FONT_SIZE_LARGE 40 int main (void) { // Definitions // ----------- double width = A4_WIDTH; double height = A4_HEIGHT; // Convert to inches, then 1 unit = 1/72th inch width = (width / 25.4) * 72.0; height = (height / 25.4) * 72.0; extern char *months[]; int num_of_months = 12; extern int days_in_month[12]; // Create dimensions struct to hold measurements struct dimensions dim; // Create dimensions struct to hold information about a // month struct month_info month; // Leap year adjustment: increment February day count by one if // it is a leap year. int year = 3043; if (isleap(year)) { days_in_month[1]++; } int verbose_output = 1; // TBD: Add ability to choose filename // Defaults to the year being generated char filename[20]; snprintf(filename, sizeof(filename), "%d.pdf", year); // Initialization // -------------- // Calculates measurements, stores them in dimensions struct. See "draw.h" calculate_dimensions(width, height, &dim); if (!CAIRO_HAS_PDF_SURFACE) { printf("Error: PDF backend not available.\n"); return 1; } cairo_surface_t *surface = cairo_pdf_surface_create(filename, dim.paper_width, dim.paper_height); cairo_t *paper = cairo_create(surface); // Sub-surface for rendering content in day boxes cairo_surface_t *day = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, dim.day_width, dim.day_height); // cd = context day cairo_t *cd = cairo_create(day); // Fill background with white color set_color(paper, WHITE); fill_bg(paper); // Construction // ------------ // Print dimensions, for debugging if (verbose_output) { print_dimensions(&dim); } // Range of months to be rendered (Default: Full calendar year, 12 months) int first_month = 0; int end_month = num_of_months; // Month generation loop for (int i = first_month; i < end_month; i++) { // Initialize month struct month.first_day = day_of_week(1, i + 1, year); month.num_of_days = days_in_month[i]; month.month_position = i; month.minimum_rows = calculate_minimum_rows(&month, &dim); printf("month.minimum_rows: %d\n", month.minimum_rows); dim.header_width = dim.paper_width - (dim.margin * 2.0); dim.header_height = dim.paper_height - (dim.margin * 3.0) - (month.minimum_rows * dim.day_height); cairo_surface_t *header = cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, dim.header_width, dim.header_height); cairo_t *ch = cairo_create(header); //set_color(ch, BLUE); //fill_bg(ch); set_color(ch, BLACK); draw_month_title(ch, &dim, "Sans", 40, months[i]); printf("header width: %f\n", dim.header_width); printf("header height: %f\n", dim.header_height); char path[20]; snprintf(path, 20, "assets/%d.png", i + 1); if (verbose_output) { printf("Drawing month \'%s\'\n", months[i]); } draw_month_art(paper, &dim, path); cairo_set_source_surface(paper, header, dim.margin, dim.margin); cairo_paint(paper); draw_month(paper, cd, day, &month, &dim); draw_month_grid(paper, &month, &dim); // Go to the next page in pdf cairo_show_page(paper); cairo_destroy(ch); cairo_surface_destroy(header); } if (verbose_output) { printf("Finished generating \'%s\'.\n", filename); } // Clean up // -------- cairo_destroy(paper); cairo_surface_destroy(surface); cairo_destroy(cd); cairo_surface_destroy(day); return 0; }