#include #include #include #include #define FONT "Monospace 10" // struct for storing dimensions used for calculations, movement, etc. struct dimensions { // Multiplication factors int row_count; /* rows */ int column_count; /* columns */ // All of these are in units chosen by width in "calp.c" // Most likely milimeters (mm) double paper_width; /* paper width */ double paper_height; /* paper height */ double month_width; /* month width */ double month_height; /* month height */ double month_top_corner_x; double month_top_corner_y; double day_width; /* day box width */ double day_height; /* day box height */ double margin; /* margin */ }; // Fill entire background with current color // Function name is changed for clarity int fill_bg(cairo_t *c) { cairo_paint(c); return 0; } // Draw text at a certain point. // Needn't be a string pointer, can be fixed array of chars // Creates and destroys layout within the scope of the function // Is that performant when looped over 365 operations? int draw_text (cairo_t *c, double x, double y, char *text) { PangoLayout *layout; PangoFontDescription *desc; // Create a PangoLayout, setting font & text layout = pango_cairo_create_layout(c); desc = pango_font_description_from_string(FONT); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); pango_layout_set_text(layout, text, -1); //printf("text: %s\n", text); cairo_move_to (c, x, y); pango_cairo_show_layout (c, layout); g_object_unref(layout); return 0; } // Calculate dimenions for one page and stores it in the dimensions struct int calculate_dimensions(double pw, double ph, struct dimensions *d) { // Percentage of page that should be margin double margin = 0.1 * pw; // Everything other than margin double month_width = 0.8 * pw; // width of day is 1/7th of total width double box_width = month_width / 7.0; // Width = Height; Day Box is a square double box_height = box_width; // Height is based on how tall # of weeks are double month_height = box_height * 6.0; // Set items in struct to calculated values d->row_count = 6; d->column_count = 7; d->paper_width = pw; d->paper_height = ph; d->margin = margin; d->month_width = month_width; d->month_top_corner_x = margin; d->month_top_corner_y = ph - margin - month_height; d->month_height = month_height; d->day_width = box_width; d->day_height = box_height; return 0; } int print_dimensions(struct dimensions *d) { printf("row count: %d\n", d->row_count); printf("column count: %d\n", d->column_count); printf("paper width: %.2f\n", d->paper_width); printf("paper height: %.2f\n", d->paper_height); printf("margin: %.2f\n", d->margin); printf("month width: %.2f\n", d->month_width); printf("month height: %.2f\n", d->month_height); printf("month_top_corner_x: %f\n", d->month_top_corner_x); printf("month_top_corner_y: %f\n", d->month_top_corner_y); printf("day width: %.2f\n", d->day_width); printf("day height: %.2f\n", d->day_height); return 0; } // Draws the lines for a month //int draw_month_grid (cairo_t *c, int month, int start_day) { //int draw_month_grid (cairo_t *c, struct dimensions *d) { // cairo_move_to (c, d->month_top_corner_x, d->month_top_corner_y); // return 0; //} // Draws one month using daybox sub-surface & context, main context, and dimension struct int draw_month (cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct dimensions *d, int days_in_month, int start_day) { double cursor_x = d->month_top_corner_x; if (start_day != 0) cursor_x = cursor_x + (d->day_width * start_day); printf("%d\n", start_day); double cursor_y = d->month_top_corner_y; int current_day = start_day; int increment = 0; char str[20]; for (int i = 0; i < d->row_count; i++) { for (int k = current_day; k < d->column_count; k++) { // When the increment reached the end of the month, end // the function. if (increment >= days_in_month) return 0; // Fill bg with color cairo_set_source_rgb (cd, 0.0, 0.0, 255.0); fill_bg(cd); // Change text color cairo_set_source_rgb (cd, 255.0, 255.0, 255.0); // draw_text(), and by extension pango_layout_set_text(), needs a // string as input, so the current day's date is converted. snprintf(str, sizeof(str), "%d", increment + 1); // Position within cd is arbitrary: (0,0) is too close to edge draw_text(cd, 4.0, 4.0, str); // Position sub-surface on main surface cairo_set_source_surface (c, s, cursor_x, cursor_y); cairo_paint(c); // Move cursor one box over cursor_x = cursor_x + d->day_width; increment++; } current_day = 0; cursor_x = d->month_top_corner_x; cursor_y = cursor_y + d->day_height; } cairo_stroke(cd); return 0; } // Get the day of the week for a given day // Mostly used for calculating when the start of a month is // Relative to "Su Mo ... Sa" frame, not when Su and Sa are together // Range is 0 -> 6 // https://wiki.c2.com/?PerpetualCalendarAlgorithm int day_of_week (int d, int m, int y) { return((d += m < 3 ? y-- : y - 2, 23*m/9 + d + 4 + y/4- y/100 + y/400)%7); }