From 924ca70a4006abbffc8f43f27c4f64c8fc517a08 Mon Sep 17 00:00:00 2001
From: foswret
Date: Fri, 22 May 2026 11:52:34 -0500
Subject: draw_month_grid() doesn't use dimension struct anymore. create
generate extents structs for month, paper, and day
---
src/calp.c | 47 ++-
src/draw.c | 47 ++-
src/draw.h | 16 +-
src/ezini.c | 1033 -----------------------------------------------------------
src/ezini.h | 121 -------
src/image.c | 173 +---------
src/image.h | 10 -
7 files changed, 92 insertions(+), 1355 deletions(-)
delete mode 100644 src/ezini.c
delete mode 100644 src/ezini.h
(limited to 'src')
diff --git a/src/calp.c b/src/calp.c
index 8acef9b..8202ab8 100644
--- a/src/calp.c
+++ b/src/calp.c
@@ -12,7 +12,6 @@
#include "date.h"
#include "color.h"
#include "image.h"
-#include "ezini.h"
// Metric
#define A4_WIDTH 210
@@ -32,6 +31,9 @@ int main (void) {
double width = A4_WIDTH;
double height = A4_HEIGHT;
+ const int row_count = 6;
+ const int column_count = 7;
+
// Convert to inches, then 1 unit = 1/72th inch
width = (width / 25.4) * 72.0;
height = (height / 25.4) * 72.0;
@@ -43,16 +45,15 @@ int main (void) {
char *months[num_of_months];
extern int days_in_month[12];
- 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_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,
MON_7, MON_8, MON_9, MON_10, MON_11, MON_12};
int i;
setlocale(LC_ALL, "");
for (i = 0; i < 12; i++) {
- printf("%d\t%s\t%s\n", i+1, nl_langinfo(nl_abmons[i]), nl_langinfo(nl_months[i]));
months[i] = nl_langinfo(nl_months[i]);
}
@@ -68,7 +69,7 @@ int main (void) {
// Leap year adjustment: increment February day count by one if
// it is a leap year.
- int year = 14;
+ const int year = 2026;
if (isleap(year)) {
days_in_month[1]++;
}
@@ -87,17 +88,41 @@ int main (void) {
// Calculates measurements, stores them in dimensions struct. See "draw.h"
calculate_dimensions(width, height, &dim);
+
+
+ struct extents paper_extents = {
+ .width = width,
+ .height = height
+ };
+
+ const double margin = 0.05 * paper_extents.width;
+
+ struct extents day_extents = {
+ .width = paper_extents.width / 10.0,
+ .height = paper_extents.width / 10.0
+ };
+
+ 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),
+ .width = day_extents.width * column_count,
+ .height = day_extents.height * row_count,
+ };
+
+ printf("%f\n", month_extents.x);
+
+
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_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, dim.day_width, dim.day_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);
@@ -119,7 +144,7 @@ int main (void) {
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);
+ 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);
@@ -137,8 +162,6 @@ int main (void) {
snprintf(path, 20, "assets/%d.png", i + 1);
- prepare_month_art(path, &dim);
-
if (verbose_output) {
printf("Drawing month \'%s\'\n", months[i]);
}
@@ -149,7 +172,7 @@ int main (void) {
cairo_paint(paper);
draw_month(paper, cd, day, &month, &dim);
- draw_month_grid(paper, &month, &dim);
+ draw_month_grid(paper, &month, &month_extents, &day_extents);
// Go to the next page in pdf
cairo_show_page(paper);
diff --git a/src/draw.c b/src/draw.c
index 051e12b..54a7ad3 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -47,6 +47,16 @@ RGB {
};
+// Generic struct for storing where an object is and how
+// it takes up space.
+struct extents {
+ double x;
+ double y;
+ double width;
+ double height;
+};
+
+
// Convert Hex color strings to their RGB counterparts.
// IMO, hex strings are easier to work with, so this is
@@ -58,6 +68,7 @@ RGB hex_to_rgb(char *str) {
sscanf(str, "%02x%02x%02x", &r, &g, &b);
+ // R, G, B values are from 0.0 - 1.0, so needs to be divided by 255.0
color.r = (r / 255.0);
color.g = (g / 255.0);
color.b = (b / 255.0);
@@ -223,10 +234,10 @@ print_dimensions(struct dimensions *d) {
// 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(struct month_info *m, struct dimensions *d) {
+calculate_minimum_rows(struct month_info *m) {
int extra_rows = 0;
- int days_in_first_week = (d->column_count - m->first_day);
+ int days_in_first_week = (7 - m->first_day);
if (m->first_day == 0) {
days_in_first_week = m->first_day;
@@ -253,32 +264,40 @@ calculate_minimum_rows(struct month_info *m, struct dimensions *d) {
// Draws the grid lines for a month
int
-draw_month_grid (cairo_t *c, struct month_info *m, struct dimensions *d) {
- double cursor_x = d->month_top_corner_x;
+draw_month_grid (cairo_t *c, struct month_info *m, struct extents *me, struct extents *de) {
+ double cursor_x = me->x;
- int row_offset = d->row_count - calculate_minimum_rows(m, d);
- double cursor_y = d->month_top_corner_y + (row_offset * d->day_height);
+ 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);
+ // double cursor_y = month_grid_pos->y;
+ double cursor_y = me->y + (row_offset * de->height);
double x = cursor_x;
double y = cursor_y;
set_color(c, BLACK);
- cairo_set_line_width (c, 1.0);
+ cairo_set_line_width(c, 1.0);
- for (int i = 0; i <= d->column_count; i++) {
+ // Vertical lines
+ for (int i = 0; i <= column_count; i++) {
cairo_move_to(c, cursor_x, cursor_y);
- cairo_line_to(c, cursor_x, cursor_y + (d->month_height - (row_offset * d->day_height)));
- cursor_x = cursor_x + d->day_width;
+ cairo_line_to(c, cursor_x, cursor_y + (me->height - (row_offset * de->height)));
+ cursor_x = cursor_x + de->width;
}
// Recenter the cursor
cursor_x = x;
cursor_y = y;
- for (int i = 0; i <= d->row_count; i++) {
+ // Horizontal lines
+ for (int i = 0; i <= row_count; i++) {
cairo_move_to(c, cursor_x, cursor_y);
- cairo_line_to(c, cursor_x + d->month_width, cursor_y);
- cursor_y = cursor_y + d->day_height;
+ cairo_line_to(c, cursor_x + me->width, cursor_y);
+ cursor_y = cursor_y + de->height;
}
cairo_stroke(c);
@@ -317,7 +336,7 @@ draw_month(cairo_t *c, cairo_t *cd, cairo_surface_t *s, struct month_info *m, st
if (m->first_day != 0) cursor_x = cursor_x + (d->day_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, d);
+ int row_offset = d->row_count - calculate_minimum_rows(m);
double cursor_y = d->month_top_corner_y + (row_offset * d->day_height);
int current_day = m->first_day;
diff --git a/src/draw.h b/src/draw.h
index 9de1ed0..274fd29 100644
--- a/src/draw.h
+++ b/src/draw.h
@@ -33,6 +33,15 @@ month_info {
int minimum_rows;
};
+struct
+extents {
+ double x;
+ double y;
+ double width;
+ double height;
+};
+
+
struct
RGB hex_to_rgb(char *str);
@@ -48,8 +57,11 @@ 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);
+
int
-draw_month_grid(cairo_t *c, struct month_info *m, struct dimensions *d);
+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);
@@ -64,7 +76,7 @@ PangoRectangle
get_logical_extents(cairo_t *c, char *font_family, int font_size, char *text);
int
-calculate_minimum_rows(struct month_info *m, struct dimensions *d);
+calculate_minimum_rows(struct month_info *m);
int
construct_day_box(cairo_t *cd, int month, int day, int week_day);
diff --git a/src/ezini.c b/src/ezini.c
deleted file mode 100644
index ee1f79e..0000000
--- a/src/ezini.c
+++ /dev/null
@@ -1,1033 +0,0 @@
-/**
- * \brief INI File handling library
- * \file ezini.c
- * \author Michael Dipperstein (mdipperstein@gmail.com)
- * \date November 22, 2015
- *
- * This file implements a set of library functions that maybe be used
- * to create, update, and/or parse INI files.
- *
- * \copyright Copyright (C) 2015, 2019 by Michael Dipperstein
- * (mdipperstein@gmail.com)
- *
- * \par
- * This file is part of the ezini library.
- *
- * \license
- * The ezini library is free software; you can redistribute it
- * and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * \par
- * The ezini library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- *
- * \par
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- *
- */
-
-/**
- * \defgroup library Library Code
- * \brief This module contains the code for the ezini INI file handling
- * library
- * @{
- */
-
-/***************************************************************************
-* INCLUDED FILES
-***************************************************************************/
-#include
-#include
-#include
-#include
-#include
-#include "ezini.h"
-
-/***************************************************************************
-* TYPE DEFINITIONS
-***************************************************************************/
-
-/**
- * \struct ini_key_list_t
- * \brief A structure used for creating linked lists of key/value pairs
- * for a each section.
- */
-
-/**
- * \typedef struct ini_key_list_t
- * \brief A shortcut for struct ini_key_list_t
- */
-
-typedef struct ini_key_list_t
-{
- char *key; /*!< pointer to a a NULL terminated string
- containing key name for this entry */
- char *value; /*!< pointer to a NULL terminated string
- containing key value for this entry Use
- ASCII strings to represent numbers */
- struct ini_key_list_t *next;/*!< pointer to the next key/value pair in
- in this section */
-
-} ini_key_list_t;
-
-
-/**
- * \struct ini_section_list_t
- * \brief A structure used for creating linked lists of sections, each
- * maintaining its own list of key/value pairs.
- */
-
-/**
- * \typedef struct ini_section_list_t
- * \brief A shortcut for struct ini_section_list_t
- */
-
-typedef struct ini_section_list_t
-{
- char *section; /*!< pointer to a NULL terminated string
- containing the section name */
- ini_key_list_t *members; /*!< pointer to the list of all key/value
- pairs in this section */
- struct ini_section_list_t *next; /*!< pointer to the next section in
- the list of entries */
-
-} ini_section_list_t;
-
-
-/***************************************************************************
-* PROTOTYPES
-***************************************************************************/
-
-/* allocate */
-static ini_key_list_t *NewKeyList(const char *key, const char *value);
-static ini_section_list_t *NewSectionList(const char *section, const char *key,
- const char *value);
-
-/* free */
-static void FreeKeyList(ini_key_list_t *list);
-static void FreeEntry(ini_entry_t *entry);
-
-/* utilities */
-static char *SkipWS(const char *str);
-static char *DupStr(const char *src);
-static char *GetLine(FILE *fp);
-
-/***************************************************************************
-* FUNCTIONS
-***************************************************************************/
-
-/**
- * \fn int AddEntryToList(ini_entry_list_t *list, const char *section,
- * const char *key, const char *value)
- *
- * \brief This function adds a (section, key, value) entry to an entry list.
- *
- * \param list A pointer to an ini_entry_list_t that points to the
- * head of entry list being modified. Pass a pointer to an ini_entry_list_t
- * pointing to NULL if the list needs to be created.
- *
- * \param section A NULL terminated string containing the name of the
- * section for the entry being added.
- *
- * \param key A NULL terminated string containing the name of the key for
- * the entry being added.
- *
- * \param value A NULL terminated string containing the value of the key for
- * the entry being added. All values must be represented as strings. They may
- * be converted to/from strings by the calling program.
- *
- * \effects
- * Information used to generate an entry structure containing copies of
- * the (section, key, value) entry is added to the list passed as a parameter.
- * Memory will be dynamically allocated as needed.
- *
- * \returns 0 for success, Non-zero on error. Error type is contained in
- * errno.
- *
- * This function adds information used to create a (section, key, value) entry
- * to an entry list.
- *
- * If an entry containing the same section name and key already exists,
- * the new value will overwrite the old value.
- *
- * If the entry is for an existing section, it will be added to the end of the
- * list for that section.
- *
- * If the entry is for a new section, a new section will be added to the list of
- * sections, and the key/value pair will be the first entry of the section.
- */
-int AddEntryToList(ini_entry_list_t *list, const char *section,
- const char *key, const char *value)
-{
- ini_section_list_t *next;
- int result;
-
- /* handle empty list */
- if (NULL == *list)
- {
- /* add the first entry to the list */
- *list = NewSectionList(section, key, value);
-
- if (NULL == *list)
- {
- return -1;
- }
-
- return 0;
- }
-
- next = *list;
- result = 1;
-
- while (1)
- {
- result = strcmp(section, next->section);
-
- if (0 == result)
- {
- break; /* match, insert here */
- }
-
- if (NULL == next->next)
- {
- break; /* no match, create new section here */
- }
-
- next = next->next;
- }
-
- if (0 == result)
- {
- ini_key_list_t *member;
-
- member = next->members;
-
- while (1)
- {
- result = strcmp(key, member->key);
-
- if (0 == result)
- {
- break; /* match, insert here */
- }
-
- if (NULL == member->next)
- {
- break; /* no match, create new section here */
- }
-
- member = member->next;
- }
-
- if (0 == result)
- {
- /* key exists, change value */
- free(member->value);
- member->value = DupStr(value);
-
- if (NULL == member->value)
- {
- return -1;
- }
- }
- else
- {
- /* new key, add to list */
- member->next = NewKeyList(key, value);
-
- if (NULL == member->next)
- {
- return -1;
- }
- }
- }
- else
- {
- /* add the section to the list with this key and value */
- next->next = NewSectionList(section, key, value);
- }
-
- return 0;
-}
-
-
-/**
- * \fn void FreeList(ini_entry_list_t list)
- *
- * \brief This function frees all of the members of an entry list.
- *
- * \param list A pointer to the head of an ini_entry_list_t
- *
- * \effects
- * All of the memory allocated for all of the entries in an entry
- * list will be freed.
- *
- * \returns Nothing
- *
- * This function uses recursion to step to the tail of the list and deletes
- * section entries on the way back up.
- */
-void FreeList(ini_entry_list_t list)
-{
- /* recurse to the end of the list and free everything on the way back */
- if (list->next != NULL)
- {
- FreeList(list->next);
- }
-
- if (list->section != NULL)
- {
- /* free the section name */
- free(list->section);
- }
-
- if (list->members != NULL)
- {
- FreeKeyList(list->members);
- }
-
- free(list);
-}
-
-
-/**
- * \fn int MakeINIFile(const char *iniFile, const ini_entry_list_t list)
- *
- * \brief This function creates the specified INI file from the list of
- * entries passed as an argument.
- *
- * \param iniFile The name of the INI file to be created. stdout will be
- * used if iniFile is NULL.
- *
- * \param list A pointer to a list of that will be used to construct
- * (section, key, value) entries.
- *
- * \effects
- * The specified file is created and the (section, key, value)
- * triples generated from the entry list are written to the file. If the
- * specified file already exists, it will be overwritten.
- *
- * \returns 0 for success, Non-zero on error. Error type is contained in
- * errno.
- *
- * This function creates the specified INI file from the list of entries
- * passed as an argument. Any existing INI file with the same name in the
- * same path will be overwritten.
- */
-int MakeINIFile(const char *iniFile, const ini_entry_list_t list)
-{
- ini_entry_list_t section;
- ini_key_list_t *members;
- FILE *fp;
-
- if (NULL == list)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (NULL == iniFile)
- {
- fp = stdout;
- }
- else
- {
-
- fp = fopen(iniFile, "w");
-
- if (NULL == fp)
- {
- return -1;
- }
- }
-
- section = list;
-
- while (section != NULL)
- {
- fprintf(fp, "[%s]\n", section->section);
-
- members = section->members;
-
- while (members != NULL)
- {
- fprintf(fp, "%s = %s\n", members->key, members->value);
- members = members->next;
- }
-
- fprintf(fp, "\n");
- section = section->next;
- }
-
- if (fp != stdout)
- {
- fclose(fp);
- }
-
- return 0;
-}
-
-
-/**
- * \fn int AddEntryToFile(const char *iniFile, const ini_entry_list_t list)
- *
- * \brief This function adds (section, key, value) entries in an entry list
- * to an INI file.
- *
- * \param iniFile The name of the INI file to be modified.
- *
- * \param list A pointer to a list of entries to be added to the INI file.
- *
- * \effects
- * The INI file will be re-written containing the results of adding
- * the entries in the entry list to the entries already contained in the INI
- * file.
- *
- * \returns 0 for success, Non-zero on error. Error type is contained in
- * errno.
- *
- * This function adds (section, key, value) entries in an entry list to an
- * INI file. Section order will be maintained with new sections added to the
- * end of the INI file. If an entry containing the same section name and key
- * already exists, the new value will overwrite the old value.
- */
-int AddEntryToFile(const char *iniFile, const ini_entry_list_t list)
-{
- ini_entry_t entry;
- ini_entry_list_t merged;
- ini_entry_list_t here;
- int result;
- FILE *fp;
-
- if (NULL == iniFile)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (NULL == list)
- {
- errno = EINVAL;
- return -1;
- }
-
- fp = fopen(iniFile, "r");
-
- if (NULL == fp)
- {
- return -1;
- }
-
- merged = NULL;
- entry.section = NULL;
- entry.key = NULL;
- entry.value = NULL;
-
- /* read ini file back into an entry list */
- while ((result = GetEntryFromFile(fp, &entry)) > 0)
- {
- AddEntryToList(&merged, entry.section, entry.key, entry.value);
- }
-
- fclose(fp);
-
- if (result < 0)
- {
- FreeList(merged);
- return -1;
- }
-
- /* add entries passed into this function to entries from INI file */
- here = list;
-
- while (here != NULL)
- {
- ini_key_list_t *members;
-
- members = here->members;
-
- while (members != NULL)
- {
- AddEntryToList(&merged, here->section, members->key,
- members->value);
- members = members->next;
- }
-
- here = here->next;
- }
-
- /* re-write INI file from merged entry list */
- result = MakeINIFile(iniFile, merged);
- FreeList(merged);
-
- return result;
-}
-
-/**
- * \fn int DeleteEntryFromFile(const char *iniFile, const char *section,
- * const char *key)
- *
- * \brief This function deletes all entries from an INI file that match the
- * section and key passed as an argument.
- *
- * \param iniFile The name of the INI file containing the entry to be
- * deleted.
- *
- * \param section A pointer to a NULL terminated string containing the name
- * of the section of the entry to be deleted.
- *
- * \param key A pointer to a NULL terminated string containing the name of
- * the key of the entry to be deleted.
- *
- * \effects
- * The INI file will be re-written without any entries that match
- * the section and key to be deleted. Empty sections will not be deleted.
- *
- * \returns 0 for success, Non-zero on error. Error type is contained in
- * errno.
- *
- * This function deletes all entries from an INI file that match the section
- * and key passed as an argument. Empty sections will not be deleted.
- *
- * \note There will never be more than one matching entry in INI files
- * created by this library.
- */
-int DeleteEntryFromFile(const char *iniFile, const char *section,
- const char *key)
-{
- ini_entry_t entry;
- ini_entry_list_t list;
- int result;
- FILE *fp;
-
- if (NULL == iniFile)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (NULL == section)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (NULL == key)
- {
- errno = EINVAL;
- return -1;
- }
-
- fp = fopen(iniFile, "r");
-
- if (NULL == fp)
- {
- return -1;
- }
-
- list = NULL;
- entry.section = NULL;
- entry.key = NULL;
- entry.value = NULL;
-
- /* read ini file back into a structure */
- while ((result = GetEntryFromFile(fp, &entry)) > 0)
- {
- if (0 != strcmp(entry.section, section))
- {
- /* this isn't one we're supposed to delete */
- AddEntryToList(&list, entry.section, entry.key, entry.value);
- }
- else if (0 != strcmp(entry.key, key))
- {
- /* this isn't one we're supposed to delete */
- AddEntryToList(&list, entry.section, entry.key, entry.value);
- }
- }
-
- fclose(fp);
-
- if (result < 0)
- {
- FreeList(list);
- return -1;
- }
-
- result = MakeINIFile(iniFile, list);
- FreeList(list);
-
- return result;
-}
-
-/**
- * \fn int GetEntryFromFile(FILE *iniFile, ini_entry_t *entry)
- *
- * \brief This function parses an INI file stream passed as an input,
- * searching for the next (section, key, value) triple.
- *
- * \param iniFile A pointer to the INI file to be parsed. It must be
- * opened for reading.
- *
- * \param entry A pointer to the entry structure used to store the discovered
- * (section, key, value) triple.
- *
- * \effects
- * The specified file is read until it discovers an entry.
- *
- * \returns 1 when an entry is found\n
- * 0 when no more entries can be found\n
- * -1 for an error. Error type is contained in errno.
- *
- * This function parses an INI file stream passed as an input, searching for
- * the next (section, key, value) triple. The resulting triple will be used
- * to populate the entry structure passed as a parameter.
- */
-int GetEntryFromFile(FILE *iniFile, ini_entry_t *entry)
-{
- char *line;
- char *ptr;
-
- if (NULL == iniFile)
- {
- errno = EINVAL;
- return -1;
- }
-
- if (NULL == entry)
- {
- errno = EINVAL;
- return -1;
- }
-
- /* handle section names, comments, and blank lines */
- while ((line = GetLine(iniFile)) != NULL)
- {
- /* skip leading spaces and blank lines */
- ptr = SkipWS(line);
-
- /* skip blank lines and lines starting with ';' or '#' */
- if (*ptr == '\0' || *ptr == ';' || *ptr == '#')
- {
- free(line);
- continue;
- }
- else if (*ptr == '[')
- {
- /* possible new section */
- char *end;
-
- end = strchr(ptr, ']');
-
- if (NULL == end)
- {
- FreeEntry(entry);
- errno = EILSEQ;
- return -1;
- }
-
- /* we have the full string for a new section, trim white space */
- ptr = SkipWS(ptr + 1);
-
- while (isspace(*(end - 1)))
- {
- end--;
- }
-
- *end = '\0';
-
- free(entry->section);
- entry->section = DupStr(ptr);
- free(line);
- }
- else
- {
- /* this line should be key = value */
- break;
- }
- }
-
- /* we either have a non-section line or nothing left to get */
- if (NULL == line)
- {
- /* nothing left to get */
- FreeEntry(entry);
- return 0;
- }
-
- /* the only other allowable lines are of the form key = value */
- free(entry->key); /* free old key */
- entry->key = ptr;
- ptr++;
-
- while (*ptr != '=')
- {
- if (*ptr == '\0')
- {
- /* didn't find '=' */
- entry->key = NULL;
- FreeEntry(entry);
- free(line);
- errno = EILSEQ;
- return -1;
- }
-
- ptr++;
- }
-
- /* we found the '=' separating key and value trim white space */
- free(entry->value); /* free old value */
- entry->value = ptr + 1;
- ptr--;
-
- while (isspace(*ptr))
- {
- ptr--;
- }
-
- *(ptr + 1) = '\0';
- entry->key = DupStr(entry->key);
-
- ptr = entry->value;
-
- /* now skip white space after '=' */
- while (*ptr == ' ' || *ptr =='\t')
- {
- if (*ptr == '\0')
- {
- FreeEntry(entry);
- free(line);
- errno = EILSEQ;
- return -1;
- }
-
- ptr++;
- }
-
- /* we found the start of value, trim trailing white space */
- entry->value = ptr;
- ptr = entry->value + strlen(entry->value) - 1;
-
- while (isspace(*ptr))
- {
- ptr--;
- }
-
- *(ptr + 1) = '\0';
- entry->value = DupStr(entry->value);
-
- free(line);
- return 1;
-}
-
-
-/**
- * \fn ini_key_list_t *NewKeyList(const char *key, const char *value)
- *
- * \brief This function allocates memory for a new ini_key_list_t type
- * variable and populates it with the data passed as parameters
- *
- * \param key A pointer to a NULL terminated string containing the key name
- *
- * \param key A pointer to a NULL terminated string containing the value of
- * this key. Use ASCII strings to represent numbers.
- *
- * \effects
- * Memory will be allocated for a new ini_key_list_t and copies
- * of the key and value strings passed as a parameter. key and value are
- * copied into the appropriate fields and the next pointer is set to NULL.
- *
- * \returns A pointer to the ini_key_list_t item that was allocated. The
- * pointer will be NULL if an error occurs.
- *
- * This function allocates memory for a new ini_key_list_t and copies
- * of the key and value strings passed as a parameter. The next pointer
- * will be set to NULL.
- */
-static ini_key_list_t *NewKeyList(const char *key, const char *value)
-{
- ini_key_list_t *item;
-
- item = (ini_key_list_t *)malloc(sizeof(ini_key_list_t));
-
- if (NULL == item)
- {
- return NULL;
- }
-
- /* allocation succeeded copy key and value */
- item->next = NULL;
-
- item->key = DupStr(key);
-
- if (NULL == item->key)
- {
- free(item);
- return NULL;
- }
-
- item->value = DupStr(value);
-
- if (NULL == item->value)
- {
- free(item->key);
- free(item);
- return NULL;
- }
-
- return item;
-}
-
-
-/**
- * \fn ini_section_list_t *NewSectionList(const char *section, const char *key,
- * const char *value)
- *
- * \brief This function allocates memory for a new ini_section_list_t type
- * variable and populates it with the data passed as parameters
- *
- * \param section A pointer to a NULL terminated string containing the section
- * name
-
- * \param key A pointer to a NULL terminated string containing the key name
- *
- * \param key A pointer to a NULL terminated string containing the value of
- * this key. Use ASCII strings to represent numbers.
- *
- * \effects
- * Memory will be allocated for a new ini_section_list_t and copies
- * of the section, key, value strings passed as a parameter. section is
- * copied to the appropriate field and a new key list items is created fo
- * the key and value strings. The next pointer will be set to NULL.
- *
- * \returns A pointer to the ini_section_list_t item that was allocated. The
- * pointer will be NULL if an error occurs.
- *
- * This function allocates memory for a new ini_section_list_t and copies
- * of the section, key, value strings passed as a parameter. A ini_key_list_t
- * is allocated for the key and value strings. The next pointer is set to NULL.
- */
-static ini_section_list_t *NewSectionList(const char *section, const char *key,
- const char *value)
-{
- ini_section_list_t *item;
-
- item = (ini_section_list_t *)malloc(sizeof(ini_section_list_t));
-
- if (NULL == item)
- {
- return NULL;
- }
-
- /* now populate item */
- item->next = NULL;
- item->section = DupStr(section);
-
- if (NULL == item->section)
- {
- free(item);
- return NULL;
- }
-
- /* start a member list with the current key and value */
- item->members = NewKeyList(key, value);
-
- if (NULL == item->members)
- {
- free(item->section);
- free(item);
- return NULL;
- }
-
- return item;
-}
-
-
-/**
- * \fn void FreeKeyList(ini_key_list_t *list)
- *
- * \brief This function frees all of the members of a key list.
- *
- * \param list A pointer to the head of an ini_key_list_t
- *
- * \effects All of the memory allocated for all of the key/value pairs in
- * a key list will be freed.
- *
- * \returns Nothing
- *
- * This function uses recursion to step to the tail of the list and deletes
- * key/value entries on the way back up.
- */
-static void FreeKeyList(ini_key_list_t *list)
-{
- /* recurse to the end of the list and free everything on the way back */
- if (list->next != NULL)
- {
- FreeKeyList(list->next);
- }
-
- free(list->key);
- free(list->value);
- free(list);
-}
-
-
-/**
- * \fn static void FreeEntry(ini_entry_t *entry)
- *
- * \brief This function frees the allocated memory that is pointed to by the
- * members of an ini_entry_t structure.
- *
- * \param entry A pointer to the entry structure containing the members
- * pointing to the memory to be freed.
- *
- * \effects Dynamically allocated memory is freed and entry data is set
- * to NULL.
- *
- * \returns Nothing
- */
-static void FreeEntry(ini_entry_t *entry)
-{
- free(entry->section);
- free(entry->key);
- free(entry->value);
-
- entry->section = NULL;
- entry->key = NULL;
- entry->value = NULL;
-}
-
-/**
- * \fn static char *SkipWS(const char *str)
- *
- * \brief This function returns a pointer to the first non-space in the
- * string passed as a parameter.
- *
- * \param str A pointer to the string being searched.
- *
- * \effects None
- *
- * \returns A pointer to the first non-space in str.
- */
-static char *SkipWS(const char *str)
-{
- char *c;
-
- c = (char *)str;
- while(isspace(*c))
- {
- c++;
- }
-
- return c;
-}
-
-/**
- * \fn static char *DupStr(const char *src)
- *
- * \brief This function returns a copy of the string passed as a parameter.
- *
- * \param str A pointer to the string being being copied.
- *
- * \effects Memory is dynamically allocated to hold a duplicate of the
- * input string.
- *
- * \returns A copy of str in malloced memory is returned on success. NULL
- * is returned on failure.
- *
- * This function returns a copy of the string passed as a parameter. The
- * memory for the copy is allocated by malloc() and must be freed by the caller.
- */
-static char *DupStr(const char *src)
-{
- char *dest;
-
- if (NULL == src)
- {
- return NULL;
- }
-
- dest = (char *)malloc(strlen(src) + 1);
-
- if (NULL != dest)
- {
- strcpy(dest, src);
- }
-
- return dest;
-}
-
-/**
- * \fn static char *GetLine(FILE *fp)
- *
- * \brief This function returns a NULL terminated array of char containing the
- * next line in the file passed as an argument.
- *
- * \param fp A pointer to the file being read.
- *
- * \effects One line is read from fp and copied into a dynamically allocated
- * string.
- *
- * \returns A NULL terminated array of char containing the next line in fp
- * is retured. The array must be free by the caller. NULL is returned at end
- * of file.
- *
- * This function returns a NULL terminated array of char containing the next
- * line in the file passed as an argument. The memory for the string returned
- * is allocated by malloc() and must be freed by the caller.
- */
-static char *GetLine(FILE *fp)
-{
- char *line; /* string to read line into */
- char *next; /* where to write the next characters into */
- const size_t chunkSize = 32;
- size_t lineSize;
-
- if ((NULL == fp) || feof(fp))
- {
- return NULL;
- }
-
- lineSize = chunkSize;
- line = (char *)malloc(lineSize * sizeof(char));
-
- if (NULL == line)
- {
- /* allocation failed */
- return NULL;
- }
-
- line[0] = '\0';
- next = line;
-
- while (NULL != fgets(next, lineSize - strlen(line), fp))
- {
- if ('\n' == line[strlen(line) - 1])
- {
- /* we got to the EOL strip off the trailing '\n' and exit */
- line[strlen(line) - 1] = '\0';
- break;
- }
- else
- {
- /* there's still more on this line */
- lineSize += chunkSize;
- line = (char *)realloc(line, lineSize);
-
- if (NULL == line)
- {
- return NULL;
- }
-
- next = line + strlen(line);
- }
- }
-
- return line;
-}
-
-/**@}*/
diff --git a/src/ezini.h b/src/ezini.h
deleted file mode 100644
index e563c7c..0000000
--- a/src/ezini.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * \brief INI File handling library header
- * \file ezini.h
- * \author Michael Dipperstein (mdipperstein@gmail.com)
- * \date November 22, 2015
- *
- * This file implements a set of library functions that maybe be used
- * to create, update, and/or parse INI files.
- *
- * \copyright Copyright (C) 2015, 2019 by Michael Dipperstein
- * (mdipperstein@gmail.com)
- *
- * \par
- * This file is part of the ezini library.
- *
- * \license The ezini library is free software; you can redistribute it
- * and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * \par
- * The ezini library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- *
- * \par
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- *
- */
-#ifndef __EZINI_H
-#define __EZINI_H
-
-/**
- * \mainpage EZIni - INI File handling library
- *
- * These pages provide documentation for EZIni, an INI File handling library.
- *
- * \copyright Copyright (C) 2015, 2019 by Michael Dipperstein
- * (mdipperstein@gmail.com)
- *
- * \license
- * The ezini library is free software; you can redistribute it
- * and/or modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * \par
- * The ezini library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- * General Public License for more details.
- *
- * \par
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- *
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/***************************************************************************
-* TYPE DEFINITIONS
-***************************************************************************/
-
-/**
- * \struct ini_entry_t
- * \brief A structure containing the section, key, and value of INI.
- * file entry
- */
-typedef struct
-{
- char *section; /*!< pointer to a NULL terminated string containing the
- section name */
- char *key; /*!< pointer to a a NULL terminated string containing
- the key name */
- char *value; /*!< pointer to a NULL terminated string with entry
- value. Use ASCII strings to represent numbers */
-} ini_entry_t;
-
-/**
- * \typedef ini_entry_list_t
- * \brief A shortcut for forward referenced struct ini_section_list_t*
- */
-typedef struct ini_section_list_t* ini_entry_list_t;
-
-/***************************************************************************
-* PROTOTYPES
-***************************************************************************/
-
-/* add (section, key, value) to a list of INI entries */
-int AddEntryToList(ini_entry_list_t *list, const char *section,
- const char *key, const char *value);
-
-/* free all of the entries in an entry list */
-void FreeList(ini_entry_list_t list);
-
-/* create/add entries to an INI file from a sorted entry list */
-int MakeINIFile(const char *iniFile, const ini_entry_list_t list);
-int AddEntryToFile(const char *iniFile, const ini_entry_list_t list);
-
-/* remove a single entry from an INI file */
-int DeleteEntryFromFile(const char *iniFile, const char *section,
- const char *key);
-
-/***************************************************************************
-* get the next entry in INI file.
-* returns: 1 if an entry is found
-* 0 if there are no more entries
-* -1 on error
-***************************************************************************/
-int GetEntryFromFile(FILE *iniFile, ini_entry_t *entry);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ndef __EZINI_H */
diff --git a/src/image.c b/src/image.c
index 4295ab1..6180631 100644
--- a/src/image.c
+++ b/src/image.c
@@ -2,26 +2,9 @@
#include
#include
#include
-#include
#include "draw.h"
-// Used for MagickWand
-#define ThrowWandException(wand) \
-{ \
- char \
- *description; \
- \
- ExceptionType \
- severity; \
- \
- description=MagickGetException(wand,&severity); \
- (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
- description=(char *) MagickRelinquishMemory(description); \
- exit(-1); \
-}
-
-
// Draw an image at a specific point
int draw_image(cairo_t *c, char *path, double x, double y) {
@@ -42,163 +25,27 @@ int draw_image(cairo_t *c, char *path, double x, double y) {
}
image = cairo_image_surface_create_from_png(path);
- cairo_set_source_surface(c, image, x, y);
- cairo_paint(c);
-
- cairo_surface_destroy (image);
- return 0;
-}
-
-
-
-
-
-
-unsigned long get_image_width(char *path) {
- MagickBooleanType status;
- MagickWand *wand;
-
- MagickWandGenesis();
- wand = NewMagickWand();
- status = MagickReadImage(wand, path);
-
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
-
- unsigned long width = MagickGetImageWidth(wand);
-
- wand = DestroyMagickWand(wand);
- MagickWandTerminus();
- return width;
-}
-
-
-
-unsigned long get_image_height(char *path) {
- MagickBooleanType status;
- MagickWand *wand;
-
- MagickWandGenesis();
- wand = NewMagickWand();
- status = MagickReadImage(wand, path);
-
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
-
- unsigned long height = MagickGetImageHeight(wand);
-
- wand = DestroyMagickWand(wand);
- MagickWandTerminus();
- return height;
-}
+ double width = cairo_image_surface_get_width(image);
+ double height = cairo_image_surface_get_height(image);
+ double fake_width = 100;
+ double fake_height = 100;
+ double width_scale = fake_width / width;
+ double height_scale = fake_height / height;
+ cairo_scale(c, width_scale, height_scale);
-// Resize an image to a specific width and height.
-// Optionally create a new file to preserve the source image.
-int resize_image(char *path, double width, double height, bool create_new) {
- MagickBooleanType status;
- MagickWand *wand;
- MagickWandGenesis();
- wand = NewMagickWand();
- status = MagickReadImage(wand, path);
-
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
-
- MagickResetIterator(wand);
-
- MagickResizeImage(wand, width, height, LanczosFilter, 1.0);
-
- if (create_new == true) {
- char new_path[30];
- snprintf(new_path, sizeof(new_path), "%s.tmp", path);
- status = MagickWriteImages(wand, new_path, MagickTrue);
- } else {
- status = MagickWriteImages(wand, path, MagickTrue);
- }
-
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
- wand = DestroyMagickWand(wand);
- MagickWandTerminus();
- return 0;
-}
-
-
-// Create a cropped version of an image to a certain dimensions and position.
-// Optionally create a new file to preserve the source image.
-int crop_image(char *path, double width, double height, double x, double y, bool create_new) {
- MagickBooleanType status;
- MagickWand *wand;
-
- MagickWandGenesis();
- wand = NewMagickWand();
- status = MagickReadImage(wand, path);
-
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
-
- MagickResetIterator(wand);
-
- MagickCropImage(wand, width, height, x, y);
-
- if (create_new == true) {
- char new_path[30];
- snprintf(new_path, sizeof(new_path), "%s.tmp", path);
- status = MagickWriteImages(wand, new_path, MagickTrue);
- } else {
- status = MagickWriteImages(wand, path, MagickTrue);
- }
+ cairo_set_source_surface(c, image, x, y);
+ cairo_paint(c);
- if (status == MagickFalse) {
- ThrowWandException(wand);
- }
- wand = DestroyMagickWand(wand);
- MagickWandTerminus();
+ cairo_surface_destroy (image);
return 0;
}
-int prepare_month_art(char *path, struct dimensions *d) {
- if (!d->header_width || !d->header_height) {
- printf("Error: header_width and header_height unknown.\n");
- return 1;
- }
-
- double desired_ratio = d->header_width / d->header_height;
-
- unsigned long width = get_image_width(path);
- unsigned long height = get_image_height(path);
- //double original_ratio = width / height;
-
-
- // Landscape
- if (desired_ratio > 1.0) {
- }
-
- // Portrait
- if (desired_ratio < 1.0) {
- }
-
-
-
- printf("%lu x %lu\n", width, height);
-
-
- return 0;
-
-}
-
-
// Draw month art
diff --git a/src/image.h b/src/image.h
index 117efaa..edfdec3 100644
--- a/src/image.h
+++ b/src/image.h
@@ -1,13 +1,3 @@
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 resize_image(char *path, double width, double height, bool create_new);
-
-int crop_image(char *path, double width, double height, double x, double y, bool create_new);
-
-unsigned long get_image_width(char *path);
-
-unsigned long get_image_height(char *path);
-
-int prepare_month_art(char *path, struct dimensions *d);
--
cgit v1.2.3