00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
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
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
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
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,
00222 int *width,
00223 int *height)
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
00255
00256 static stp_papersize_t *
00257 stp_xml_process_paper(stp_mxml_node_t *paper)
00258 {
00259 stp_mxml_node_t *prop;
00260 const char *stmp;
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 stp_papersize_t *outpaper;
00276 int
00277 id = 0,
00278 name = 0,
00279 height = 0,
00280 width = 0,
00281 left = 0,
00282 right = 0,
00283 bottom = 0,
00284 top = 0,
00285 unit = 0;
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
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)
00385 return outpaper;
00386 stp_free(outpaper);
00387 outpaper = NULL;
00388 return NULL;
00389 }
00390
00391
00392
00393
00394 static int
00395 stp_xml_process_paperdef(stp_mxml_node_t *paperdef, const char *file)
00396 {
00397 stp_mxml_node_t *paper;
00398 stp_papersize_t *outpaper;
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 }