diff options
| author | foswret | 2026-05-03 13:11:42 -0500 |
|---|---|---|
| committer | foswret | 2026-05-03 13:11:42 -0500 |
| commit | ff329ec93ddacae823704bac2d95e7a830a456b3 (patch) | |
| tree | 18de0192eae0b946c763aaccabd7467d96895ee8 /src | |
| parent | 03ed4535c8489700058fb283837752035f3cf83d (diff) | |
draw month title, move rendering of month as far down the page as possible
Diffstat (limited to 'src')
| -rw-r--r-- | src/calp.c | 29 | ||||
| -rw-r--r-- | src/draw.c | 115 | ||||
| -rw-r--r-- | src/draw.h | 10 |
3 files changed, 132 insertions, 22 deletions
@@ -10,6 +10,11 @@ #define A4_WIDTH 210 #define A4_HEIGHT 297 +// Font Settings +#define FONT_FAMILY "Sans" +#define FONT_SIZE_NORMAL 10 +#define FONT_SIZE_LARGE 40 + int main (void) { // Definitions // ----------- @@ -17,7 +22,7 @@ int main (void) { double width = (A4_WIDTH / 25.4) * 72.0; double height = (A4_HEIGHT / 25.4) * 72.0; - //extern char *months[]; + extern char *months[]; int num_of_months = 12; extern int days_in_month[12]; @@ -38,7 +43,6 @@ int main (void) { - // Initialization // -------------- // Calculates measurements, stores them in dimensions struct. See "draw.h" @@ -52,23 +56,38 @@ int main (void) { cairo_surface_create_similar(surface, CAIRO_CONTENT_COLOR_ALPHA, dim.day_width, dim.day_height); cairo_t *cd = cairo_create(day); + // General rectangle struct for positioning. Used whenever dimensions need + // to be passed to another function + // PangoRectangle logical_extents; + // Fill background with white color cairo_set_source_rgb (paper, 255.0, 255.0, 255.0); fill_bg(paper); - + + + + // Construction + // ------------ // Print dimensions, for debugging //print_dimensions(&dim); // Draw all months for (int i = 0; i < num_of_months; i++) { + + cairo_set_source_rgb (paper, 0.0, 0.0, 0.0); + draw_month_title(paper, &dim, months[i]); + + calculate_minimum_rows(day_of_week(1, i + 1, year), days_in_month[i], &dim); + draw_month(paper, cd, day, &dim, days_in_month[i], day_of_week(1, i + 1, year)); - printf("%d\n", day_of_week(1, i + 1, year)); - // Goes to next page in pdf + + // Go to next page in pdf cairo_show_page(paper); } + // Clean up // -------- @@ -3,8 +3,6 @@ #include <stdio.h> #include <stdlib.h> -#define FONT "Monospace 10" - // struct for storing dimensions used for calculations, movement, etc. struct dimensions { // Multiplication factors @@ -25,6 +23,15 @@ struct dimensions { }; +// 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); +} + // Fill entire background with current color @@ -38,20 +45,28 @@ int fill_bg(cairo_t *c) { // Draw text at a certain point. // Needn't be a string pointer, can be fixed array of chars +// Requires Font Family (string) and Size (int) // 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) { +int draw_text (cairo_t *c, double x, double y, char *font_family, int font_size, char *text) { + char font[100]; + + // Concat font string for pango_font_description_from_string + snprintf(font, sizeof(font), "%s %d", font_family, font_size); + + //Initialize Pango Stuff PangoLayout *layout; PangoFontDescription *desc; + // Create a PangoLayout, setting font & text layout = pango_cairo_create_layout(c); - desc = pango_font_description_from_string(FONT); + desc = pango_font_description_from_string(font); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); + pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); pango_layout_set_text(layout, text, -1); - //printf("text: %s\n", text); cairo_move_to (c, x, y); pango_cairo_show_layout (c, layout); @@ -60,6 +75,30 @@ int draw_text (cairo_t *c, double x, double y, char *text) { } +PangoRectangle get_logical_extents (cairo_t *c, char *font_family, int font_size, char *text) { + char font[100]; + + // Concat font string for pango_font_description_from_string + snprintf(font, sizeof(font), "%s %d", font_family, font_size); + + PangoLayout *layout; + PangoFontDescription *desc; + PangoRectangle rect; + + // 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); + pango_layout_get_pixel_extents(layout, &rect, NULL); + //pango_layout_get_extents(layout, NULL, &rect); + + g_object_unref(layout); + return(rect); +} + // Calculate dimenions for one page and stores it in the dimensions struct int calculate_dimensions(double pw, double ph, struct dimensions *d) { @@ -109,6 +148,35 @@ int print_dimensions(struct dimensions *d) { return 0; } +// Calculate minimum amount of rows a month can fit in. +// Most months can fit within 4 or 5 rows instead of 6. +// TBD: This can probably done in a more efficient way +int calculate_minimum_rows(int first_day, int num_of_days, struct dimensions *d) { + int extra_rows = 0; + + int days_in_first_week = (d->column_count - first_day); + + if (first_day == 0) { + days_in_first_week = first_day; + } + + int days_in_last_week = (num_of_days - days_in_first_week) % 7; + + int middle_weeks = (num_of_days - days_in_first_week - days_in_last_week) / 7; + + if (days_in_first_week != 0) { + extra_rows++; + } + + if (days_in_last_week != 0) { + extra_rows++; + } + + int minimum_rows = middle_weeks + extra_rows; + + return minimum_rows; +} + // Draws the lines for a month //int draw_month_grid (cairo_t *c, int month, int start_day) { @@ -122,9 +190,12 @@ int print_dimensions(struct dimensions *d) { // 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; + + // Push bottom of month as far down the page as the margin allows + int row_offset = d->row_count - calculate_minimum_rows(start_day, days_in_month, d); + double cursor_y = d->month_top_corner_y + (row_offset * d->day_height); int current_day = start_day; @@ -138,8 +209,13 @@ int draw_month (cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct dimensions * // the function. if (increment >= days_in_month) return 0; - // Fill bg with color + + if ((k == 0) || (k == 6)) { + cairo_set_source_rgb (cd, 255.0, 0.0, 0.0); + } else { cairo_set_source_rgb (cd, 0.0, 0.0, 255.0); + } + fill_bg(cd); // Change text color @@ -151,7 +227,11 @@ int draw_month (cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct dimensions * // Position within cd is arbitrary: (0,0) is too close to edge - draw_text(cd, 4.0, 4.0, str); + draw_text(cd, 4.0, 4.0, "Sans", 10, str); + + if ((k == 0) || (k == 6)) { + draw_text(cd, d->day_width - 40.0, d->day_height - 40.0, "Sans", 10, "▨"); + } // Position sub-surface on main surface @@ -173,11 +253,14 @@ int draw_month (cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct dimensions * 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); +int draw_month_title(cairo_t *c, struct dimensions *d, char *name) { + PangoRectangle rect; + + rect = get_logical_extents(c, "Sans", 40, name); + + + double cursor_x = (d->paper_width / 2.0) - ((rect.width / 2.0)); + double cursor_y = 50.0; + draw_text(c, cursor_x, cursor_y, "Sans", 40, name); + return 0; } @@ -14,7 +14,7 @@ struct dimensions { int fill_bg(cairo_t *c); -int draw_text(cairo_t *c, double x, double y, char *text); +int draw_text (cairo_t *c, double x, double y, char *font_family, int font_size, char *text); int calculate_dimensions(double pw, double ph, struct dimensions *d); @@ -25,3 +25,11 @@ int print_dimensions(struct dimensions *d); int draw_month (cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct dimensions *d, int days_in_month, int start_day); int day_of_week (int d, int m, int y); + +int draw_month_title(cairo_t *c, struct dimensions *d, char *name); + +PangoRectangle get_logical_extents (cairo_t *c, char *font_family, int font_size, char *text); + +int calculate_minimum_rows(int first_day, int num_of_days, struct dimensions *d); + + |
