libgimpprint API Reference: src/main/print-papers.c Source File

Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

# src/main/print-papers.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: print-papers_8c-source.html,v 1.1.1.2 2004/12/22 23:49:09 jlovell Exp $"
    00003  *
    00004  *   Print plug-in driver utility functions for the GIMP.
    00005  *
    00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
    00007  *      Robert Krawitz (rlk@alum.mit.edu)
    00008  *
    00009  *   This program is free software; you can redistribute it and/or modify it
    00010  *   under the terms of the GNU General Public License as published by the Free
    00011  *   Software Foundation; either version 2 of the License, or (at your option)
    00012  *   any later version.
    00013  *
    00014  *   This program is distributed in the hope that it will be useful, but
    00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00017  *   for more details.
    00018  *
    00019  *   You should have received a copy of the GNU General Public License
    00020  *   along with this program; if not, write to the Free Software
    00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00022  */
    00023
    00024 /*
    00025  * This file must include only standard C header files.  The core code must
    00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
    00027  */
    00028
    00029 #ifdef HAVE_CONFIG_H
    00030 #include <config.h>
    00031 #endif
    00032 #include <gimp-print/gimp-print.h>
    00033 #include "gimp-print-internal.h"
    00034 #include <gimp-print/gimp-print-intl-internal.h>
    00035 #include <math.h>
    00036 #ifdef HAVE_LIMITS_H
    00037 #include <limits.h>
    00038 #endif
    00039 #include <string.h>
    00040 #include <stdlib.h>
    00041
    00042 static stp_list_t *paper_list = NULL;
    00043
    00044 static void
    00045 stpi_paper_freefunc(void *item)
    00046 {
    00047   stp_papersize_t *paper = (stp_papersize_t *) (item);
    00048   STP_SAFE_FREE(paper->name);
    00049   STP_SAFE_FREE(paper->text);
    00050   STP_SAFE_FREE(paper->comment);
    00051   STP_SAFE_FREE(paper);
    00052 }
    00053
    00054 static const char *
    00055 stpi_paper_namefunc(const void *item)
    00056 {
    00057   const stp_papersize_t *paper = (const stp_papersize_t *) (item);
    00058   return paper->name;
    00059 }
    00060
    00061 static const char *
    00062 stpi_paper_long_namefunc(const void *item)
    00063 {
    00064   const stp_papersize_t *paper = (const stp_papersize_t *) (item);
    00065   return paper->text;
    00066 }
    00067
    00068 static int
    00069 stpi_paper_list_init(void)
    00070 {
    00071   if (paper_list)
    00072     stp_list_destroy(paper_list);
    00073   paper_list = stp_list_create();
    00074   stp_list_set_freefunc(paper_list, stpi_paper_freefunc);
    00075   stp_list_set_namefunc(paper_list, stpi_paper_namefunc);
    00076   stp_list_set_long_namefunc(paper_list, stpi_paper_long_namefunc);
    00077   /* stp_list_set_sortfunc(stpi_paper_sortfunc); */
    00078
    00079   return 0;
    00080 }
    00081
    00082 static inline void
    00083 check_paperlist(void)
    00084 {
    00085   if (paper_list == NULL)
    00086     {
    00087       stp_xml_parse_file_named("papers.xml");
    00088       if (paper_list == NULL)
    00089         {
    00090           stp_erprintf("No papers found: is STP_MODULE_PATH correct?\n");
    00091           stpi_paper_list_init();
    00092         }
    00093     }
    00094 }
    00095
    00096 static int
    00097 stpi_paper_create(stp_papersize_t *p)
    00098 {
    00099   stp_list_item_t *paper_item;
    00100
    00101   if (paper_list == NULL)
    00102     {
    00103       stpi_paper_list_init();
    00104       stp_deprintf(STP_DBG_PAPER,
    00105                    "stpi_paper_create(): initialising paper_list...\n");
    00106     }
    00107
    00108   /* Check the paper does not already exist */
    00109   paper_item = stp_list_get_start(paper_list);
    00110   while (paper_item)
    00111     {
    00112       const stp_papersize_t *ep =
    00113         (const stp_papersize_t *) stp_list_item_get_data(paper_item);
    00114       if (ep && !strcmp(p->name, ep->name))
    00115         {
    00116           stpi_paper_freefunc(p);
    00117           return 1;
    00118         }
    00119       paper_item = stp_list_item_next(paper_item);
    00120     }
    00121
    00122   /* Add paper to list */
    00123   stp_list_item_create(paper_list, NULL, (void *) p);
    00124
    00125   return 0;
    00126 }
    00127
    00128 static int
    00129 stpi_paper_destroy(stp_papersize_t *p)
    00130 {
    00131   stp_list_item_t *paper_item;
    00132   check_paperlist();
    00133
    00134   /* Check if paper exists */
    00135   paper_item = stp_list_get_start(paper_list);
    00136   while (paper_item)
    00137     {
    00138       const stp_papersize_t *ep = (const stp_papersize_t *)
    00139         stp_list_item_get_data(paper_item);
    00140       if (ep && !strcmp(p->name, ep->name))
    00141         {
    00142           stp_list_item_destroy (paper_list, paper_item);
    00143           return 0;
    00144         }
    00145       paper_item = stp_list_item_next(paper_item);
    00146     }
    00147   /* Paper did not exist */
    00148   return 1;
    00149 }
    00150
    00151
    00152 int
    00153 stp_known_papersizes(void)
    00154 {
    00155   check_paperlist();
    00156   return stp_list_get_length(paper_list);
    00157 }
    00158
    00159 const stp_papersize_t *
    00160 stp_get_papersize_by_name(const char *name)
    00161 {
    00162   stp_list_item_t *paper;
    00163
    00164   check_paperlist();
    00165   paper = stp_list_get_item_by_name(paper_list, name);
    00166   if (!paper)
    00167     return NULL;
    00168   else
    00169     return (const stp_papersize_t *) stp_list_item_get_data(paper);
    00170 }
    00171
    00172 const stp_papersize_t *
    00173 stp_get_papersize_by_index(int idx)
    00174 {
    00175   stp_list_item_t *paper;
    00176
    00177   check_paperlist();
    00178   paper = stp_list_get_item_by_index(paper_list, idx);
    00179   if (!paper)
    00180     return NULL;
    00181   else
    00182     return (const stp_papersize_t *) stp_list_item_get_data(paper);
    00183 }
    00184
    00185 static int
    00186 paper_size_mismatch(int l, int w, const stp_papersize_t *val)
    00187 {
    00188   int hdiff = abs(l - (int) val->height);
    00189   int vdiff = abs(w - (int) val->width);
    00190   return hdiff + vdiff;
    00191 }
    00192
    00193 const stp_papersize_t *
    00194 stp_get_papersize_by_size(int l, int w)
    00195 {
    00196   int score = INT_MAX;
    00197   const stp_papersize_t *ref = NULL;
    00198   const stp_papersize_t *val = NULL;
    00199   int i;
    00200   int sizes = stp_known_papersizes();
    00201   for (i = 0; i < sizes; i++)
    00202     {
    00203       val = stp_get_papersize_by_index(i);
    00204
    00205       if (val->width == w && val->height == l)
    00206         return val;
    00207       else
    00208         {
    00209           int myscore = paper_size_mismatch(l, w, val);
    00210           if (myscore < score && myscore < 20)
    00211             {
    00212               ref = val;
    00213               score = myscore;
    00214             }
    00215         }
    00216     }
    00217   return ref;
    00218 }
    00219
    00220 void
    00221 stp_default_media_size(const stp_vars_t *v,     /* I */
    00222                        int  *width,             /* O - Width in points */
    00223                        int  *height)            /* O - Height in points */
    00224 {
    00225   if (stp_get_page_width(v) > 0 && stp_get_page_height(v) > 0)
    00226     {
    00227       *width = stp_get_page_width(v);
    00228       *height = stp_get_page_height(v);
    00229     }
    00230   else
    00231     {
    00232       const char *page_size = stp_get_string_parameter(v, "PageSize");
    00233       const stp_papersize_t *papersize = NULL;
    00234       if (page_size)
    00235         papersize = stp_get_papersize_by_name(page_size);
    00236       if (!papersize)
    00237         {
    00238           *width = 1;
    00239           *height = 1;
    00240         }
    00241       else
    00242         {
    00243           *width = papersize->width;
    00244           *height = papersize->height;
    00245         }
    00246       if (*width == 0)
    00247         *width = 612;
    00248       if (*height == 0)
    00249         *height = 792;
    00250     }
    00251 }
    00252
    00253 /*
    00254  * Process the <paper> node.
    00255  */
    00256 static stp_papersize_t *
    00257 stp_xml_process_paper(stp_mxml_node_t *paper) /* The paper node */
    00258 {
    00259   stp_mxml_node_t *prop;                              /* Temporary node pointer */
    00260   const char *stmp;                                /* Temporary string */
    00261   /* props[] (unused) is the correct tag sequence */
    00262   /*  const char *props[] =
    00263     {
    00264       "name",
    00265       "description",
    00266       "width",
    00267       "height",
    00268       "left",
    00269       "right",
    00270       "bottom",
    00271       "top",
    00272       "unit",
    00273       NULL
    00274       };*/
    00275   stp_papersize_t *outpaper;   /* Generated paper */
    00276   int
    00277     id = 0,                     /* Check id is present */
    00278     name = 0,                   /* Check name is present */
    00279     height = 0,                 /* Check height is present */
    00280     width = 0,                  /* Check width is present */
    00281     left = 0,                   /* Check left is present */
    00282     right = 0,                  /* Check right is present */
    00283     bottom = 0,                 /* Check bottom is present */
    00284     top = 0,                    /* Check top is present */
    00285     unit = 0;                   /* Check unit is present */
    00286
    00287   if (stp_get_debug_level() & STP_DBG_XML)
    00288     {
    00289       stmp = stp_mxmlElementGetAttr(paper, (const char*) "name");
    00290       stp_erprintf("stp_xml_process_paper: name: %s\n", stmp);
    00291     }
    00292
    00293   outpaper = stp_zalloc(sizeof(stp_papersize_t));
    00294   if (!outpaper)
    00295     return NULL;
    00296
    00297   outpaper->name = stp_strdup(stp_mxmlElementGetAttr(paper, "name"));
    00298
    00299   outpaper->top = 0;
    00300   outpaper->left = 0;
    00301   outpaper->bottom = 0;
    00302   outpaper->right = 0;
    00303   if (outpaper->name)
    00304     id = 1;
    00305
    00306   prop = paper->child;
    00307   while(prop)
    00308     {
    00309       if (prop->type == STP_MXML_ELEMENT)
    00310         {
    00311           const char *prop_name = prop->value.element.name;
    00312
    00313           if (!strcmp(prop_name, "description"))
    00314             {
    00315               outpaper->text = stp_strdup(stp_mxmlElementGetAttr(prop, "value"));
    00316               name = 1;
    00317             }
    00318           if (!strcmp(prop_name, "comment"))
    00319             outpaper->comment = stp_strdup(stp_mxmlElementGetAttr(prop, "value"));
    00320           if (!strcmp(prop_name, "width"))
    00321             {
    00322               stmp = stp_mxmlElementGetAttr(prop, "value");
    00323               if (stmp)
    00324                 {
    00325                   outpaper->width = stp_xmlstrtoul(stmp);
    00326                   width = 1;
    00327                 }
    00328             }
    00329           if (!strcmp(prop_name, "height"))
    00330             {
    00331               stmp = stp_mxmlElementGetAttr(prop, "value");
    00332               if (stmp)
    00333                 {
    00334                   outpaper->height = stp_xmlstrtoul(stmp);
    00335                   height = 1;
    00336                 }
    00337             }
    00338           if (!strcmp(prop_name, "left"))
    00339             {
    00340               stmp = stp_mxmlElementGetAttr(prop, "value");
    00341               outpaper->left = stp_xmlstrtoul(stmp);
    00342               left = 1;
    00343             }
    00344           if (!strcmp(prop_name, "right"))
    00345             {
    00346               stmp = stp_mxmlElementGetAttr(prop, "value");
    00347               outpaper->right = stp_xmlstrtoul(stmp);
    00348               right = 1;
    00349             }
    00350           if (!strcmp(prop_name, "bottom"))
    00351             {
    00352               stmp = stp_mxmlElementGetAttr(prop, "value");
    00353               outpaper->bottom = stp_xmlstrtoul(stmp);
    00354               bottom = 1;
    00355             }
    00356           if (!strcmp(prop_name, "top"))
    00357             {
    00358               stmp = stp_mxmlElementGetAttr(prop, "value");
    00359               outpaper->top = stp_xmlstrtoul(stmp);
    00360               top = 1;
    00361             }
    00362           if (!strcmp(prop_name, "unit"))
    00363             {
    00364               stmp = stp_mxmlElementGetAttr(prop, "value");
    00365               if (stmp)
    00366                 {
    00367                   if (!strcmp(stmp, "english"))
    00368                     outpaper->paper_unit = PAPERSIZE_ENGLISH_STANDARD;
    00369                   else if (!strcmp(stmp, "english-extended"))
    00370                     outpaper->paper_unit = PAPERSIZE_ENGLISH_EXTENDED;
    00371                   else if (!strcmp(stmp, "metric"))
    00372                     outpaper->paper_unit = PAPERSIZE_METRIC_STANDARD;
    00373                   else if (!strcmp(stmp, "metric-extended"))
    00374                     outpaper->paper_unit = PAPERSIZE_METRIC_EXTENDED;
    00375                   /* Default unit */
    00376                   else
    00377                     outpaper->paper_unit = PAPERSIZE_METRIC_EXTENDED;
    00378                   unit = 1;
    00379                 }
    00380             }
    00381         }
    00382       prop = prop->next;
    00383     }
    00384   if (id && name && width && height && unit) /* Margins are optional */
    00385     return outpaper;
    00386   stp_free(outpaper);
    00387   outpaper = NULL;
    00388   return NULL;
    00389 }
    00390
    00391 /*
    00392  * Parse the <paperdef> node.
    00393  */
    00394 static int
    00395 stp_xml_process_paperdef(stp_mxml_node_t *paperdef, const char *file) /* The paperdef node */
    00396 {
    00397   stp_mxml_node_t *paper;                           /* paper node pointer */
    00398   stp_papersize_t *outpaper;         /* Generated paper */
    00399
    00400   paper = paperdef->child;
    00401   while (paper)
    00402     {
    00403       if (paper->type == STP_MXML_ELEMENT)
    00404         {
    00405           const char *paper_name = paper->value.element.name;
    00406           if (!strcmp(paper_name, "paper"))
    00407             {
    00408               outpaper = stp_xml_process_paper(paper);
    00409               if (outpaper)
    00410                 stpi_paper_create(outpaper);
    00411             }
    00412         }
    00413       paper = paper->next;
    00414     }
    00415   return 1;
    00416 }
    00417
    00418 void
    00419 stpi_init_paper(void)
    00420 {
    00421   stp_register_xml_parser("paperdef", stp_xml_process_paperdef);
    00422 }