17dd7cddfSDavid du Colombier /* Copyright (C) 1991, 1994, 1996, 1997 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: gdevlbp8.c,v 1.6 2002/10/07 08:28:56 ghostgum Exp $*/
187dd7cddfSDavid du Colombier /* Canon LBP-8II and LIPS III driver */
197dd7cddfSDavid du Colombier #include "gdevprn.h"
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier /*
227dd7cddfSDavid du Colombier Modifications:
237dd7cddfSDavid du Colombier 2.2.97 Lauri Paatero
247dd7cddfSDavid du Colombier Changed CSI command into ESC [. DCS commands may still need to be changed
257dd7cddfSDavid du Colombier (to ESC P).
267dd7cddfSDavid du Colombier 4.9.96 Lauri Paatero
277dd7cddfSDavid du Colombier Corrected LBP-8II margins again. Real problem was that (0,0) is NOT
287dd7cddfSDavid du Colombier in upper left corner.
297dd7cddfSDavid du Colombier Now using relative addressing for vertical addressing. This avoids
307dd7cddfSDavid du Colombier problems
317dd7cddfSDavid du Colombier when printing to paper with wrong size.
327dd7cddfSDavid du Colombier 18.6.96 Lauri Paatero, lauri.paatero@paatero.pp.fi
337dd7cddfSDavid du Colombier Corrected LBP-8II margins.
347dd7cddfSDavid du Colombier Added logic to recognize (and optimize away) long strings of 00's in data.
357dd7cddfSDavid du Colombier For LBP-8II removed use of 8-bit CSI (this does not work if 8-bit character
367dd7cddfSDavid du Colombier set has been configured in LBP-8II. (Perhaps this should also be done
377dd7cddfSDavid du Colombier for LBP-8III?)
387dd7cddfSDavid du Colombier Original versions:
397dd7cddfSDavid du Colombier LBP8 driver: Tom Quinn (trq@prg.oxford.ac.uk)
407dd7cddfSDavid du Colombier LIPS III driver: Kenji Okamoto (okamoto@okamoto.cias.osakafu-u.ac.jp)
417dd7cddfSDavid du Colombier */
427dd7cddfSDavid du Colombier
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier #define X_DPI 300
457dd7cddfSDavid du Colombier #define Y_DPI 300
467dd7cddfSDavid du Colombier #define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8) /* bytes per line */
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier /* The device descriptors */
497dd7cddfSDavid du Colombier private dev_proc_print_page(lbp8_print_page);
507dd7cddfSDavid du Colombier private dev_proc_print_page(lips3_print_page);
517dd7cddfSDavid du Colombier
523ff48bf5SDavid du Colombier const gx_device_printer far_data gs_lbp8_device =
537dd7cddfSDavid du Colombier prn_device(prn_std_procs, "lbp8",
547dd7cddfSDavid du Colombier DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
557dd7cddfSDavid du Colombier X_DPI, Y_DPI,
567dd7cddfSDavid du Colombier 0.16, 0.2, 0.32, 0.21, /* margins: left, bottom, right, top */
577dd7cddfSDavid du Colombier 1, lbp8_print_page);
587dd7cddfSDavid du Colombier
593ff48bf5SDavid du Colombier const gx_device_printer far_data gs_lips3_device =
607dd7cddfSDavid du Colombier prn_device(prn_std_procs, "lips3",
617dd7cddfSDavid du Colombier 82, /* width_10ths, 8.3" */
627dd7cddfSDavid du Colombier 117, /* height_10ths, 11.7" */
637dd7cddfSDavid du Colombier X_DPI, Y_DPI,
647dd7cddfSDavid du Colombier 0.16, 0.27, 0.23, 0.27, /* margins */
657dd7cddfSDavid du Colombier 1, lips3_print_page);
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier /* ------ Internal routines ------ */
687dd7cddfSDavid du Colombier
69*593dc095SDavid du Colombier #define ESC (char)0x1b
70*593dc095SDavid du Colombier #define CSI '\233'
71*593dc095SDavid du Colombier #define DCS '\220'
72*593dc095SDavid du Colombier #define ST '\234'
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier static const char lbp8_init[] = {
757dd7cddfSDavid du Colombier ESC, ';', ESC, 'c', ESC, ';', /* reset, ISO */
767dd7cddfSDavid du Colombier ESC, '[', '2', '&', 'z', /* fullpaint mode */
777dd7cddfSDavid du Colombier ESC, '[', '1', '4', 'p', /* select page type (A4) */
787dd7cddfSDavid du Colombier ESC, '[', '1', '1', 'h', /* set mode */
797dd7cddfSDavid du Colombier ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
807dd7cddfSDavid du Colombier ESC, '[', '6', '3', 'k', /* Move 63 dots up (to top of printable area) */
817dd7cddfSDavid du Colombier };
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier static const char *lbp8_end = NULL;
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier static const char lips3_init[] = {
867dd7cddfSDavid du Colombier ESC, '<', /* soft reset */
877dd7cddfSDavid du Colombier DCS, '0', 'J', ST, /* JOB END */
887dd7cddfSDavid du Colombier DCS, '3', '1', ';', '3', '0', '0', ';', '2', 'J', ST, /* 300dpi, LIPS3 JOB START */
897dd7cddfSDavid du Colombier ESC, '<', /* soft reset */
907dd7cddfSDavid du Colombier DCS, '2', 'y', 'P', 'r', 'i', 'n', 't', 'i', 'n', 'g', '(', 'g', 's', ')', ST, /* Printing (gs) display */
917dd7cddfSDavid du Colombier ESC, '[', '?', '1', 'l', /* auto cr-lf disable */
927dd7cddfSDavid du Colombier ESC, '[', '?', '2', 'h', /* auto ff disable */
937dd7cddfSDavid du Colombier ESC, '[', '1', '1', 'h', /* set mode */
947dd7cddfSDavid du Colombier ESC, '[', '7', ' ', 'I', /* select unit size (300dpi)*/
957dd7cddfSDavid du Colombier ESC, '[', 'f' /* move to home position */
967dd7cddfSDavid du Colombier };
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier static const char lips3_end[] = {
997dd7cddfSDavid du Colombier DCS, '0', 'J', ST /* JOB END */
1007dd7cddfSDavid du Colombier };
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier /* Send the page to the printer. */
1037dd7cddfSDavid du Colombier private int
can_print_page(gx_device_printer * pdev,FILE * prn_stream,const char * init,int init_size,const char * end,int end_size)1047dd7cddfSDavid du Colombier can_print_page(gx_device_printer *pdev, FILE *prn_stream,
1057dd7cddfSDavid du Colombier const char *init, int init_size, const char *end, int end_size)
1067dd7cddfSDavid du Colombier {
1077dd7cddfSDavid du Colombier char data[LINE_SIZE*2];
1087dd7cddfSDavid du Colombier char *out_data;
1097dd7cddfSDavid du Colombier int last_line_nro = 0;
1107dd7cddfSDavid du Colombier
1117dd7cddfSDavid du Colombier fwrite(init, init_size, 1, prn_stream); /* initialize */
1127dd7cddfSDavid du Colombier
1137dd7cddfSDavid du Colombier /* Send each scan line in turn */
1147dd7cddfSDavid du Colombier {
1157dd7cddfSDavid du Colombier int lnum;
1167dd7cddfSDavid du Colombier int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
1177dd7cddfSDavid du Colombier byte rmask = (byte)(0xff << (-pdev->width & 7));
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier for ( lnum = 0; lnum < pdev->height; lnum++ ) {
1207dd7cddfSDavid du Colombier char *end_data = data + LINE_SIZE;
1217dd7cddfSDavid du Colombier gdev_prn_copy_scan_lines(pdev, lnum,
1227dd7cddfSDavid du Colombier (byte *)data, line_size);
1237dd7cddfSDavid du Colombier /* Mask off 1-bits beyond the line width. */
1247dd7cddfSDavid du Colombier end_data[-1] &= rmask;
1257dd7cddfSDavid du Colombier /* Remove trailing 0s. */
1267dd7cddfSDavid du Colombier while ( end_data > data && end_data[-1] == 0 )
1277dd7cddfSDavid du Colombier end_data--;
1287dd7cddfSDavid du Colombier if ( end_data != data ) {
1297dd7cddfSDavid du Colombier int num_cols = 0;
1307dd7cddfSDavid du Colombier int out_count;
1317dd7cddfSDavid du Colombier int zero_count;
1327dd7cddfSDavid du Colombier out_data = data;
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier /* move down */
1357dd7cddfSDavid du Colombier fprintf(prn_stream, "%c[%de",
1367dd7cddfSDavid du Colombier ESC, lnum-last_line_nro );
1377dd7cddfSDavid du Colombier last_line_nro = lnum;
1387dd7cddfSDavid du Colombier
1397dd7cddfSDavid du Colombier while (out_data < end_data) {
1407dd7cddfSDavid du Colombier /* Remove leading 0s*/
1417dd7cddfSDavid du Colombier while(out_data < end_data && *out_data == 0) {
1427dd7cddfSDavid du Colombier num_cols += 8;
1437dd7cddfSDavid du Colombier out_data++;
1447dd7cddfSDavid du Colombier }
1457dd7cddfSDavid du Colombier
1467dd7cddfSDavid du Colombier out_count = end_data - out_data;
1477dd7cddfSDavid du Colombier zero_count = 0;
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier /* if there is a lot data, find if there is sequence of zeros */
1507dd7cddfSDavid du Colombier if (out_count>22) {
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier out_count = 1;
1537dd7cddfSDavid du Colombier
1547dd7cddfSDavid du Colombier while(out_data+out_count+zero_count < end_data) {
1557dd7cddfSDavid du Colombier if (out_data[zero_count+out_count] != 0) {
1567dd7cddfSDavid du Colombier out_count += 1+zero_count;
1577dd7cddfSDavid du Colombier zero_count = 0;
1587dd7cddfSDavid du Colombier }
1597dd7cddfSDavid du Colombier else {
1607dd7cddfSDavid du Colombier zero_count++;
1617dd7cddfSDavid du Colombier if (zero_count>20)
1627dd7cddfSDavid du Colombier break;
1637dd7cddfSDavid du Colombier }
1647dd7cddfSDavid du Colombier }
1657dd7cddfSDavid du Colombier
1667dd7cddfSDavid du Colombier }
1677dd7cddfSDavid du Colombier
1687dd7cddfSDavid du Colombier if (out_count==0)
1697dd7cddfSDavid du Colombier break;
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier /* move down and across*/
1727dd7cddfSDavid du Colombier fprintf(prn_stream, "%c[%d`",
1737dd7cddfSDavid du Colombier ESC, num_cols );
1747dd7cddfSDavid du Colombier /* transfer raster graphic command */
1757dd7cddfSDavid du Colombier fprintf(prn_stream, "%c[%d;%d;300;.r",
1767dd7cddfSDavid du Colombier ESC, out_count, out_count);
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier /* send the row */
1797dd7cddfSDavid du Colombier fwrite(out_data, sizeof(char),
1807dd7cddfSDavid du Colombier out_count, prn_stream);
1817dd7cddfSDavid du Colombier
1827dd7cddfSDavid du Colombier out_data += out_count+zero_count;
1837dd7cddfSDavid du Colombier num_cols += 8*(out_count+zero_count);
1847dd7cddfSDavid du Colombier }
1857dd7cddfSDavid du Colombier }
1867dd7cddfSDavid du Colombier }
1877dd7cddfSDavid du Colombier }
1887dd7cddfSDavid du Colombier
1897dd7cddfSDavid du Colombier /* eject page */
1907dd7cddfSDavid du Colombier fprintf(prn_stream, "%c=", ESC);
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier /* terminate */
1937dd7cddfSDavid du Colombier if (end != NULL)
1947dd7cddfSDavid du Colombier fwrite(end, end_size, 1, prn_stream);
1957dd7cddfSDavid du Colombier
1967dd7cddfSDavid du Colombier return 0;
1977dd7cddfSDavid du Colombier }
1987dd7cddfSDavid du Colombier
1997dd7cddfSDavid du Colombier /* Print an LBP-8 page. */
2007dd7cddfSDavid du Colombier private int
lbp8_print_page(gx_device_printer * pdev,FILE * prn_stream)2017dd7cddfSDavid du Colombier lbp8_print_page(gx_device_printer *pdev, FILE *prn_stream)
2027dd7cddfSDavid du Colombier { return can_print_page(pdev, prn_stream, lbp8_init, sizeof(lbp8_init),
2037dd7cddfSDavid du Colombier lbp8_end, sizeof(lbp8_end));
2047dd7cddfSDavid du Colombier }
2057dd7cddfSDavid du Colombier
2067dd7cddfSDavid du Colombier /* Print a LIPS III page. */
2077dd7cddfSDavid du Colombier private int
lips3_print_page(gx_device_printer * pdev,FILE * prn_stream)2087dd7cddfSDavid du Colombier lips3_print_page(gx_device_printer *pdev, FILE *prn_stream)
2097dd7cddfSDavid du Colombier { return can_print_page(pdev, prn_stream, lips3_init, sizeof(lips3_init),
2107dd7cddfSDavid du Colombier lips3_end, sizeof(lips3_end));
2117dd7cddfSDavid du Colombier }
212