void SetOptions() { SetCommandLineOptions(); SetCommonOptions(); SetConfigOnlyOptions(); SetEnvMapping(); }
int /* O - Exit status */ imagetops_main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { cups_image_t *img; /* Image to print */ float xprint, /* Printable area */ yprint, xinches, /* Total size in inches */ yinches; float xsize, /* Total size in points */ ysize, xsize2, ysize2; float aspect; /* Aspect ratio */ int xpages, /* # x pages */ ypages, /* # y pages */ xpage, /* Current x page */ ypage, /* Current y page */ page; /* Current page number */ int xc0, yc0, /* Corners of the page in image coords */ xc1, yc1; cups_ib_t *row; /* Current row */ int y; /* Current Y coordinate in image */ int colorspace; /* Output colorspace */ int out_offset, /* Offset into output buffer */ out_length; /* Length of output buffer */ ppd_file_t *ppd; /* PPD file */ ppd_choice_t *choice; /* PPD option choice */ int num_options; /* Number of print options */ cups_option_t *options; /* Print options */ const char *val; /* Option value */ int slowcollate; /* Collate copies the slow way */ float g; /* Gamma correction value */ float b; /* Brightness factor */ float zoom; /* Zoom facter */ int xppi, yppi; /* Pixels-per-inch */ int hue, sat; /* Hue and saturation adjustment */ int realcopies, /* Real copies being printed */ emit_jcl; /* Emit JCL? */ float left, top; /* Left and top of image */ char filename[1024]; /* Name of file to print */ time_t curtime; /* Current time */ struct tm *curtm; /* Current date */ char curdate[255]; /* Current date string */ int psFileMode = 0; //0:CREATE New ; 1: Append int outColorDevice = 1; //0 : monochrome print , 1:color print int count = 0,numFiles=1; int defout,outfd; /* * Make sure status messages are not buffered... */ int ii=0; for(;ii<argc;ii++) LOGI("imagetops : argv:%s",argv[ii]); fflush(stdout); Copies = 1; setbuf(stderr, NULL); /* * Ignore broken pipe signals... */ signal(SIGPIPE, SIG_IGN); /* * Process command-line options and write the prolog... */ zoom = 0.0; xppi = 0; yppi = 0; hue = 0; sat = 100; g = 1.0; b = 1.0; Copies = atoi(argv[4]); options = NULL; num_options = cupsParseOptions(argv[5], 0, &options); ppdFilePath = argv[6]; ContentType= argv[7]; psFilePath = argv[8]; outColorDevice = atoi(argv[9]); numFiles = argc - 10; LOGI("imagetops : numFiles=%d",numFiles); ppd = SetCommonOptions(num_options, options, 0); if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) { /* * This IPP attribute is unnecessarily complicated... * * single-document, separate-documents-collated-copies, and * single-document-new-sheet all require collated copies. * * separate-documents-uncollated-copies allows for uncollated copies. */ Collate = _cups_strcasecmp(val, "separate-documents-uncollated-copies") != 0; } if ((val = cupsGetOption("Collate", num_options, options)) != NULL && _cups_strcasecmp(val, "True") == 0) Collate = 1; if ((val = cupsGetOption("gamma", num_options, options)) != NULL) { /* * Get gamma value from 1 to 10000... */ g = atoi(val) * 0.001f; if (g < 0.001f) g = 0.001f; else if (g > 10.0f) g = 10.0f; } if ((val = cupsGetOption("brightness", num_options, options)) != NULL) { /* * Get brightness value from 10 to 1000. */ b = atoi(val) * 0.01f; if (b < 0.1f) b = 0.1f; else if (b > 10.0f) b = 10.0f; } if ((val = cupsGetOption("scaling", num_options, options)) != NULL) zoom = atoi(val) * 0.01; else if ((val = cupsGetOption("fitplot", num_options, options)) != NULL && !_cups_strcasecmp(val, "true")) zoom = 1.0; else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL && !_cups_strcasecmp(val, "true")) zoom = 1.0; if ((val = cupsGetOption("ppi", num_options, options)) != NULL) if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) yppi = xppi; if ((val = cupsGetOption("position", num_options, options)) != NULL) { if (_cups_strcasecmp(val, "center") == 0) { XPosition = 0; YPosition = 0; } else if (_cups_strcasecmp(val, "top") == 0) { XPosition = 0; YPosition = 1; } else if (_cups_strcasecmp(val, "left") == 0) { XPosition = -1; YPosition = 0; } else if (_cups_strcasecmp(val, "right") == 0) { XPosition = 1; YPosition = 0; } else if (_cups_strcasecmp(val, "top-left") == 0) { XPosition = -1; YPosition = 1; } else if (_cups_strcasecmp(val, "top-right") == 0) { XPosition = 1; YPosition = 1; } else if (_cups_strcasecmp(val, "bottom") == 0) { XPosition = 0; YPosition = -1; } else if (_cups_strcasecmp(val, "bottom-left") == 0) { XPosition = -1; YPosition = -1; } else if (_cups_strcasecmp(val, "bottom-right") == 0) { XPosition = 1; YPosition = -1; } } if ((val = cupsGetOption("saturation", num_options, options)) != NULL) sat = atoi(val); if ((val = cupsGetOption("hue", num_options, options)) != NULL) hue = atoi(val); if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL) { val = choice->choice; choice->marked = 0; } else val = cupsGetOption("mirror", num_options, options); if (val && (!_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") || !_cups_strcasecmp(val, "yes"))) Flip = 1; if ((val = cupsGetOption("emit-jcl", num_options, options)) != NULL && (!_cups_strcasecmp(val, "false") || !_cups_strcasecmp(val, "off") || !_cups_strcasecmp(val, "no") || !strcmp(val, "0"))) emit_jcl = 0; else emit_jcl = 1; LOGI("imagetops/Copies=%d , Collate=%d, gamma=%f, brightness=%f, zoom=%f",Copies,Collate,g,b,zoom); LOGI("imagetops/xppi=%d,yppi=%d,XPosition=%d,YPosition=%d,sat=%d,hue=%d,flip=%d,emit_jcl=%d",xppi,yppi,XPosition,YPosition,sat,hue,Flip,emit_jcl); /* * Open the input image to print... */ if(outColorDevice == 1) //added @ grv colorspace = CUPS_IMAGE_RGB_CMYK; else colorspace = CUPS_IMAGE_WHITE; LOGI("imagetops/ colorspace = %d",colorspace); for(count=0;count<numFiles;count++){ Copies = atoi(argv[4]); //do everything for both image files strlcpy(filename, argv[(10 + count)], sizeof(filename)); LOGI("imagetops : count=%d , filename=%s",count,filename); img = cupsImageOpen(filename, colorspace, CUPS_IMAGE_WHITE, sat, hue, NULL); if (img == NULL) { LOGI("imagetops:error:The print file could not be opened."); _cupsLangPrintFilter(stderr, "ERROR", _("The print file could not be opened.")); ppdClose(ppd); return (1); } colorspace = cupsImageGetColorSpace(img); LOGI("imagetops: cupsImageGetColorSpace finished : colorspace :%d",colorspace); /* * Scale as necessary... */ if (zoom == 0.0 && xppi == 0) { xppi = cupsImageGetXPPI(img); yppi = cupsImageGetYPPI(img); } LOGI("imagetops:xppi=%d",xppi); LOGI("imagetops:yppi=%d",yppi); if (yppi == 0) yppi = xppi; fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n", xppi, yppi, zoom); if (xppi > 0) { /* * Scale the image as neccesary to match the desired pixels-per-inch. */ if (Orientation & 1) { xprint = (PageTop - PageBottom) / 72.0; yprint = (PageRight - PageLeft) / 72.0; } else { xprint = (PageRight - PageLeft) / 72.0; yprint = (PageTop - PageBottom) / 72.0; } fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", xprint, yprint); xinches = (float)cupsImageGetWidth(img) / (float)xppi; yinches = (float)cupsImageGetHeight(img) / (float)yppi; fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n", xinches, yinches); if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL) { xinches = xinches * atoi(val) / 100; yinches = yinches * atoi(val) / 100; } if (cupsGetOption("orientation-requested", num_options, options) == NULL && cupsGetOption("landscape", num_options, options) == NULL) { /* * Rotate the image if it will fit landscape but not portrait... */ fputs("DEBUG: Auto orientation...\n", stderr); LOGI("imagetops.c : Auto orientation..."); if ((xinches > xprint || yinches > yprint) && xinches <= yprint && yinches <= xprint) { /* * Rotate the image as needed... */ fputs("DEBUG: Using landscape orientation...\n", stderr); LOGI("imagetops.c : Auto orientation : Using landscape orientation"); Orientation = (Orientation + 1) & 3; xsize = yprint; yprint = xprint; xprint = xsize; } } }else{ /* * Scale percentage of page size... */ xprint = (PageRight - PageLeft) / 72.0; yprint = (PageTop - PageBottom) / 72.0; aspect = (float)cupsImageGetYPPI(img) / (float)cupsImageGetXPPI(img); fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n", xprint, yprint); fprintf(stderr, "DEBUG: cupsImageGetXPPI(img) = %d, cupsImageGetYPPI(img) = %d, aspect = %f\n", cupsImageGetXPPI(img), cupsImageGetYPPI(img), aspect); xsize = xprint * zoom; ysize = xsize * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; if (ysize > (yprint * zoom)) { ysize = yprint * zoom; xsize = ysize * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); } xsize2 = yprint * zoom; ysize2 = xsize2 * cupsImageGetHeight(img) / cupsImageGetWidth(img) / aspect; if (ysize2 > (xprint * zoom)) { ysize2 = xprint * zoom; xsize2 = ysize2 * cupsImageGetWidth(img) * aspect / cupsImageGetHeight(img); } fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize); fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2); if (cupsGetOption("orientation-requested", num_options, options) == NULL && cupsGetOption("landscape", num_options, options) == NULL) { /* * Choose the rotation with the largest area, but prefer * portrait if they are equal... */ fputs("DEBUG: Auto orientation...\n", stderr); if ((xsize * ysize) < (xsize2 * xsize2)) { /* * Do landscape orientation... */ fputs("DEBUG: Using landscape orientation...\n", stderr); Orientation = 1; xinches = xsize2; yinches = ysize2; xprint = (PageTop - PageBottom) / 72.0; yprint = (PageRight - PageLeft) / 72.0; } else { /* * Do portrait orientation... */ fputs("DEBUG: Using portrait orientation...\n", stderr); Orientation = 0; xinches = xsize; yinches = ysize; } } else if (Orientation & 1) { fputs("DEBUG: Using landscape orientation...\n", stderr); xinches = xsize2; yinches = ysize2; xprint = (PageTop - PageBottom) / 72.0; yprint = (PageRight - PageLeft) / 72.0; } else { fputs("DEBUG: Using portrait orientation...\n", stderr); xinches = xsize; yinches = ysize; xprint = (PageRight - PageLeft) / 72.0; yprint = (PageTop - PageBottom) / 72.0; } } /* * Compute the number of pages to print and the size of the image on each * page... */ xpages = ceil(xinches / xprint); ypages = ceil(yinches / yprint); xprint = xinches / xpages; yprint = yinches / ypages; fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",xpages, xprint, ypages, yprint); /* * Update the page size for custom sizes... */ if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL && _cups_strcasecmp(choice->choice, "Custom") == 0) { float width, /* New width in points */ length; /* New length in points */ char s[255]; /* New custom page size... */ /* * Use the correct width and length for the current orientation... */ if (Orientation & 1) { width = yprint * 72.0; length = xprint * 72.0; } else { width = xprint * 72.0; length = yprint * 72.0; } /* * Add margins to page size... */ width += ppd->custom_margins[0] + ppd->custom_margins[2]; length += ppd->custom_margins[1] + ppd->custom_margins[3]; /* * Enforce minimums... */ if (width < ppd->custom_min[0]) width = ppd->custom_min[0]; if (length < ppd->custom_min[1]) length = ppd->custom_min[1]; fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",width / 72.0, length / 72.0); /* * Set the new custom size... */ sprintf(s, "Custom.%.0fx%.0f", width, length); ppdMarkOption(ppd, "PageSize", s); /* * Update page variables... */ PageWidth = width; PageLength = length; PageLeft = ppd->custom_margins[0]; PageRight = width - ppd->custom_margins[2]; PageBottom = ppd->custom_margins[1]; PageTop = length - ppd->custom_margins[3]; } /* * See if we need to collate, and if so how we need to do it... */ if (xpages == 1 && ypages == 1) Collate = 0; slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL; if (Copies > 1 && !slowcollate) { realcopies = Copies; Copies = 1; } else realcopies = 1; /* * Write any "exit server" options that have been selected... */ //Changes to create ps file -- start if(count == 0){//single side print defout = dup(1); outfd = open(psFilePath,O_RDWR | O_CREAT,S_IRWXU |S_IRWXG | S_IRWXO); dup2(outfd,1); } //Changes to create ps file -- end ppdEmit(ppd, stdout, PPD_ORDER_EXIT); /* * Write any JCL commands that are needed to print PostScript code... */ if (emit_jcl) ppdEmitJCL(ppd, stdout, atoi(argv[1]), argv[2], argv[3]); /* * Start sending the document with any commands needed... */ curtime = time(NULL); curtm = localtime(&curtime); ////////////////// if(count == 0){ puts("%!PS-Adobe-3.0"); printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom,PageRight, PageTop); printf("%%%%LanguageLevel: %d\n", LanguageLevel); printf("%%%%Pages: %d\n", xpages * ypages * Copies * numFiles); puts("%%DocumentData: Clean7Bit"); puts("%%DocumentNeededResources: font Helvetica-Bold"); puts("%%Creator: imagetops/" CUPS_SVERSION); strftime(curdate, sizeof(curdate), "%c", curtm); printf("%%%%CreationDate: %s\n", curdate); WriteTextComment("Title", argv[3]); WriteTextComment("For", argv[2]); if (Orientation & 1) puts("%%Orientation: Landscape"); else puts("%%Orientation: Portrait"); puts("%%EndComments"); puts("%%BeginProlog"); if (ppd != NULL && ppd->patches != NULL) puts(ppd->patches); ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT); ppdEmit(ppd, stdout, PPD_ORDER_ANY); ppdEmit(ppd, stdout, PPD_ORDER_PROLOG); if (g != 1.0 || b != 1.0) printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } " "ifelse %.3f mul } bind settransfer\n", g, b); WriteCommon(); switch (Orientation) { case 0 : WriteLabelProlog(cupsGetOption("page-label", num_options, options), PageBottom, PageTop, PageWidth); break; case 1 : WriteLabelProlog(cupsGetOption("page-label", num_options, options), PageLeft, PageRight, PageLength); break; case 2 : WriteLabelProlog(cupsGetOption("page-label", num_options, options), PageLength - PageTop, PageLength - PageBottom, PageWidth); break; case 3 : WriteLabelProlog(cupsGetOption("page-label", num_options, options), PageWidth - PageRight, PageWidth - PageLeft,PageLength); break; } if (realcopies > 1) { if (ppd == NULL || ppd->language_level == 1) printf("/#copies %d def\n", realcopies); else printf("<</NumCopies %d>>setpagedevice\n", realcopies); } puts("%%EndProlog"); } /* * Output the pages... */ row = malloc(cupsImageGetWidth(img) * abs(colorspace) + 3); fprintf(stderr, "DEBUG: XPosition=%d, YPosition=%d, Orientation=%d\n",XPosition, YPosition, Orientation); fprintf(stderr, "DEBUG: xprint=%.0f, yprint=%.0f\n", xprint, yprint); fprintf(stderr, "DEBUG: PageLeft=%.0f, PageRight=%.0f, PageWidth=%.0f\n",PageLeft, PageRight, PageWidth); fprintf(stderr, "DEBUG: PageBottom=%.0f, PageTop=%.0f, PageLength=%.0f\n",PageBottom, PageTop, PageLength); switch (Orientation) { default : switch (XPosition) { case -1 : left = PageLeft; break; default : left = (PageRight + PageLeft - xprint * 72) / 2; break; case 1 : left = PageRight - xprint * 72; break; } switch (YPosition) { case -1 : top = PageBottom + yprint * 72; break; default : top = (PageTop + PageBottom + yprint * 72) / 2; break; case 1 : top = PageTop; break; } break; case 1 : switch (XPosition) { case -1 : left = PageBottom; break; default : left = (PageTop + PageBottom - xprint * 72) / 2; break; case 1 : left = PageTop - xprint * 72; break; } switch (YPosition) { case -1 : top = PageLeft + yprint * 72; break; default : top = (PageRight + PageLeft + yprint * 72) / 2; break; case 1 : top = PageRight; break; } break; case 2 : switch (XPosition) { case 1 : left = PageLeft; break; default : left = (PageRight + PageLeft - xprint * 72) / 2; break; case -1 : left = PageRight - xprint * 72; break; } switch (YPosition) { case 1 : top = PageBottom + yprint * 72; break; default : top = (PageTop + PageBottom + yprint * 72) / 2; break; case -1 : top = PageTop; break; } break; case 3 : switch (XPosition) { case 1 : left = PageBottom; break; default : left = (PageTop + PageBottom - xprint * 72) / 2; break; case -1 : left = PageTop - xprint * 72; break; } switch (YPosition) { case 1 : top = PageLeft + yprint * 72; break; default : top = (PageRight + PageLeft + yprint * 72) / 2; break; case -1 : top = PageRight; break; } break; } fprintf(stderr, "DEBUG: left=%.2f, top=%.2f\n", left, top); for (page = 1; Copies > 0; Copies --) for (xpage = 0; xpage < xpages; xpage ++) for (ypage = 0; ypage < ypages; ypage ++, page ++) { if (ppd && ppd->num_filters == 0) fprintf(stderr, "PAGE: %d %d\n", page, realcopies); _cupsLangPrintFilter(stderr, "INFO", _("Printing page %d."), page); printf("%%%%Page: %d %d\n", (page * (count+1)), (page*(count+1))); //TEST_TODO if(count>=1){ puts("%%BeginPageSetup"); if (Orientation & 1) puts("%%PageOrientation: Landscape"); else puts("%%PageOrientation: Portrait"); puts("%%EndPageSetup"); } ppdEmit(ppd, stdout, PPD_ORDER_PAGE); puts("gsave"); if (Flip) printf("%.0f 0 translate -1 1 scale\n", PageWidth); switch (Orientation) { case 1 : /* Landscape */ printf("%.0f 0 translate 90 rotate\n", PageWidth); break; case 2 : /* Reverse Portrait */ printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); break; case 3 : /* Reverse Landscape */ printf("0 %.0f translate -90 rotate\n", PageLength); break; } puts("gsave"); xc0 = cupsImageGetWidth(img) * xpage / xpages; xc1 = cupsImageGetWidth(img) * (xpage + 1) / xpages - 1; yc0 = cupsImageGetHeight(img) * ypage / ypages; yc1 = cupsImageGetHeight(img) * (ypage + 1) / ypages - 1; printf("%.1f %.1f translate\n", left, top); printf("%.3f %.3f scale\n\n",xprint * 72.0 / (xc1 - xc0 + 1),yprint * 72.0 / (yc1 - yc0 + 1)); if (LanguageLevel == 1) { printf("/picture %d string def\n", (xc1 - xc0 + 1) * abs(colorspace)); printf("%d %d 8[1 0 0 -1 0 1]", (xc1 - xc0 + 1), (yc1 - yc0 + 1)); if (colorspace == CUPS_IMAGE_WHITE) puts("{currentfile picture readhexstring pop} image"); else printf("{currentfile picture readhexstring pop} false %d colorimage\n",abs(colorspace)); for (y = yc0; y <= yc1; y ++) { cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row); ps_hex(row, (xc1 - xc0 + 1) * abs(colorspace), y == yc1); } } else { switch (colorspace) { case CUPS_IMAGE_WHITE : puts("/DeviceGray setcolorspace"); break; case CUPS_IMAGE_RGB : puts("/DeviceRGB setcolorspace"); break; case CUPS_IMAGE_CMYK : puts("/DeviceCMYK setcolorspace"); break; } printf("<<" "/ImageType 1" "/Width %d" "/Height %d" "/BitsPerComponent 8", xc1 - xc0 + 1, yc1 - yc0 + 1); switch (colorspace) { case CUPS_IMAGE_WHITE : fputs("/Decode[0 1]", stdout); break; case CUPS_IMAGE_RGB : fputs("/Decode[0 1 0 1 0 1]", stdout); break; case CUPS_IMAGE_CMYK : fputs("/Decode[0 1 0 1 0 1 0 1]", stdout); break; } fputs("\n/DataSource currentfile/ASCII85Decode filter", stdout); if (((xc1 - xc0 + 1) / xprint) < 100.0) fputs("/Interpolate true", stdout); puts("/ImageMatrix[1 0 0 -1 0 1]>>image"); for (y = yc0, out_offset = 0; y <= yc1; y ++) { cupsImageGetRow(img, xc0, y, xc1 - xc0 + 1, row + out_offset); out_length = (xc1 - xc0 + 1) * abs(colorspace) + out_offset; out_offset = out_length & 3; ps_ascii85(row, out_length, y == yc1); if (out_offset > 0) memcpy(row, row + out_length - out_offset, out_offset); } } if(count==1){ puts("grestore"); WriteLabels(0); puts("grestore"); } puts("showpage"); puts("%%PageTrailer"); } } //end of big for loop puts("%%EOF"); /* * End the job with the appropriate JCL command or CTRL-D otherwise. */ if (emit_jcl) { if (ppd && ppd->jcl_end) ppdEmitJCLEnd(ppd, stdout); else putchar(0x04); } fflush(stdout); dup2(defout,1); close(outfd); close(defout); /* * Close files... */ LOGI("imagetops:Close files"); cupsImageClose(img); ppdClose(ppd); return (0); }
int /* O - Exit status */ TextMain(const char *name, /* I - Name of filter */ int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { FILE *fp; /* Print file */ ppd_file_t *ppd; /* PPD file */ int i, /* Looping var */ ch, /* Current char from file */ lastch, /* Previous char from file */ attr, /* Current attribute */ line, /* Current line */ column, /* Current column */ page_column; /* Current page column */ int num_options; /* Number of print options */ cups_option_t *options; /* Print options */ const char *val; /* Option value */ char keyword[64], /* Keyword string */ *keyptr; /* Pointer into string */ int keycol; /* Column where keyword starts */ int ccomment; /* Inside a C-style comment? */ int cstring; /* Inside a C string */ /* * Make sure status messages are not buffered... */ setbuf(stderr, NULL); /* * Check command-line... */ if (argc < 6 || argc > 7) { fprintf(stderr, _("Usage: %s job-id user title copies options [file]\n"), name); return (1); } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, send stdin instead... */ if (argc == 6) fp = stdin; else { /* * Try to open the print file... */ if ((fp = fopen(argv[6], "rb")) == NULL) { perror("DEBUG: unable to open print file - "); return (1); } } /* * Process command-line options and write the prolog... */ options = NULL; num_options = cupsParseOptions(argv[5], 0, &options); if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL && strcasecmp(val, "no") && strcasecmp(val, "off") && strcasecmp(val, "false")) { PageLeft = 72.0f; PageRight = PageWidth - 36.0f; PageBottom = PageBottom > 36.0f ? PageBottom : 36.0f; PageTop = PageLength - 36.0f; CharsPerInch = 12; LinesPerInch = 8; if ((val = getenv("CONTENT_TYPE")) == NULL) { PrettyPrint = PRETTY_PLAIN; NumKeywords = 0; Keywords = NULL; } else if (strcasecmp(val, "application/x-cshell") == 0) { PrettyPrint = PRETTY_SHELL; NumKeywords = sizeof(csh_keywords) / sizeof(csh_keywords[0]); Keywords = csh_keywords; } else if (strcasecmp(val, "application/x-csource") == 0) { PrettyPrint = PRETTY_CODE; NumKeywords = sizeof(code_keywords) / sizeof(code_keywords[0]); Keywords = code_keywords; } else if (strcasecmp(val, "application/x-perl") == 0) { PrettyPrint = PRETTY_PERL; NumKeywords = sizeof(perl_keywords) / sizeof(perl_keywords[0]); Keywords = perl_keywords; } else if (strcasecmp(val, "application/x-shell") == 0) { PrettyPrint = PRETTY_SHELL; NumKeywords = sizeof(sh_keywords) / sizeof(sh_keywords[0]); Keywords = sh_keywords; } else { PrettyPrint = PRETTY_PLAIN; NumKeywords = 0; Keywords = NULL; } } ppd = SetCommonOptions(num_options, options, 1); if ((val = cupsGetOption("wrap", num_options, options)) == NULL) WrapLines = 1; else WrapLines = !strcasecmp(val, "true") || !strcasecmp(val, "on") || !strcasecmp(val, "yes"); if ((val = cupsGetOption("columns", num_options, options)) != NULL) PageColumns = atoi(val); if ((val = cupsGetOption("cpi", num_options, options)) != NULL) CharsPerInch = atof(val); if ((val = cupsGetOption("lpi", num_options, options)) != NULL) LinesPerInch = atof(val); if (PrettyPrint) PageTop -= 216.0f / LinesPerInch; Copies = atoi(argv[4]); WriteProlog(argv[3], argv[2], getenv("CLASSIFICATION"), cupsGetOption("page-label", num_options, options), ppd); /* * Read text from the specified source and print it... */ lastch = 0; column = 0; line = 0; page_column = 0; attr = 0; keyptr = keyword; keycol = 0; ccomment = 0; cstring = 0; while ((ch = getutf8(fp)) >= 0) { /* * Control codes: * * BS Backspace (0x08) * HT Horizontal tab; next 8th column (0x09) * LF Line feed; forward full line (0x0a) * VT Vertical tab; reverse full line (0x0b) * FF Form feed (0x0c) * CR Carriage return (0x0d) * ESC 7 Reverse full line (0x1b 0x37) * ESC 8 Reverse half line (0x1b 0x38) * ESC 9 Forward half line (0x1b 0x39) */ switch (ch) { case 0x08 : /* BS - backspace for boldface & underline */ if (column > 0) column --; keyptr = keyword; keycol = column; break; case 0x09 : /* HT - tab to next 8th column */ if (PrettyPrint && keyptr > keyword) { *keyptr = '\0'; keyptr = keyword; if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), compare_keywords)) { /* * Put keywords in boldface... */ i = page_column * (ColumnWidth + ColumnGutter); while (keycol < column) { Page[line][keycol + i].attr |= ATTR_BOLD; keycol ++; } } } column = (column + 8) & ~7; if (column >= ColumnWidth && WrapLines) { /* Wrap text to margins */ line ++; column = 0; if (line >= SizeLines) { page_column ++; line = 0; if (page_column >= PageColumns) { WritePage(); page_column = 0; } } } keycol = column; attr &= ~ATTR_BOLD; break; case 0x0d : /* CR */ #ifndef __APPLE__ /* * All but MacOS/Darwin treat CR as was intended by ANSI * folks, namely to move to column 0/1. Some programs still * use this to do boldfacing and underlining... */ column = 0; break; #else /* * MacOS/Darwin still need to treat CR as a line ending. */ { int nextch; if ((nextch = getc(fp)) != 0x0a) ungetc(nextch, fp); else ch = nextch; } #endif /* !__APPLE__ */ case 0x0a : /* LF - output current line */ if (PrettyPrint && keyptr > keyword) { *keyptr = '\0'; keyptr = keyword; if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), compare_keywords)) { /* * Put keywords in boldface... */ i = page_column * (ColumnWidth + ColumnGutter); while (keycol < column) { Page[line][keycol + i].attr |= ATTR_BOLD; keycol ++; } } } line ++; column = 0; keycol = 0; if (!ccomment && !cstring) attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); if (line >= SizeLines) { page_column ++; line = 0; if (page_column >= PageColumns) { WritePage(); page_column = 0; } } break; case 0x0b : /* VT - move up 1 line */ if (line > 0) line --; keyptr = keyword; keycol = column; if (!ccomment && !cstring) attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); break; case 0x0c : /* FF - eject current page... */ if (PrettyPrint && keyptr > keyword) { *keyptr = '\0'; keyptr = keyword; if (bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), compare_keywords)) { /* * Put keywords in boldface... */ i = page_column * (ColumnWidth + ColumnGutter); while (keycol < column) { Page[line][keycol + i].attr |= ATTR_BOLD; keycol ++; } } } page_column ++; column = 0; keycol = 0; line = 0; if (!ccomment && !cstring) attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); if (page_column >= PageColumns) { WritePage(); page_column = 0; } break; case 0x1b : /* Escape sequence */ ch = getutf8(fp); if (ch == '7') { /* * ESC 7 Reverse full line (0x1b 0x37) */ if (line > 0) line --; } else if (ch == '8') { /* * ESC 8 Reverse half line (0x1b 0x38) */ if ((attr & ATTR_RAISED) && line > 0) { attr &= ~ATTR_RAISED; line --; } else if (attr & ATTR_LOWERED) attr &= ~ATTR_LOWERED; else attr |= ATTR_RAISED; } else if (ch == '9') { /* * ESC 9 Forward half line (0x1b 0x39) */ if ((attr & ATTR_LOWERED) && line < (SizeLines - 1)) { attr &= ~ATTR_LOWERED; line ++; } else if (attr & ATTR_RAISED) attr &= ~ATTR_RAISED; else attr |= ATTR_LOWERED; } break; default : /* All others... */ if (ch < ' ') break; /* Ignore other control chars */ if (PrettyPrint > PRETTY_PLAIN) { /* * Do highlighting of C/C++ keywords, preprocessor commands, * and comments... */ if (ch == ' ' && (attr & ATTR_BOLD)) { /* * Stop bolding preprocessor command... */ attr &= ~ATTR_BOLD; } else if (!(isalnum(ch & 255) || ch == '_') && keyptr > keyword) { /* * Look for a keyword... */ *keyptr = '\0'; keyptr = keyword; if (!(attr & ATTR_ITALIC) && bsearch(&keyptr, Keywords, NumKeywords, sizeof(char *), compare_keywords)) { /* * Put keywords in boldface... */ i = page_column * (ColumnWidth + ColumnGutter); while (keycol < column) { Page[line][keycol + i].attr |= ATTR_BOLD; keycol ++; } } } else if ((isalnum(ch & 255) || ch == '_') && !ccomment && !cstring) { /* * Add characters to the current keyword (if they'll fit). */ if (keyptr == keyword) keycol = column; if (keyptr < (keyword + sizeof(keyword) - 1)) *keyptr++ = ch; } else if (ch == '\"' && lastch != '\\' && !ccomment && !cstring) { /* * Start a C string constant... */ cstring = -1; attr = ATTR_BLUE; } else if (ch == '*' && lastch == '/' && !cstring && PrettyPrint != PRETTY_SHELL) { /* * Start a C-style comment... */ ccomment = 1; attr = ATTR_ITALIC | ATTR_GREEN; } else if (ch == '/' && lastch == '/' && !cstring && PrettyPrint == PRETTY_CODE) { /* * Start a C++-style comment... */ attr = ATTR_ITALIC | ATTR_GREEN; } else if (ch == '#' && !cstring && PrettyPrint != PRETTY_CODE) { /* * Start a shell-style comment... */ attr = ATTR_ITALIC | ATTR_GREEN; } else if (ch == '#' && column == 0 && !ccomment && !cstring && PrettyPrint == PRETTY_CODE) { /* * Start a preprocessor command... */ attr = ATTR_BOLD | ATTR_RED; } } if (column >= ColumnWidth && WrapLines) { /* Wrap text to margins */ column = 0; line ++; if (line >= SizeLines) { page_column ++; line = 0; if (page_column >= PageColumns) { WritePage(); page_column = 0; } } } /* * Add text to the current column & line... */ if (column < ColumnWidth) { i = column + page_column * (ColumnWidth + ColumnGutter); if (PrettyPrint) Page[line][i].attr = attr; else if (ch == ' ' && Page[line][i].ch) ch = Page[line][i].ch; else if (ch == Page[line][i].ch) Page[line][i].attr |= ATTR_BOLD; else if (Page[line][i].ch == '_') Page[line][i].attr |= ATTR_UNDERLINE; else if (ch == '_') { Page[line][i].attr |= ATTR_UNDERLINE; if (Page[line][i].ch) ch = Page[line][i].ch; } else Page[line][i].attr = attr; Page[line][i].ch = ch; } if (PrettyPrint) { if ((ch == '{' || ch == '}') && !ccomment && !cstring && column < ColumnWidth) { /* * Highlight curley braces... */ Page[line][column].attr |= ATTR_BOLD; } else if ((ch == '/' || ch == '*') && lastch == '/' && column < ColumnWidth && PrettyPrint != PRETTY_SHELL) { /* * Highlight first comment character... */ Page[line][column - 1].attr = attr; } else if (ch == '\"' && lastch != '\\' && !ccomment && cstring > 0) { /* * End a C string constant... */ cstring = 0; attr &= ~ATTR_BLUE; } else if (ch == '/' && lastch == '*' && ccomment) { /* * End a C-style comment... */ ccomment = 0; attr &= ~(ATTR_ITALIC | ATTR_GREEN); } if (cstring < 0) cstring = 1; } column ++; break; } /* * Save this character for the next cycle. */ lastch = ch; } /* * Write any remaining page data... */ if (line > 0 || page_column > 0 || column > 0) WritePage(); /* * Write the epilog and return... */ WriteEpilogue(); if (ppd != NULL) ppdClose(ppd); return (0); }