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.c,v 1.34 2004/05/07 19:20:33 rleigh 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 }

Generated on Wed Aug 25 07:56:14 2004 for libgimpprint API Reference by doxygen 1.3.6