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/gimp-print-intl-internal.h>
00034 #include "gimp-print-internal.h"
00035 #include <time.h>
00036 #include <string.h>
00037 #ifdef HAVE_LIMITS_H
00038 #include <limits.h>
00039 #endif
00040 #include <stdio.h>
00041
00042 #ifdef _MSC_VER
00043 #define strncasecmp(s,t,n) _strnicmp(s,t,n)
00044 #define strcasecmp(s,t) _stricmp(s,t)
00045 #endif
00046
00047
00048
00049
00050
00051 static FILE *ps_ppd = NULL;
00052 static const char *ps_ppd_file = NULL;
00053
00054
00055
00056
00057
00058
00059 static void ps_hex(const stp_vars_t *, unsigned short *, int);
00060 static void ps_ascii85(const stp_vars_t *, unsigned short *, int, int);
00061 static char *ppd_find(const char *, const char *, const char *, int *);
00062
00063 static const stp_parameter_t the_parameters[] =
00064 {
00065 {
00066 "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
00067 N_("Size of the paper being printed to"),
00068 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00069 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00070 },
00071 {
00072 "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
00073 N_("Type of media (plain paper, photo paper, etc.)"),
00074 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00075 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00076 },
00077 {
00078 "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
00079 N_("Source (input slot) of the media"),
00080 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00081 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00082 },
00083 {
00084 "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
00085 N_("Resolution and quality of the print"),
00086 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00087 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00088 },
00089 {
00090 "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
00091 N_("Type of ink in the printer"),
00092 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00093 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00094 },
00095 {
00096 "PPDFile", N_("PPDFile"), N_("Basic Printer Setup"),
00097 N_("PPD File"),
00098 STP_PARAMETER_TYPE_FILE, STP_PARAMETER_CLASS_FEATURE,
00099 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00100 },
00101 {
00102 "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
00103 N_("Printing Output Mode"),
00104 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00105 STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00106 },
00107 };
00108
00109 static const int the_parameter_count =
00110 sizeof(the_parameters) / sizeof(const stp_parameter_t);
00111
00112
00113
00114
00115
00116 static stp_parameter_list_t
00117 ps_list_parameters(const stp_vars_t *v)
00118 {
00119 stp_parameter_list_t *ret = stp_parameter_list_create();
00120 int i;
00121 for (i = 0; i < the_parameter_count; i++)
00122 stp_parameter_list_add_param(ret, &(the_parameters[i]));
00123 return ret;
00124 }
00125
00126 static void
00127 ps_parameters_internal(const stp_vars_t *v, const char *name,
00128 stp_parameter_t *description)
00129 {
00130 int i;
00131 char line[1024],
00132 lname[255],
00133 loption[255],
00134 *ltext;
00135 const char *ppd_file = stp_get_file_parameter(v, "PPDFile");
00136 description->p_type = STP_PARAMETER_TYPE_INVALID;
00137 description->deflt.str = 0;
00138
00139 if (name == NULL)
00140 return;
00141
00142 if (ppd_file != NULL && strlen(ppd_file) > 0 &&
00143 (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0))
00144 {
00145 if (ps_ppd != NULL)
00146 fclose(ps_ppd);
00147
00148 ps_ppd = fopen(ppd_file, "r");
00149
00150 if (ps_ppd == NULL)
00151 ps_ppd_file = NULL;
00152 else
00153 ps_ppd_file = ppd_file;
00154 }
00155
00156 for (i = 0; i < the_parameter_count; i++)
00157 if (strcmp(name, the_parameters[i].name) == 0)
00158 {
00159 stp_fill_parameter_settings(description, &(the_parameters[i]));
00160 break;
00161 }
00162
00163 if (strcmp(name, "PrintingMode") == 0)
00164 {
00165 description->bounds.str = stp_string_list_create();
00166 stp_string_list_add_string
00167 (description->bounds.str, "Color", _("Color"));
00168 stp_string_list_add_string
00169 (description->bounds.str, "BW", _("Black and White"));
00170 description->deflt.str =
00171 stp_string_list_param(description->bounds.str, 0)->name;
00172 return;
00173 }
00174
00175 if (ps_ppd == NULL)
00176 {
00177 if (strcmp(name, "PageSize") == 0)
00178 {
00179 int papersizes = stp_known_papersizes();
00180 description->bounds.str = stp_string_list_create();
00181 for (i = 0; i < papersizes; i++)
00182 {
00183 const stp_papersize_t *pt = stp_get_papersize_by_index(i);
00184 if (strlen(pt->name) > 0)
00185 stp_string_list_add_string
00186 (description->bounds.str, pt->name, pt->text);
00187 }
00188 description->deflt.str =
00189 stp_string_list_param(description->bounds.str, 0)->name;
00190 description->is_active = 1;
00191 }
00192 else
00193 description->is_active = 0;
00194 return;
00195 }
00196
00197 rewind(ps_ppd);
00198 description->bounds.str = stp_string_list_create();
00199
00200 while (fgets(line, sizeof(line), ps_ppd) != NULL)
00201 {
00202 if (line[0] != '*')
00203 continue;
00204
00205 if (sscanf(line, "*%s %[^:]", lname, loption) != 2)
00206 continue;
00207
00208 if (strcasecmp(lname, name) == 0)
00209 {
00210 if ((ltext = strchr(loption, '/')) != NULL)
00211 *ltext++ = '\0';
00212 else
00213 ltext = loption;
00214
00215 stp_string_list_add_string(description->bounds.str, loption, ltext);
00216 }
00217 }
00218
00219 if (stp_string_list_count(description->bounds.str) > 0)
00220 description->deflt.str =
00221 stp_string_list_param(description->bounds.str, 0)->name;
00222 else
00223 description->is_active = 0;
00224 return;
00225 }
00226
00227 static void
00228 ps_parameters(const stp_vars_t *v, const char *name,
00229 stp_parameter_t *description)
00230 {
00231 setlocale(LC_ALL, "C");
00232 ps_parameters_internal(v, name, description);
00233 setlocale(LC_ALL, "");
00234 }
00235
00236
00237
00238
00239
00240 static void
00241 ps_media_size_internal(const stp_vars_t *v,
00242 int *width,
00243 int *height)
00244 {
00245 char *dimensions;
00246 const char *pagesize = stp_get_string_parameter(v, "PageSize");
00247 const char *ppd_file_name = stp_get_file_parameter(v, "PPDFile");
00248 float fwidth, fheight;
00249 if (!pagesize)
00250 pagesize = "";
00251
00252 stp_dprintf(STP_DBG_PS, v,
00253 "ps_media_size(%d, \'%s\', \'%s\', %p, %p)\n",
00254 stp_get_model_id(v), ppd_file_name, pagesize,
00255 (void *) width, (void *) height);
00256
00257 if ((dimensions = ppd_find(ppd_file_name, "PaperDimension", pagesize, NULL))
00258 != NULL)
00259 {
00260 sscanf(dimensions, "%f%f", &fwidth, &fheight);
00261 *width = fwidth;
00262 *height = fheight;
00263 stp_dprintf(STP_DBG_PS, v, "dimensions '%s' %f %f %d %d\n",
00264 dimensions, fwidth, fheight, *width, *height);
00265 }
00266 else
00267 stp_default_media_size(v, width, height);
00268 }
00269
00270 static void
00271 ps_media_size(const stp_vars_t *v, int *width, int *height)
00272 {
00273 setlocale(LC_ALL, "C");
00274 ps_media_size_internal(v, width, height);
00275 setlocale(LC_ALL, "");
00276 }
00277
00278
00279
00280
00281
00282 static void
00283 ps_imageable_area_internal(const stp_vars_t *v,
00284 int *left,
00285 int *right,
00286 int *bottom,
00287 int *top)
00288 {
00289 char *area;
00290 float fleft,
00291 fright,
00292 fbottom,
00293 ftop;
00294 int width, height;
00295 const char *pagesize = stp_get_string_parameter(v, "PageSize");
00296 if (!pagesize)
00297 pagesize = "";
00298 ps_media_size(v, &width, &height);
00299
00300 if ((area = ppd_find(stp_get_file_parameter(v, "PPDFile"),
00301 "ImageableArea", pagesize, NULL))
00302 != NULL)
00303 {
00304 stp_dprintf(STP_DBG_PS, v, "area = \'%s\'\n", area);
00305 if (sscanf(area, "%f%f%f%f", &fleft, &fbottom, &fright, &ftop) == 4)
00306 {
00307 *left = (int)fleft;
00308 *right = (int)fright;
00309 *bottom = height - (int)fbottom;
00310 *top = height - (int)ftop;
00311 }
00312 else
00313 *left = *right = *bottom = *top = 0;
00314 stp_dprintf(STP_DBG_PS, v, "l %d r %d b %d t %d h %d w %d\n",
00315 *left, *right, *bottom, *top, width, height);
00316 }
00317 else
00318 {
00319 *left = 18;
00320 *right = width - 18;
00321 *top = 36;
00322 *bottom = height - 36;
00323 }
00324 }
00325
00326 static void
00327 ps_imageable_area(const stp_vars_t *v,
00328 int *left,
00329 int *right,
00330 int *bottom,
00331 int *top)
00332 {
00333 setlocale(LC_ALL, "C");
00334 ps_imageable_area_internal(v, left, right, bottom, top);
00335 setlocale(LC_ALL, "");
00336 }
00337
00338 static void
00339 ps_limit(const stp_vars_t *v,
00340 int *width,
00341 int *height,
00342 int *min_width,
00343 int *min_height)
00344 {
00345 *width = INT_MAX;
00346 *height = INT_MAX;
00347 *min_width = 1;
00348 *min_height = 1;
00349 }
00350
00351
00352
00353
00354 static void
00355 ps_describe_resolution_internal(const stp_vars_t *v, int *x, int *y)
00356 {
00357 const char *resolution = stp_get_string_parameter(v, "Resolution");
00358 *x = -1;
00359 *y = -1;
00360 if (resolution)
00361 sscanf(resolution, "%dx%d", x, y);
00362 return;
00363 }
00364
00365 static void
00366 ps_describe_resolution(const stp_vars_t *v, int *x, int *y)
00367 {
00368 setlocale(LC_ALL, "C");
00369 ps_describe_resolution_internal(v, x, y);
00370 setlocale(LC_ALL, "");
00371 }
00372
00373 static const char *
00374 ps_describe_output(const stp_vars_t *v)
00375 {
00376 const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
00377 if (print_mode && strcmp(print_mode, "Color") == 0)
00378 return "RGB";
00379 else
00380 return "Whitescale";
00381 }
00382
00383
00384
00385
00386
00387 static int
00388 ps_print_internal(const stp_vars_t *v, stp_image_t *image)
00389 {
00390 int status = 1;
00391 int model = stp_get_model_id(v);
00392 const char *ppd_file = stp_get_file_parameter(v, "PPDFile");
00393 const char *resolution = stp_get_string_parameter(v, "Resolution");
00394 const char *media_size = stp_get_string_parameter(v, "PageSize");
00395 const char *media_type = stp_get_string_parameter(v, "MediaType");
00396 const char *media_source = stp_get_string_parameter(v, "InputSlot");
00397 const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
00398 unsigned short *out = NULL;
00399 int top = stp_get_top(v);
00400 int left = stp_get_left(v);
00401 int i, j;
00402 int y;
00403 int page_left,
00404 page_right,
00405 page_top,
00406 page_bottom,
00407 page_width,
00408 page_height,
00409 out_width,
00410 out_height,
00411 out_channels,
00412 out_ps_height,
00413 out_offset;
00414 time_t curtime;
00415 unsigned zero_mask;
00416 char *command;
00417 const char *temp;
00418 int order,
00419 num_commands;
00420 struct
00421 {
00422 const char *keyword, *choice;
00423 char *command;
00424 int order;
00425 } commands[4];
00426 int image_height,
00427 image_width;
00428 stp_vars_t *nv = stp_vars_create_copy(v);
00429 if (!resolution)
00430 resolution = "";
00431 if (!media_size)
00432 media_size = "";
00433 if (!media_type)
00434 media_type = "";
00435 if (!media_source)
00436 media_source = "";
00437
00438 stp_prune_inactive_options(nv);
00439 if (!stp_verify(nv))
00440 {
00441 stp_eprintf(nv, "Print options not verified; cannot print.\n");
00442 return 0;
00443 }
00444
00445 stp_image_init(image);
00446
00447
00448
00449
00450
00451 out_width = stp_get_width(v);
00452 out_height = stp_get_height(v);
00453
00454 ps_imageable_area(nv, &page_left, &page_right, &page_bottom, &page_top);
00455 left -= page_left;
00456 top -= page_top;
00457 page_width = page_right - page_left;
00458 page_height = page_bottom - page_top;
00459
00460 image_height = stp_image_height(image);
00461 image_width = stp_image_width(image);
00462
00463
00464
00465
00466
00467 curtime = time(NULL);
00468
00469 left += page_left;
00470
00471 top = page_height - top;
00472
00473 stp_dprintf(STP_DBG_PS, v,
00474 "out_width = %d, out_height = %d\n", out_width, out_height);
00475 stp_dprintf(STP_DBG_PS, v,
00476 "page_left = %d, page_right = %d, page_bottom = %d, page_top = %d\n",
00477 page_left, page_right, page_bottom, page_top);
00478 stp_dprintf(STP_DBG_PS, v, "left = %d, top = %d\n", left, top);
00479
00480 stp_puts("%!PS-Adobe-3.0\n", v);
00481 #ifdef HAVE_CONFIG_H
00482 stp_zprintf(v, "%%%%Creator: %s/Gimp-Print %s (%s)\n",
00483 stp_image_get_appname(image), VERSION, RELEASE_DATE);
00484 #else
00485 stp_zprintf(v, "%%%%Creator: %s/Gimp-Print\n", stp_image_get_appname(image));
00486 #endif
00487 stp_zprintf(v, "%%%%CreationDate: %s", ctime(&curtime));
00488 stp_puts("%Copyright: 1997-2002 by Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu)\n", v);
00489 stp_zprintf(v, "%%%%BoundingBox: %d %d %d %d\n",
00490 left, top - out_height, left + out_width, top);
00491 stp_puts("%%DocumentData: Clean7Bit\n", v);
00492 stp_zprintf(v, "%%%%LanguageLevel: %d\n", model + 1);
00493 stp_puts("%%Pages: 1\n", v);
00494 stp_puts("%%Orientation: Portrait\n", v);
00495 stp_puts("%%EndComments\n", v);
00496
00497
00498
00499
00500
00501 num_commands = 0;
00502
00503 if ((command = ppd_find(ppd_file, "PageSize", media_size, &order)) != NULL)
00504 {
00505 commands[num_commands].keyword = "PageSize";
00506 commands[num_commands].choice = media_size;
00507 commands[num_commands].command = stp_malloc(strlen(command) + 1);
00508 strcpy(commands[num_commands].command, command);
00509 commands[num_commands].order = order;
00510 num_commands ++;
00511 }
00512
00513 if ((command = ppd_find(ppd_file, "InputSlot", media_source, &order)) != NULL)
00514 {
00515 commands[num_commands].keyword = "InputSlot";
00516 commands[num_commands].choice = media_source;
00517 commands[num_commands].command = stp_malloc(strlen(command) + 1);
00518 strcpy(commands[num_commands].command, command);
00519 commands[num_commands].order = order;
00520 num_commands ++;
00521 }
00522
00523 if ((command = ppd_find(ppd_file, "MediaType", media_type, &order)) != NULL)
00524 {
00525 commands[num_commands].keyword = "MediaType";
00526 commands[num_commands].choice = media_type;
00527 commands[num_commands].command = stp_malloc(strlen(command) + 1);
00528 strcpy(commands[num_commands].command, command);
00529 commands[num_commands].order = order;
00530 num_commands ++;
00531 }
00532
00533 if ((command = ppd_find(ppd_file, "Resolution", resolution, &order)) != NULL)
00534 {
00535 commands[num_commands].keyword = "Resolution";
00536 commands[num_commands].choice = resolution;
00537 commands[num_commands].command = stp_malloc(strlen(command) + 1);
00538 strcpy(commands[num_commands].command, command);
00539 commands[num_commands].order = order;
00540 num_commands ++;
00541 }
00542
00543
00544
00545
00546
00547 for (i = 0; i < (num_commands - 1); i ++)
00548 for (j = i + 1; j < num_commands; j ++)
00549 if (commands[j].order < commands[i].order)
00550 {
00551 temp = commands[i].keyword;
00552 commands[i].keyword = commands[j].keyword;
00553 commands[j].keyword = temp;
00554
00555 temp = commands[i].choice;
00556 commands[i].choice = commands[j].choice;
00557 commands[j].choice = temp;
00558
00559 order = commands[i].order;
00560 commands[i].order = commands[j].order;
00561 commands[j].order = order;
00562
00563 command = commands[i].command;
00564 commands[i].command = commands[j].command;
00565 commands[j].command = command;
00566 }
00567
00568
00569
00570
00571
00572 if (num_commands > 0)
00573 {
00574 stp_puts("%%BeginSetup\n", v);
00575
00576 for (i = 0; i < num_commands; i ++)
00577 {
00578 stp_puts("[{\n", v);
00579 stp_zprintf(v, "%%%%BeginFeature: *%s %s\n", commands[i].keyword,
00580 commands[i].choice);
00581 if (commands[i].command[0])
00582 {
00583 stp_puts(commands[i].command, v);
00584 if (commands[i].command[strlen(commands[i].command) - 1] != '\n')
00585 stp_puts("\n", v);
00586 }
00587
00588 stp_puts("%%EndFeature\n", v);
00589 stp_puts("} stopped cleartomark\n", v);
00590 stp_free(commands[i].command);
00591 }
00592
00593 stp_puts("%%EndSetup\n", v);
00594 }
00595
00596
00597
00598
00599
00600 stp_puts("%%Page: 1 1\n", v);
00601 stp_puts("gsave\n", v);
00602
00603 stp_zprintf(v, "%d %d translate\n", left, top);
00604
00605
00606
00607
00608
00609 setlocale(LC_ALL, "C");
00610 stp_zprintf(v, "%.3f %.3f scale\n",
00611 (double)out_width / ((double)image_width),
00612 (double)out_height / ((double)image_height));
00613 setlocale(LC_ALL, "");
00614
00615 stp_channel_reset(nv);
00616 stp_channel_add(nv, 0, 0, 1.0);
00617 if (strcmp(print_mode, "Color") == 0)
00618 {
00619 stp_channel_add(nv, 1, 0, 1.0);
00620 stp_channel_add(nv, 2, 0, 1.0);
00621 stp_set_string_parameter(nv, "STPIOutputType", "RGB");
00622 }
00623 else
00624 stp_set_string_parameter(nv, "STPIOutputType", "Whitescale");
00625
00626 out_channels = stp_color_init(nv, image, 256);
00627
00628 if (model == 0)
00629 {
00630 stp_zprintf(v, "/picture %d string def\n", image_width * out_channels);
00631
00632 stp_zprintf(v, "%d %d 8\n", image_width, image_height);
00633
00634 stp_puts("[ 1 0 0 -1 0 1 ]\n", v);
00635
00636 if (strcmp(print_mode, "Color") == 0)
00637 stp_puts("{currentfile picture readhexstring pop} false 3 colorimage\n", v);
00638 else
00639 stp_puts("{currentfile picture readhexstring pop} image\n", v);
00640
00641 for (y = 0; y < image_height; y ++)
00642 {
00643 if (stp_color_get_row(nv, image, y, &zero_mask))
00644 {
00645 status = 2;
00646 break;
00647 }
00648
00649 out = stp_channel_get_input(nv);
00650 ps_hex(v, out, image_width * out_channels);
00651 }
00652 }
00653 else
00654 {
00655 if (strcmp(print_mode, "Color") == 0)
00656 stp_puts("/DeviceRGB setcolorspace\n", v);
00657 else
00658 stp_puts("/DeviceGray setcolorspace\n", v);
00659
00660 stp_puts("<<\n", v);
00661 stp_puts("\t/ImageType 1\n", v);
00662
00663 stp_zprintf(v, "\t/Width %d\n", image_width);
00664 stp_zprintf(v, "\t/Height %d\n", image_height);
00665 stp_puts("\t/BitsPerComponent 8\n", v);
00666
00667 if (strcmp(print_mode, "Color") == 0)
00668 stp_puts("\t/Decode [ 0 1 0 1 0 1 ]\n", v);
00669 else
00670 stp_puts("\t/Decode [ 0 1 ]\n", v);
00671
00672 stp_puts("\t/DataSource currentfile /ASCII85Decode filter\n", v);
00673
00674 if ((image_width * 72 / out_width) < 100)
00675 stp_puts("\t/Interpolate true\n", v);
00676
00677 stp_puts("\t/ImageMatrix [ 1 0 0 -1 0 1 ]\n", v);
00678
00679 stp_puts(">>\n", v);
00680 stp_puts("image\n", v);
00681
00682 for (y = 0, out_offset = 0; y < image_height; y ++)
00683 {
00684
00685 if (stp_color_get_row(nv, image, y , &zero_mask))
00686 {
00687 status = 2;
00688 break;
00689 }
00690 out = stp_channel_get_input(nv);
00691
00692 out_ps_height = out_offset + image_width * out_channels;
00693
00694 if (y < (image_height - 1))
00695 {
00696 ps_ascii85(v, out, out_ps_height & ~3, 0);
00697 out_offset = out_ps_height & 3;
00698 }
00699 else
00700 {
00701 ps_ascii85(v, out, out_ps_height, 1);
00702 out_offset = 0;
00703 }
00704
00705 if (out_offset > 0)
00706 memcpy(out, out + out_ps_height - out_offset, out_offset);
00707 }
00708 }
00709 stp_image_conclude(image);
00710
00711 stp_puts("grestore\n", v);
00712 stp_puts("showpage\n", v);
00713 stp_puts("%%Trailer\n", v);
00714 stp_puts("%%EOF\n", v);
00715 stp_vars_destroy(nv);
00716 return status;
00717 }
00718
00719 static int
00720 ps_print(const stp_vars_t *v, stp_image_t *image)
00721 {
00722 int status;
00723 setlocale(LC_ALL, "C");
00724 status = ps_print_internal(v, image);
00725 setlocale(LC_ALL, "");
00726 return status;
00727 }
00728
00729
00730
00731
00732
00733
00734 static void
00735 ps_hex(const stp_vars_t *v,
00736 unsigned short *data,
00737 int length)
00738 {
00739 int col;
00740 static const char *hex = "0123456789ABCDEF";
00741
00742
00743 col = 0;
00744 while (length > 0)
00745 {
00746 unsigned char pixel = (*data & 0xff00) >> 8;
00747
00748
00749
00750
00751
00752 stp_putc(hex[pixel >> 4], v);
00753 stp_putc(hex[pixel & 15], v);
00754
00755 data ++;
00756 length --;
00757
00758 col += 2;
00759 if (col >= 72)
00760 {
00761 col = 0;
00762 stp_putc('\n', v);
00763 }
00764 }
00765
00766 if (col > 0)
00767 stp_putc('\n', v);
00768 }
00769
00770
00771
00772
00773
00774
00775 static void
00776 ps_ascii85(const stp_vars_t *v,
00777 unsigned short *data,
00778 int length,
00779 int last_line)
00780 {
00781 int i;
00782 unsigned b;
00783 unsigned char c[5];
00784 static int column = 0;
00785
00786
00787 while (length > 3)
00788 {
00789 unsigned char d0 = (data[0] & 0xff00) >> 8;
00790 unsigned char d1 = (data[1] & 0xff00) >> 8;
00791 unsigned char d2 = (data[2] & 0xff00) >> 8;
00792 unsigned char d3 = (data[3] & 0xff00) >> 8;
00793 b = (((((d0 << 8) | d1) << 8) | d2) << 8) | d3;
00794
00795 if (b == 0)
00796 {
00797 stp_putc('z', v);
00798 column ++;
00799 }
00800 else
00801 {
00802 c[4] = (b % 85) + '!';
00803 b /= 85;
00804 c[3] = (b % 85) + '!';
00805 b /= 85;
00806 c[2] = (b % 85) + '!';
00807 b /= 85;
00808 c[1] = (b % 85) + '!';
00809 b /= 85;
00810 c[0] = b + '!';
00811
00812 stp_zfwrite((const char *)c, 5, 1, v);
00813 column += 5;
00814 }
00815
00816 if (column > 72)
00817 {
00818 stp_putc('\n', v);
00819 column = 0;
00820 }
00821
00822 data += 4;
00823 length -= 4;
00824 }
00825
00826 if (last_line)
00827 {
00828 if (length > 0)
00829 {
00830 for (b = 0, i = length; i > 0; b = (b << 8) | data[0], data ++, i --);
00831
00832 c[4] = (b % 85) + '!';
00833 b /= 85;
00834 c[3] = (b % 85) + '!';
00835 b /= 85;
00836 c[2] = (b % 85) + '!';
00837 b /= 85;
00838 c[1] = (b % 85) + '!';
00839 b /= 85;
00840 c[0] = b + '!';
00841
00842 stp_zfwrite((const char *)c, length + 1, 1, v);
00843 }
00844
00845 stp_puts("~>\n", v);
00846 column = 0;
00847 }
00848 }
00849
00850
00851
00852
00853
00854
00855 static char *
00856 ppd_find(const char *ppd_file,
00857 const char *name,
00858 const char *option,
00859 int *order)
00860 {
00861 char line[1024],
00862 lname[255],
00863 loption[255],
00864 *opt;
00865 static char *value = NULL;
00866
00867
00868 if (ppd_file == NULL || name == NULL || option == NULL)
00869 return (NULL);
00870 if (!value)
00871 value = stp_zalloc(32768);
00872
00873 if (ps_ppd_file == NULL || strcmp(ps_ppd_file, ppd_file) != 0)
00874 {
00875 if (ps_ppd != NULL)
00876 fclose(ps_ppd);
00877
00878 ps_ppd = fopen(ppd_file, "r");
00879
00880 if (ps_ppd == NULL)
00881 ps_ppd_file = NULL;
00882 else
00883 ps_ppd_file = ppd_file;
00884 }
00885
00886 if (ps_ppd == NULL)
00887 return (NULL);
00888
00889 if (order != NULL)
00890 *order = 1000;
00891
00892 rewind(ps_ppd);
00893 while (fgets(line, sizeof(line), ps_ppd) != NULL)
00894 {
00895 if (line[0] != '*')
00896 continue;
00897
00898 if (strncasecmp(line, "*OrderDependency:", 17) == 0 && order != NULL)
00899 {
00900 sscanf(line, "%*s%d", order);
00901 continue;
00902 }
00903 else if (sscanf(line, "*%s %[^/:]", lname, loption) != 2)
00904 continue;
00905
00906 if (strcasecmp(lname, name) == 0 &&
00907 strcasecmp(loption, option) == 0)
00908 {
00909 opt = strchr(line, ':') + 1;
00910 while (*opt == ' ' || *opt == '\t')
00911 opt ++;
00912 if (*opt != '\"')
00913 continue;
00914
00915 strcpy(value, opt + 1);
00916 if ((opt = strchr(value, '\"')) == NULL)
00917 {
00918 while (fgets(line, sizeof(line), ps_ppd) != NULL)
00919 {
00920 strcat(value, line);
00921 if (strchr(line, '\"') != NULL)
00922 {
00923 strcpy(strchr(value, '\"'), "\n");
00924 break;
00925 }
00926 }
00927 }
00928 else
00929 *opt = '\0';
00930
00931 return (value);
00932 }
00933 }
00934
00935 return (NULL);
00936 }
00937
00938 static const stp_printfuncs_t print_ps_printfuncs =
00939 {
00940 ps_list_parameters,
00941 ps_parameters,
00942 ps_media_size,
00943 ps_imageable_area,
00944 ps_limit,
00945 ps_print,
00946 ps_describe_resolution,
00947 ps_describe_output,
00948 stp_verify_printer_params,
00949 NULL,
00950 NULL
00951 };
00952
00953
00954 static stp_family_t print_ps_module_data =
00955 {
00956 &print_ps_printfuncs,
00957 NULL
00958 };
00959
00960
00961 static int
00962 print_ps_module_init(void)
00963 {
00964 return stp_family_register(print_ps_module_data.printer_list);
00965 }
00966
00967
00968 static int
00969 print_ps_module_exit(void)
00970 {
00971 return stp_family_unregister(print_ps_module_data.printer_list);
00972 }
00973
00974
00975
00976 #define stp_module_version print_ps_LTX_stp_module_version
00977 #define stp_module_data print_ps_LTX_stp_module_data
00978
00979 stp_module_version_t stp_module_version = {0, 0};
00980
00981 stp_module_t stp_module_data =
00982 {
00983 "ps",
00984 VERSION,
00985 "Postscript family driver",
00986 STP_MODULE_CLASS_FAMILY,
00987 NULL,
00988 print_ps_module_init,
00989 print_ps_module_exit,
00990 (void *) &print_ps_module_data
00991 };
00992