/* gdevlbp3.c */ /* Canon LASER SHOT LBP-310/320 printer driver for Ghostscript * working on standerd/fine image mode. * * If any comment, write to naoya@mahoroba.ne.jp */ #include "gdevprn.h" #define mm_to_inch(x) (x)/25.4 /* The device descriptor */ static dev_proc_print_page(lbp310PrintPage); static dev_proc_print_page(lbp320PrintPage); gx_device_printer far_data gs_lbp310_device = prn_device(prn_std_procs, "lbp310", DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 600, 600, mm_to_inch(5.0), mm_to_inch(5.0), mm_to_inch(5.0), mm_to_inch(5.0), 1, lbp310PrintPage); gx_device_printer far_data gs_lbp320_device = prn_device(prn_std_procs, "lbp320", DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS, 600, 600, mm_to_inch(5.0), mm_to_inch(5.0), mm_to_inch(5.0), mm_to_inch(5.0), 1, lbp320PrintPage); enum Paper { a4, a5, postcard, b5, letter }; struct bounding { enum Paper paper; int Top, Bottom, Left, Right; }; struct ppi { int w; int h; int id; }; static const struct ppi PaperInfo[] = { {2100, 2960, 14}, /* A4 */ {1485, 2098, 16}, /* A5 */ {1000, 1480, 18}, /* Postcard */ {1820, 2570, 26}, /* B5 */ {2100, 2790, 14} /* Letter */ }; static void BoundImage(gx_device_printer *, struct bounding *); static long CompressImage(gx_device_printer *, struct bounding *, FILE *, const char *); static int lbp310PrintPage(gx_device_printer *pDev, FILE *fp) { int i; byte Buf[10]; long DataSize; struct bounding Box; BoundImage(pDev, &Box); DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.r"); /* ----==== Set size ====---- */ sprintf(Buf, "0%ld", DataSize); i = (DataSize+strlen(Buf)+1)&1; /* ----==== escape to LIPS ====---- */ fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); fprintf(fp, "\x1bP0J\x1b\\"); return(0); } static int lbp320PrintPage(gx_device_printer *pDev, FILE *fp) { int i; byte Buf[16]; long DataSize; struct bounding Box; BoundImage(pDev, &Box); /* ----==== fix bounding box 4-byte align ====---- */ Box.Left &= ~1; Box.Right |= 1; /* ----==== JOB start ??? ====---- */ fprintf(fp, "\x1b%%-12345X@PJL CJLMODE\n@PJL JOB\n"); DataSize = CompressImage(pDev, &Box, fp, "\x1b[1;%d;%d;11;%d;.&r"); /* ----==== Set size ====---- */ sprintf(Buf, "000%ld", DataSize); i = (DataSize+strlen(Buf)+1)&3; /* ----==== escape to LIPS ====---- */ fprintf(fp, "\x80%s\x80\x80\x80\x80\x0c",Buf+i); fprintf(fp, "\x1bP0J\x1b\\"); fprintf(fp, "\x1b%%-12345X@PJL CJLMODE\n@PJL EOJ\n\x1b%%-12345X"); return(0); } static void BoundImage(gx_device_printer *pDev, struct bounding *pBox) { int x, y, flag; int LineSize = gdev_mem_bytes_per_scan_line((gx_device *)pDev); int Xsize, Ysize, Pt, Pb, Pl, Pr; int Xres = (int)pDev->x_pixels_per_inch, Yres = (int)pDev->y_pixels_per_inch, height = pDev->height; byte *Buf; enum Paper paper; /* ----==== Check parameters ====---- */ paper = height*10/Yres < 82 ? postcard :\ height*10/Yres < 98 ? a5 :\ height*10/Yres < 109 ? b5 :\ height*10/Yres < 116 ? letter : a4; Xsize = Xres * mm_to_inch(PaperInfo[paper].w-100) / 160; Ysize = Yres * mm_to_inch(PaperInfo[paper].h-100) / 10; /* ----==== Allocate momory ====---- */ if (LineSize < Xsize*2+1) { LineSize = Xsize*2+1; } Buf = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 1, LineSize, "LineBuffer"); /* ----==== bounding image ====---- */ Pt = Pb = Pl = Pr = -1; for(y=0 ; y x) { Pl = x; } if (Pr < x) { Pr = x; } flag = 1; } } if (flag) { if (Pt == -1) { Pt = y; } Pb = y; } } pBox->paper = paper; pBox->Top = Pt; pBox->Bottom = Pb; pBox->Left = Pl; pBox->Right = Pr; gs_free(gs_lib_ctx_get_non_gc_memory_t(), Buf, 1, LineSize, "LineBuffer"); } static long CompressImage(gx_device_printer *pDev, struct bounding *pBox, FILE *fp, const char *format) { int x, y, i, count = 255; int Xres = (int)pDev->x_pixels_per_inch; int LineSize = gdev_mem_bytes_per_scan_line((gx_device *)pDev); byte *Buf, oBuf[128], c_prev, c_cur, c_tmp; long DataSize = 0; /* ----==== Printer initialize ====---- */ /* ----==== start TEXT mode ====---- */ fprintf(fp, "\x1b%%@"); /* ----==== job start ====---- */ fprintf(fp, "\x1bP35;%d;1J;GhostScript\x1b\\", Xres); /* ----==== soft reset ====---- */ fprintf(fp, "\x1b<"); /* ----==== select size as dot ====---- */ fprintf(fp, "\x1b[7 I"); /* ----==== ??? ====---- */ fprintf(fp, "\x1b[;1;'v"); /* ----==== set paper size ====---- */ fprintf(fp, "\x1b[%d;;p", PaperInfo[pBox->paper].id); /* ----==== select sheet feeder ====---- */ fprintf(fp, "\x1b[1q"); /* ----==== disable automatic FF ====---- */ fprintf(fp, "\x1b[?2h"); /* ----==== set number of copies ====---- */ fprintf(fp, "\x1b[%dv", 1); /* ----==== move CAP location ====---- */ fprintf(fp, "\x1b[%d;%df", pBox->Top, pBox->Left*16); /* ----==== draw raster image ====---- */ fprintf(fp, format, pBox->Right-pBox->Left+1, Xres, pBox->Bottom-pBox->Top+1); /* ----==== Allocate momory ====---- */ Buf = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 1, LineSize, "LineBuffer"); /* ----==== transfer raster image ====---- */ for (y=pBox->Top ; y<=pBox->Bottom ; y++) { gdev_prn_copy_scan_lines(pDev, y, Buf, LineSize); for (x=pBox->Left*2 ; x<=pBox->Right*2+1 ; x++) { /* ----==== check pointer & Reverse bit order ====---- */ c_cur = 0; if (x> 1; } } /* ----==== Compress data ====---- */ if (count < 0) { if (c_prev == c_cur && count > -127) { count--; continue; } else { fprintf(fp, "%c%c", count, c_prev); DataSize += 2; } } else if (count == 0) { if (c_prev == c_cur) { count--; } else { count++; c_prev = *(oBuf+count) = c_cur; } continue; } else if (count < 127) { if (c_prev == c_cur) { fprintf(fp, "%c", count-1); fwrite(oBuf, 1, count, fp); DataSize += (count+1); count = -1; } else { count++; c_prev = *(oBuf+count) = c_cur; } continue; } else if (count == 127) { fprintf(fp, "%c", count); fwrite(oBuf, 1, count+1, fp); DataSize += (count+2); } c_prev = *oBuf = c_cur; count = 0; } } /* ----==== flush data ====---- */ if (count < 0) { fprintf(fp, "%c%c", count, c_prev); DataSize += 2; } else { fprintf(fp, "%c", count); fwrite(oBuf, 1, count+1, fp); DataSize += (count+2); } gs_free(gs_lib_ctx_get_non_gc_memory_t(), Buf, 1, LineSize, "LineBuffer"); return(DataSize); }