diff options
| author | foswret | 2026-05-23 14:09:36 -0500 |
|---|---|---|
| committer | foswret | 2026-05-23 14:09:36 -0500 |
| commit | 5ead4f6c3d36557c56e27cf52835409d81ae6ed8 (patch) | |
| tree | 006ecd1051d3b0fd142fe55a90973e5746d3e5fb | |
| parent | 924ca70a4006abbffc8f43f27c4f64c8fc517a08 (diff) | |
remove month art drawing for now, working toward removing dimension struct in favor of generic extent structs
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | src/calp.c | 132 | ||||
| -rw-r--r-- | src/draw.c | 99 | ||||
| -rw-r--r-- | src/draw.h | 25 | ||||
| -rw-r--r-- | src/image.c | 11 | ||||
| -rw-r--r-- | src/image.h | 3 |
6 files changed, 168 insertions, 103 deletions
@@ -31,6 +31,7 @@ $ LANG=nl_NL.utf8 calp # Planned Features - Sunrise/sunset calcuations - Moon phase calculations +- Switch between US day-ordering convention and ISO 8601 (first day = Monday) # Credits - ezini library by Michael Dipperstein @@ -13,13 +13,6 @@ #include "color.h" #include "image.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 @@ -28,33 +21,40 @@ int main (void) { // Definitions // ----------- - double width = A4_WIDTH; - double height = A4_HEIGHT; - - const int row_count = 6; - const int column_count = 7; + double paper_width = A4_WIDTH; + double paper_height = A4_HEIGHT; // Convert to inches, then 1 unit = 1/72th inch - width = (width / 25.4) * 72.0; - height = (height / 25.4) * 72.0; + paper_width = (paper_width / 25.4) * 72.0; + paper_height = (paper_height / 25.4) * 72.0; + - //extern char *months[]; int num_of_months = 12; char *months[num_of_months]; extern int days_in_month[12]; + char *week_names[7]; + //const nl_item nl_abmons[12] = {ABMON_1, ABMON_2, ABMON_3, ABMON_4, // ABMON_5, ABMON_6, ABMON_7, ABMON_8, // ABMON_9, ABMON_10, ABMON_11, ABMON_12}; - const nl_item nl_months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, + const nl_item locale_months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, MON_8, MON_9, MON_10, MON_11, MON_12}; - int i; + const nl_item locale_days[7] = {ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, + ABDAY_5, ABDAY_6, ABDAY_7}; + setlocale(LC_ALL, ""); - for (i = 0; i < 12; i++) { - months[i] = nl_langinfo(nl_months[i]); + + for (int i = 0; i < 12; i++) { + months[i] = nl_langinfo(locale_months[i]); + } + + for (int i = 0; i < 7; i++) { + week_names[i] = nl_langinfo(locale_days[i]); + printf("%s\n", week_names[i]); } @@ -62,19 +62,27 @@ int main (void) { // Create dimensions struct to hold measurements struct dimensions dim; + const int row_count = 6; + const int column_count = 7; + + // Create dimensions struct to hold information about a // month - struct month_info month; + struct month_info month = { + .row_count = row_count, + .column_count = column_count + }; + // Leap year adjustment: increment February day count by one if // it is a leap year. const int year = 2026; + if (isleap(year)) { days_in_month[1]++; } - int verbose_output = 0; // TBD: Add ability to choose filename @@ -86,22 +94,35 @@ int main (void) { // Initialization // -------------- // Calculates measurements, stores them in dimensions struct. See "draw.h" - calculate_dimensions(width, height, &dim); + calculate_dimensions(paper_width, paper_height, &dim); + // Height and width of the paper + // .x and .y are empty struct extents paper_extents = { - .width = width, - .height = height + .width = paper_width, + .height = paper_height }; const double margin = 0.05 * paper_extents.width; + struct alignment page_layout = { + .margin = margin + }; + + // Width and Height of the boxes are set + // No position data is set until later. struct extents day_extents = { .width = paper_extents.width / 10.0, .height = paper_extents.width / 10.0 }; + //struct extents week_name_extents = { + // .width = day_extents.width + //}; + + // Position and dimensions of the month "grid" struct extents month_extents = { .x = (paper_extents.width - (day_extents.width * column_count)) / 2.0, .y = paper_extents.height - margin - (day_extents.height * row_count), @@ -109,20 +130,42 @@ int main (void) { .height = day_extents.height * row_count, }; - printf("%f\n", month_extents.x); + + // Position and width of the header + // Height is set dynamically, based on the size of + // the month grid + struct extents header_extents = { + .x = margin, + .y = margin, + .width = paper_extents.width - (margin * 2.0), + }; + // Program fails if the PDF backend isn't available if (!CAIRO_HAS_PDF_SURFACE) { printf("Error: PDF backend not available.\n"); return 1; } - cairo_surface_t *surface = cairo_pdf_surface_create(filename, paper_extents.width, paper_extents.height); + // Main surface and context are created + cairo_surface_t *surface = + cairo_pdf_surface_create( + filename, + paper_extents.width, + paper_extents.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, day_extents.width, day_extents.height); + cairo_surface_create_similar( + surface, + CAIRO_CONTENT_COLOR_ALPHA, + day_extents.width, + day_extents.height + ); // cd = context day cairo_t *cd = cairo_create(day); @@ -146,32 +189,36 @@ int main (void) { month.month_position = i; month.minimum_rows = calculate_minimum_rows(&month); - 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); + double month_header_spacing = margin * 3.0; - 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); + header_extents.height = paper_extents.height - month_header_spacing - ((month.minimum_rows + 1) * day_extents.height); + // Create another surface and context for working with the + // header + cairo_surface_t *header = cairo_surface_create_similar( + surface, + CAIRO_CONTENT_COLOR_ALPHA, + header_extents.width, + header_extents.height + ); + cairo_t *ch = cairo_create(header); - set_color(ch, BLACK); - draw_month_title(ch, &dim, "Sans", 40, months[i]); - char path[20]; - snprintf(path, 20, "assets/%d.png", i + 1); + set_color(ch, BLUE); + fill_bg(ch); - if (verbose_output) { - printf("Drawing month \'%s\'\n", months[i]); - } - draw_month_art(paper, &dim, path); + set_color(ch, BLACK); + draw_month_title(ch, &header_extents, &page_layout, FONT_FAMILY, FONT_SIZE_LARGE, months[i]); - cairo_set_source_surface(paper, header, dim.margin, dim.margin); + // Draw the header + cairo_set_source_surface(paper, header, header_extents.x, header_extents.y); cairo_paint(paper); - draw_month(paper, cd, day, &month, &dim); + draw_month_dates(paper, cd, day, &month, &month_extents, &day_extents); draw_month_grid(paper, &month, &month_extents, &day_extents); // Go to the next page in pdf @@ -182,9 +229,6 @@ int main (void) { } - if (verbose_output) { - printf("Finished generating \'%s\'.\n", filename); - } // Clean up @@ -5,6 +5,7 @@ #include "color.h" + // struct for storing dimensions used for calculations, movement, etc. struct dimensions { @@ -34,6 +35,8 @@ month_info { int month_position; int first_day; int num_of_days; + int column_count; + int row_count; int minimum_rows; }; @@ -56,7 +59,10 @@ struct extents { double height; }; - +struct alignment { + double margin; + double padding; +}; // Convert Hex color strings to their RGB counterparts. // IMO, hex strings are easier to work with, so this is @@ -170,6 +176,30 @@ get_logical_extents (cairo_t *c, char *font_family, int font_size, char *text) { } +PangoRectangle +get_ink_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 // Used for determining where elements should be drawn on the page @@ -208,27 +238,6 @@ calculate_dimensions(double pw, double ph, struct dimensions *d) { } -// Print the contents of a dimensions struct. -// Use for debugging -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); - //printf("header width: %.2f\n", d->header_width); - //printf("header height: %.2f\n", d->header_height); - return 0; -} - - // Calculate minimum amount of rows a month can fit in. // Most months can fit within 4 or 5 rows instead of 6. @@ -266,13 +275,10 @@ calculate_minimum_rows(struct month_info *m) { int draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct extents *de) { double cursor_x = me->x; - - int column_count = 7; - int row_count = 6; // double cursor_x = month_grid_pos->x; // make d->row_count reside in month_info *m - int row_offset = row_count - calculate_minimum_rows(m); + int row_offset = m->row_count - calculate_minimum_rows(m); // double cursor_y = month_grid_pos->y; double cursor_y = me->y + (row_offset * de->height); @@ -283,7 +289,7 @@ draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct ex cairo_set_line_width(c, 1.0); // Vertical lines - for (int i = 0; i <= column_count; i++) { + for (int i = 0; i <= m->column_count; i++) { cairo_move_to(c, cursor_x, cursor_y); cairo_line_to(c, cursor_x, cursor_y + (me->height - (row_offset * de->height))); cursor_x = cursor_x + de->width; @@ -294,7 +300,7 @@ draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct ex cursor_y = y; // Horizontal lines - for (int i = 0; i <= row_count; i++) { + for (int i = 0; i <= m->row_count; i++) { cairo_move_to(c, cursor_x, cursor_y); cairo_line_to(c, cursor_x + me->width, cursor_y); cursor_y = cursor_y + de->height; @@ -309,7 +315,7 @@ draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct ex int construct_day_box(cairo_t *cd, int month, int day, int week_day) { char str[20]; - double padding = 8.0; + double padding = 3.0; set_color(cd, WHITE); fill_bg(cd); @@ -330,22 +336,22 @@ construct_day_box(cairo_t *cd, int month, int day, int week_day) { // 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 month_info *m, struct dimensions *d) { - double cursor_x = d->month_top_corner_x; +draw_month_dates(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, struct extents *me, struct extents *de) { + double cursor_x = me->x; - if (m->first_day != 0) cursor_x = cursor_x + (d->day_width * m->first_day); + if (m->first_day != 0) cursor_x = cursor_x + (de->width * m->first_day); // Push bottom of month as far down the page as the margin allows - int row_offset = d->row_count - calculate_minimum_rows(m); - double cursor_y = d->month_top_corner_y + (row_offset * d->day_height); + int row_offset = m->row_count - calculate_minimum_rows(m); + double cursor_y = me->y + (row_offset * de->height); int current_day = m->first_day; int increment = 0; - for (int i = 0; i < d->row_count; i++) { - for (int k = current_day; k < d->column_count; k++) { + for (int i = 0; i < m->row_count; i++) { + for (int k = current_day; k < m->column_count; k++) { // When the increment reached the end of the month, end // the function. if (increment >= m->num_of_days) return 0; @@ -359,14 +365,14 @@ draw_month(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, st cairo_paint(c); // Move cursor one "box" over - cursor_x = cursor_x + d->day_width; + cursor_x = cursor_x + de->width; increment++; } current_day = 0; - cursor_x = d->month_top_corner_x; - cursor_y = cursor_y + d->day_height; + cursor_x = me->x; + cursor_y = cursor_y + de->height; } cairo_stroke(cd); @@ -377,21 +383,20 @@ draw_month(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, st // Draws the month being drawn at the top of the page int -draw_month_title(cairo_t *c, struct dimensions *d, char *font_family, int font_size, char *name) { +draw_month_title(cairo_t *c, struct extents *he, struct alignment *pl, char *font_family, int font_size, char *name) { PangoRectangle rect; rect = get_logical_extents(c, font_family, font_size, name); - //double cursor_x = (d->header_height / 2.0) - ((rect.width / 2.0)); - double cursor_x = ((d->header_width - rect.width) / 2.0); - //double cursor_y = height + d->margin; - double cursor_y = d->header_height - rect.height - d->margin; + double cursor_x = ((he->width - rect.width) / 2.0); + double cursor_y = he->height - pl->margin - rect.height; + draw_text(c, cursor_x, cursor_y, font_family, font_size, name); return 0; } - -//int draw_weekday_names(cairo_t *c, struct dimensions *d) { -// +//int +//draw_week_names(cairo_t *c, struct month_info *m, struct extents *me, struct extents *dte, char **names) { +// return 0; //} @@ -1,3 +1,10 @@ +// Metric +#define A4_WIDTH 210 +#define A4_HEIGHT 297 + +#define US_LETTER_WIDTH 216 +#define US_LETTER_HEIGHT 279 + struct dimensions { int row_count; /* rows */ @@ -30,6 +37,8 @@ month_info { int month_position; int first_day; int num_of_days; + int column_count; + int row_count; int minimum_rows; }; @@ -42,6 +51,12 @@ extents { }; +struct alignment { + double margin; + double padding; +}; + + struct RGB hex_to_rgb(char *str); @@ -54,9 +69,6 @@ draw_text(cairo_t *c, double x, double y, char *font_family, int font_size, char int calculate_dimensions(double pw, double ph, struct dimensions *d); -int -print_dimensions(struct dimensions *d); - //int //draw_month_grid(cairo_t *c, struct month_info *m, struct dimensions *d); @@ -64,17 +76,20 @@ int draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct extents *de); int -draw_month(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, struct dimensions *d); +draw_month_dates(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, struct extents *me, struct extents *de); int day_of_week(int d, int m, int y); int -draw_month_title(cairo_t *c, struct dimensions *d, char *font_family, int font_size, char *name); +draw_month_title(cairo_t *c, struct extents *he, struct alignment *pl, char *font_family, int font_size, char *name); PangoRectangle get_logical_extents(cairo_t *c, char *font_family, int font_size, char *text); +PangoRectangle +get_ink_extents (cairo_t *c, char *font_family, int font_size, char *text); + int calculate_minimum_rows(struct month_info *m); diff --git a/src/image.c b/src/image.c index 6180631..d9ee5fa 100644 --- a/src/image.c +++ b/src/image.c @@ -49,17 +49,16 @@ int draw_image(cairo_t *c, char *path, double x, double y) { // Draw month art -int draw_month_art(cairo_t *c, struct dimensions *d, char *path) { +int draw_month_art(cairo_t *c, struct dimensions *d, struct extents *he, struct alignment *pl, char *path) { cairo_save(c); - double width = d->header_width; + double width = he->width; // TODO: Make this relative to text height - double height = d->header_height - (d->margin * 3.0); + double height = he->height - (pl->margin * 3.0); - double cursor_x = d->margin; + double cursor_x = pl->margin; double cursor_y = d->margin; - cairo_rectangle (c, d->margin, d->margin, width, height); + cairo_rectangle (c, cursor_x, cursor_y, width, height); cairo_clip(c); - draw_image(c, path, cursor_x, cursor_y); cairo_restore(c); diff --git a/src/image.h b/src/image.h index edfdec3..bebdacf 100644 --- a/src/image.h +++ b/src/image.h @@ -1,3 +1,4 @@ int draw_image(cairo_t *c, char *path, double x, double y); -int draw_month_art(cairo_t *c, struct dimensions *d, char *path); +int draw_month_art(cairo_t *c, struct extents *he, struct alignment *pl, char *path); + |
