summaryrefslogtreecommitdiff
path: root/src/main/print-papers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/print-papers.c')
-rw-r--r--src/main/print-papers.c308
1 files changed, 202 insertions, 106 deletions
diff --git a/src/main/print-papers.c b/src/main/print-papers.c
index b5fb1e7..c457295 100644
--- a/src/main/print-papers.c
+++ b/src/main/print-papers.c
@@ -16,8 +16,7 @@
* for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
@@ -37,109 +36,129 @@
#endif
#include <string.h>
#include <stdlib.h>
+#include <sys/param.h>
-static stp_list_t *paper_list = NULL;
+typedef struct
+{
+ char *name;
+ stp_papersize_list_t *list;
+} papersize_list_impl_t;
+
+static stp_list_t *list_of_papersize_lists = NULL;
static void
-stpi_paper_freefunc(void *item)
+papersize_list_impl_freefunc(void *item)
+{
+ papersize_list_impl_t *papersize_list = (papersize_list_impl_t *) item;
+ stp_list_destroy(papersize_list->list);
+ STP_SAFE_FREE(papersize_list->name);
+ STP_SAFE_FREE(papersize_list);
+}
+
+static const char *
+papersize_list_impl_namefunc(const void *item)
+{
+ return ((const papersize_list_impl_t *) item)->name;
+}
+
+static const char *
+papersize_list_impl_long_namefunc(const void *item)
+{
+ return ((const papersize_list_impl_t *) item)->name;
+}
+
+static void
+check_list_of_papersize_lists(void)
+{
+ if (! list_of_papersize_lists)
+ {
+ stp_deprintf(STP_DBG_PAPER, "Initializing...\n");
+ list_of_papersize_lists = stp_list_create();
+ stp_list_set_freefunc(list_of_papersize_lists, papersize_list_impl_freefunc);
+ stp_list_set_namefunc(list_of_papersize_lists, papersize_list_impl_namefunc);
+ stp_list_set_long_namefunc(list_of_papersize_lists, papersize_list_impl_long_namefunc);
+ }
+}
+
+static void
+stpi_papersize_freefunc(void *item)
{
stp_papersize_t *paper = (stp_papersize_t *) (item);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
STP_SAFE_FREE(paper->name);
STP_SAFE_FREE(paper->text);
STP_SAFE_FREE(paper->comment);
+#pragma GCC diagnostic pop
STP_SAFE_FREE(paper);
}
static const char *
-stpi_paper_namefunc(const void *item)
+stpi_papersize_namefunc(const void *item)
{
const stp_papersize_t *paper = (const stp_papersize_t *) (item);
return paper->name;
}
static const char *
-stpi_paper_long_namefunc(const void *item)
+stpi_papersize_long_namefunc(const void *item)
{
const stp_papersize_t *paper = (const stp_papersize_t *) (item);
return paper->text;
}
-static int
-stpi_paper_list_init(void)
-{
- if (paper_list)
- stp_list_destroy(paper_list);
- paper_list = stp_list_create();
- stp_list_set_freefunc(paper_list, stpi_paper_freefunc);
- stp_list_set_namefunc(paper_list, stpi_paper_namefunc);
- stp_list_set_long_namefunc(paper_list, stpi_paper_long_namefunc);
- /* stp_list_set_sortfunc(stpi_paper_sortfunc); */
-
- return 0;
-}
-
-static inline void
-check_paperlist(void)
+stp_papersize_list_t *
+stpi_create_papersize_list(void)
{
- if (paper_list == NULL)
- {
- stp_xml_parse_file_named("papers.xml");
- if (paper_list == NULL)
- {
- stp_erprintf("No papers found: is STP_MODULE_PATH correct?\n");
- stpi_paper_list_init();
- }
- }
+ stp_list_t *papersize_list = stp_list_create();
+ stp_list_set_freefunc(papersize_list, stpi_papersize_freefunc);
+ stp_list_set_namefunc(papersize_list, stpi_papersize_namefunc);
+ stp_list_set_long_namefunc(papersize_list, stpi_papersize_long_namefunc);
+ return (stp_papersize_list_t *) papersize_list;
}
-static int
-stpi_paper_create(stp_papersize_t *p)
+int
+stpi_papersize_create(stp_papersize_list_t *list, stp_papersize_t *p)
{
- stp_list_item_t *paper_item;
-
- if (paper_list == NULL)
- {
- stpi_paper_list_init();
- stp_deprintf(STP_DBG_PAPER,
- "stpi_paper_create(): initialising paper_list...\n");
- }
-
- /* Check the paper does not already exist */
- paper_item = stp_list_get_start(paper_list);
- while (paper_item)
+ stp_list_item_t *papersize_item;
+
+ /*
+ * Check the paper does not already exist
+ * Not the most efficient way of doing it, but the number of papers
+ * is not large enough to be a significant bottleneck.
+ */
+ papersize_item = stp_list_get_start(list);
+ while (papersize_item)
{
const stp_papersize_t *ep =
- (const stp_papersize_t *) stp_list_item_get_data(paper_item);
+ (const stp_papersize_t *) stp_list_item_get_data(papersize_item);
if (ep && !strcmp(p->name, ep->name))
{
- stp_erprintf("Duplicate paper size `%s'\n",
- p->name);
- stpi_paper_freefunc(p);
+ stp_erprintf("Duplicate paper size `%s'\n", p->name);
+ stpi_papersize_freefunc(p);
return 1;
}
- paper_item = stp_list_item_next(paper_item);
+ papersize_item = stp_list_item_next(papersize_item);
}
/* Add paper to list */
- stp_list_item_create(paper_list, NULL, (void *) p);
+ stp_list_item_create(list, NULL, (void *) p);
return 0;
}
int
-stp_known_papersizes(void)
+stpi_papersize_count(const stp_papersize_list_t *paper_size_list)
{
- check_paperlist();
- return stp_list_get_length(paper_list);
+ return stp_list_get_length(paper_size_list);
}
const stp_papersize_t *
-stp_get_papersize_by_name(const char *name)
+stpi_get_papersize_by_name(const stp_papersize_list_t *list, const char *name)
{
stp_list_item_t *paper;
- check_paperlist();
- paper = stp_list_get_item_by_name(paper_list, name);
+ paper = stp_list_get_item_by_name(list, name);
if (!paper)
return NULL;
else
@@ -147,37 +166,52 @@ stp_get_papersize_by_name(const char *name)
}
const stp_papersize_t *
-stp_get_papersize_by_index(int idx)
+stpi_get_listed_papersize(const char *name, const char *papersize_list)
{
- stp_list_item_t *paper;
-
- check_paperlist();
- paper = stp_list_get_item_by_index(paper_list, idx);
- if (!paper)
- return NULL;
+ const stp_papersize_list_t *list =
+ stpi_get_papersize_list_named(papersize_list, "");
+ if (list)
+ return stpi_get_papersize_by_name(list, name);
else
- return (const stp_papersize_t *) stp_list_item_get_data(paper);
+ return NULL;
+}
+
+const stp_papersize_t *
+stpi_standard_describe_papersize(const stp_vars_t *v, const char *name)
+{
+ STPI_ASSERT(v, NULL);
+ return stpi_get_listed_papersize(name, "standard");
+}
+
+const stp_papersize_t *
+stp_describe_papersize(const stp_vars_t *v, const char *name)
+{
+ return stpi_printer_describe_papersize(v, name);
}
static int
-paper_size_mismatch(stp_dimension_t l, stp_dimension_t w, const stp_papersize_t *val)
+papersize_size_mismatch(stp_dimension_t l, stp_dimension_t w,
+ const stp_papersize_t *val)
{
- stp_dimension_t hdiff = abs(l - (stp_dimension_t) val->height);
- stp_dimension_t vdiff = abs(w - (stp_dimension_t) val->width);
+ stp_dimension_t hdiff = STP_DABS(l - (stp_dimension_t) val->height);
+ stp_dimension_t vdiff = STP_DABS(w - (stp_dimension_t) val->width);
return hdiff > vdiff ? hdiff : vdiff;
}
-const stp_papersize_t *
-stp_get_papersize_by_size(stp_dimension_t l, stp_dimension_t w)
+static const stp_papersize_t *
+get_papersize_by_size_internal(const stp_papersize_list_t *list,
+ stp_dimension_t l, stp_dimension_t w,
+ int exact)
{
int score = INT_MAX;
const stp_papersize_t *ref = NULL;
const stp_papersize_t *val = NULL;
- int i;
- int sizes = stp_known_papersizes();
- for (i = 0; i < sizes; i++)
+ const stp_papersize_list_item_t *ptli =
+ stpi_papersize_list_get_start(list);
+ STPI_ASSERT(list, NULL);
+ while (ptli)
{
- val = stp_get_papersize_by_index(i);
+ val = stpi_paperlist_item_get_data(ptli);
if (val->width == w && val->height == l)
{
@@ -187,40 +221,32 @@ stp_get_papersize_by_size(stp_dimension_t l, stp_dimension_t w)
else
ref = val;
}
- else
+ else if (!exact)
{
- int myscore = paper_size_mismatch(l, w, val);
+ int myscore = papersize_size_mismatch(l, w, val);
if (myscore < score && myscore < 5)
{
ref = val;
score = myscore;
}
}
+ ptli = stpi_paperlist_item_next(ptli);
}
return ref;
}
const stp_papersize_t *
-stp_get_papersize_by_size_exact(stp_dimension_t l, stp_dimension_t w)
+stpi_get_papersize_by_size(const stp_papersize_list_t *list,
+ stp_dimension_t l, stp_dimension_t w)
{
- const stp_papersize_t *ref = NULL;
- const stp_papersize_t *val = NULL;
- int i;
- int sizes = stp_known_papersizes();
- for (i = 0; i < sizes; i++)
- {
- val = stp_get_papersize_by_index(i);
+ return get_papersize_by_size_internal(list, l, w, 0);
+}
- if (val->width == w && val->height == l)
- {
- if (val->top == 0 && val->left == 0 &&
- val->bottom == 0 && val->right == 0)
- return val;
- else
- ref = val;
- }
- }
- return ref;
+const stp_papersize_t *
+stpi_get_papersize_by_size_exact(const stp_papersize_list_t *list,
+ stp_dimension_t l, stp_dimension_t w)
+{
+ return get_papersize_by_size_internal(list, l, w, 1);
}
void
@@ -238,7 +264,7 @@ stp_default_media_size(const stp_vars_t *v, /* I */
const char *page_size = stp_get_string_parameter(v, "PageSize");
const stp_papersize_t *papersize = NULL;
if (page_size)
- papersize = stp_get_papersize_by_name(page_size);
+ papersize = stp_describe_papersize(v, page_size);
if (!papersize)
{
*width = 1;
@@ -262,8 +288,8 @@ stp_default_media_size(const stp_vars_t *v, /* I */
static stp_papersize_t *
stp_xml_process_paper(stp_mxml_node_t *paper) /* The paper node */
{
- stp_mxml_node_t *prop; /* Temporary node pointer */
- const char *stmp; /* Temporary string */
+ stp_mxml_node_t *prop; /* Temporary node pointer */
+ const char *stmp; /* Temporary string */
/* props[] (unused) is the correct tag sequence */
/* const char *props[] =
{
@@ -385,8 +411,6 @@ stp_xml_process_paper(stp_mxml_node_t *paper) /* The paper node */
{
if (!strcmp(stmp, "envelope"))
outpaper->paper_size_type = PAPERSIZE_TYPE_ENVELOPE;
- else if (!strcmp(stmp, "special"))
- outpaper->paper_size_type = PAPERSIZE_TYPE_SPECIAL;
else
outpaper->paper_size_type = PAPERSIZE_TYPE_STANDARD;
}
@@ -405,7 +429,8 @@ stp_xml_process_paper(stp_mxml_node_t *paper) /* The paper node */
* Parse the <paperdef> node.
*/
static int
-stp_xml_process_paperdef(stp_mxml_node_t *paperdef, const char *file) /* The paperdef node */
+stp_xml_process_papersize_def(stp_mxml_node_t *paperdef, const char *file,
+ stp_papersize_list_t *papersize_list)
{
stp_mxml_node_t *paper; /* paper node pointer */
stp_papersize_t *outpaper; /* Generated paper */
@@ -415,12 +440,12 @@ stp_xml_process_paperdef(stp_mxml_node_t *paperdef, const char *file) /* The pap
{
if (paper->type == STP_MXML_ELEMENT)
{
- const char *paper_name = paper->value.element.name;
- if (!strcmp(paper_name, "paper"))
+ const char *papersize_name = paper->value.element.name;
+ if (!strcmp(papersize_name, "paper"))
{
outpaper = stp_xml_process_paper(paper);
if (outpaper)
- stpi_paper_create(outpaper);
+ stpi_papersize_create(papersize_list, outpaper);
}
}
paper = paper->next;
@@ -428,8 +453,79 @@ stp_xml_process_paperdef(stp_mxml_node_t *paperdef, const char *file) /* The pap
return 1;
}
-void
-stpi_init_paper(void)
+const stp_papersize_list_t *
+stpi_get_papersize_list_named(const char *name, const char *file)
+{
+ stp_list_item_t *item;
+ papersize_list_impl_t *impl;
+
+ check_list_of_papersize_lists();
+ item = stp_list_get_item_by_name(list_of_papersize_lists, name);
+ if (item)
+ {
+ impl = (papersize_list_impl_t *) stp_list_item_get_data(item);
+ }
+ else
+ {
+ char buf[MAXPATHLEN+1];
+ stp_deprintf(STP_DBG_PAPER, "Loading paper list %s from %s\n",
+ name, file ? file : "(null)");
+ if (! file)
+ return NULL;
+ else if (!strcmp(file, ""))
+ (void) snprintf(buf, MAXPATHLEN, "papers/%s.xml", name);
+ else
+ strncpy(buf, file, MAXPATHLEN);
+ stp_mxml_node_t *node =
+ stp_xml_parse_file_from_path_safe(buf, "paperdef", NULL);
+ const char *stmp = stp_mxmlElementGetAttr(node, "name");
+ STPI_ASSERT(stmp && !strcmp(name, stmp), NULL);
+ impl = stp_malloc(sizeof(papersize_list_impl_t));
+ impl->name = stp_strdup(name);
+ impl->list = stpi_create_papersize_list();
+ stp_deprintf(STP_DBG_PAPER, " Loading %s\n", stmp);
+ stp_list_item_create(list_of_papersize_lists, NULL, impl);
+ stp_xml_process_papersize_def(node, buf, impl->list);
+ }
+ return impl->list;
+}
+
+stp_papersize_list_t *
+stpi_find_papersize_list_named(const char *name)
+{
+ stp_list_item_t *item;
+
+ check_list_of_papersize_lists();
+ item = stp_list_get_item_by_name(list_of_papersize_lists, name);
+ if (item)
+ {
+ papersize_list_impl_t *impl =
+ (papersize_list_impl_t *) stp_list_item_get_data(item);
+ if (impl)
+ return impl->list;
+ }
+ return NULL;
+}
+
+stp_papersize_list_t *
+stpi_new_papersize_list(const char *name)
+{
+ stp_list_item_t *item;
+ papersize_list_impl_t *impl;
+
+ check_list_of_papersize_lists();
+ item = stp_list_get_item_by_name(list_of_papersize_lists, name);
+ if (item)
+ return NULL;
+ impl = stp_malloc(sizeof(papersize_list_impl_t));
+ impl->name = stp_strdup(name);
+ impl->list = stpi_create_papersize_list();
+ stp_list_item_create(list_of_papersize_lists, NULL, impl);
+ return impl->list;
+}
+
+const stp_papersize_list_t *
+stpi_get_standard_papersize_list(void)
{
- stp_register_xml_parser("paperdef", stp_xml_process_paperdef);
+ return stpi_get_papersize_list_named("standard", "");
}