From:     Digestifier <Linux-Development-Request@senator-bedfellow.mit.edu>
To:       Linux-Development@senator-bedfellow.mit.edu
Reply-To: Linux-Development@senator-bedfellow.mit.edu
Date:     Tue, 30 Aug 94 16:13:18 EDT
Subject:  Linux-Development Digest #90

Linux-Development Digest #90, Volume #2          Tue, 30 Aug 94 16:13:18 EDT

Contents:
  BJC600 Driver for GNU gs 2.6.1 (Yves Arrouye)

----------------------------------------------------------------------------

From: arrouye@petole.imag.fr (Yves Arrouye)
Subject: BJC600 Driver for GNU gs 2.6.1
Date: Tue, 30 Aug 1994 09:42:58 GMT

PLEASE READ THE POST "Drivers for Canon BJC 600 available for GNU gs 2.6.1 and  
Aladdin gs 3.0.1" <1994Aug30.094003.17039@imag.fr> FIRST FOR EXPLANATIONS AND
INSTRUCTIONS. THANK YOU.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#       bjc600jp.pch
# This archive created: Tue Aug 30 11:38:48 1994
export PATH; PATH=/bin:$PATH
if test -f 'bjc600jp.pch'
then
        echo shar: will not over-write existing file "'bjc600jp.pch'"
else
cat << \SHAR_EOF > 'bjc600jp.pch'
--- devs.mak.orig       Wed Jun 22 03:29:02 1994
+++ 
@@ -56,6 +56,9 @@
 # *    appledmp  Apple Dot Matrix Printer (should also work with Imagewriter)
 #      bj10e   Canon BubbleJet BJ10e
 # *    bj200   Canon BubbleJet BJ200
+#
+# *    bjc600j   Canon Color BubbleJet BJC-600J
+# *    bjc600jc  Canon Color BubbleJet BJC-600J
 # *    cdeskjet  H-P DeskJet 500C with 1 bit/pixel color
 # *    cdjcolor  H-P DeskJet 500C with 24 bit/pixel color and
 #              high-quality color (Floyd-Steinberg) dithering
@@ -63,6 +66,8 @@
 # *    cdj500  H-P DeskJet 500C (same as cdjcolor)
 # *    cdj550  H-P DeskJet 550C
 # *    declj250  alternate DEC LJ250 driver
+# *    dj505j  H-P DeskJet 505J
+# *    dj505jc  H-P DeskJet 505J Plus
 # +    deskjet  H-P DeskJet and DeskJet Plus
 # *    dfaxhigh  DigiBoard, Inc.'s DigiFAX software format (high resolution)
 # *    dfaxlow  DigiFAX low (normal) resolution
@@ -452,13 +457,25 @@
 pjxl300.dev: $(cdeskjet_)
        $(SHP)gssetdev pjxl300 $(cdeskjet_)
 
+dj505j.dev: $(cdeskjet_)
+       $(SHP)gssetdev dj505j $(cdeskjet_)
+
+dj505jc.dev: $(cdeskjet_)
+       $(SHP)gssetdev dj505jc $(cdeskjet_)
+
+bjc600j.dev: $(cdeskjet_)
+       $(SHP)gssetdev bjc600j $(cdeskjet_)
+
+bjc600jc.dev: $(cdeskjet_)
+       $(SHP)gssetdev bjc600jc $(cdeskjet_)
+
 # NB: you can also customise the build if required, using -DA4 (for A4 paper)
 # and -DBitsPerPixel=<number> if you wish the default to be other than 24
 # for the generic drivers (cdj500, cdj550, pjxl300, pjtest, pjxltest).
 # E.g,. to make A4 paper the default, change the second line below this to
 #      $(CCC) -DA4 gdevdjet.c
 gdevcdj.$(OBJ): gdevcdj.c $(PDEVH) $(gdevpcl_h)
-       $(CCC) gdevcdj.c
+       $(CCC) -DA4 gdevcdj.c
 
 djet500c_=gdevdjtc.$(OBJ) $(HPPCL)
 djet500c.dev: $(djet500c_)
--- gdevcdj.c.orig      Thu May 20 22:14:22 1993
+++ gdevcdj.c   Wed Jun 22 05:26:54 1994
@@ -29,6 +29,11 @@
  ***       please contact g.cameron@biomed.abdn.ac.uk if you have questions.
  ***/
 
+/***
+ ***       dj505j was added to this driver by toyoda@plum.fuis.fukui-u.ac.jp
+ ***       escp, bjc600j was added to this driver by  
yoshio@nak.math.keio.ac.jp
+ ***/
+
 /*
  * Note that there are six drivers contained in this code:
  *
@@ -39,6 +44,10 @@
  *     5 - pjxl:        HP PaintJet XL
  *     6 - declj250:    DEC LJ250
  *
+ *     7 - dj505j:      HP DeskJet 505J
+ *     8 - escp:        ESC/P printers
+ *     9 - bjc600j:     CANON BJC-600
+ *
  * All of these drivers have 8-bit (monochrome), 16-bit and 24-bit
  *     (colour) and for the DJ 550C 32-bit, (colour, cmyk mode)
  *     options in addition to the usual 1-bit and 3-bit modes
@@ -53,6 +62,9 @@
 
 #define DESKJET_PRINT_LIMIT  0.04       /* 'real' top margin? */
 #define PAINTJET_PRINT_LIMIT 0.0        /* This is a guess.. */
+#define DJ505J_PRINT_LIMIT   0.25
+#define ESC_P_PRINT_LIMIT   0.335      /* is factory default (8.5mm),  
minimally 3mm. */
+#define BJC600J_PRINT_LIMIT (2.5/25.4) /* experimental result */
 
 /* Margins are left, bottom, right, top. */
 #define DESKJET_MARGINS_LETTER   0.25, 0.50, 0.25, 0.167
@@ -60,6 +72,23 @@
 #define PAINTJET_MARGINS_LETTER  0.167, 0.167, 0.167, 0.167
 #define PAINTJET_MARGINS_A4      0.167, 0.167, 0.167, 0.167
 #define PAINTJET_MARGINS_A3      0.167, 0.167, 0.167, 0.167
+#define DJ505J_MARGINS_LETTER    0.125, 0.668, 0.125, 0.25  
+#define DJ505J_MARGINS_A4        0.125, 0.668, 0.125, 0.25
+#define BJC600J_MARGINS_LETTER  (3.2/25.4), (11.0/25.4), (3.2/25.4),  
(2.5/25.4)
+#define BJC600J_MARGINS_A4      (3.2/25.4), (11.0/25.4), (3.2/25.4),  
(2.5/25.4)
+/*
+ * With ESC/P commands, BJC-600J can print no more than 8 inches width.
+ * So it can't use full width of letter size paper.  Since non printable
+ * left side area is 0.134 inch, we set up margins as follows.
+ */
+#define ESC_P_MARGINS_LETTER    0.134, 0.276+0.2, 0.366+0.01, 0.335
+#define ESC_P_MARGINS_A4        0.134, 0.276+0.2, 0.166+0.01, 0.335
+
+#define BJ_SIZE_A4 0
+#define BJ_SIZE_B5 1
+#define BJ_SIZE_PC 2
+#define BJ_SIZE_LETTER 3
+#define BJ_SIZE_LEGAL 4
 
 /* Default page size is US-Letter or A4 (other sizes from command line) */
 #ifndef A4
@@ -85,10 +114,16 @@
 #define PJ180    3
 #define PJXL180  4
 #define DECLJ250 5
+#define DJ505J   6
+#define ESC_P    7
+#define BJC600J  (ESC_P+1)
 
 /* No. of ink jets (used to minimise head movements) */
 #define HEAD_ROWS_MONO 50
 #define HEAD_ROWS_COLOUR 16
+/* only for bjc600j (YK) */
+#define BJ_HEAD_ROWS_MONO 64
+#define BJ_HEAD_ROWS_COLOUR 64
 
 /* Colour mapping procedures */
 private dev_proc_map_rgb_color (gdev_pcl_map_rgb_color);
@@ -100,18 +135,33 @@
 private dev_proc_open_device(pjxl300_open);
 private dev_proc_open_device(pjxl_open);
 private dev_proc_open_device(pj_open);
+private dev_proc_open_device(dj505j_open);
+private dev_proc_open_device(escp_open);
+private dev_proc_open_device(bjc600j_open);
 private dev_proc_print_page(dj500c_print_page);
 private dev_proc_print_page(dj550c_print_page);
 private dev_proc_print_page(pjxl_print_page);
 private dev_proc_print_page(pj_print_page);
 private dev_proc_print_page(pjxl300_print_page);
 private dev_proc_print_page(declj250_print_page);
+private dev_proc_print_page(dj505j_print_page);
+private dev_proc_print_page(escp_print_page);
+private dev_proc_print_page(bjc600j_print_page);
+
+/* Add codes later if needed. (YK) */
+#define ep_get_props cdj_get_props
+#define ep_put_props cdj_put_props
+
 private dev_proc_get_props(cdj_get_props);
 private dev_proc_get_props(pjxl_get_props);
 private dev_proc_get_props(pj_get_props);
+private dev_proc_get_props(bj_get_props);
+private dev_proc_get_props(ep_get_props);
 private dev_proc_put_props(cdj_put_props);
 private dev_proc_put_props(pjxl_put_props);
 private dev_proc_put_props(pj_put_props);
+private dev_proc_put_props(bj_put_props);
+private dev_proc_put_props(ep_put_props);
 
 /* The device descriptors */
 typedef struct gx_device_cdj_s gx_device_cdj;
@@ -142,10 +192,26 @@
 
 typedef struct gx_device_hp_s gx_device_pj;
 
+typedef struct gx_device_bj_s gx_device_bj;
+struct gx_device_bj_s {
+        gx_device_common;
+        gx_prn_device_common;
+       int blackemphasis;      /* 0: normal, 1: black emphasis */
+       int draft;              /* 0: normal, 1: draft printing */
+       int color;              /* 0: Transparent */
+                               /* 1: M, 2: C, 4: Y, 7: K (Color decomp) */
+                               /* if > 8, print in black ink. */
+       int thickness;          /* 0: normal, 1: thick paper */
+       int paperkind;          /* 0: normal, 1: coated paper, 2: OHP, 3: BPF  
*/
+       int papersize;          /* 0:a4, 1:b5, 2:postcard, 3:letter, 4:legal  
*/
+       int sheetfeeder;
+};
+
 #define hp_device ((gx_device_hp *)pdev)
 #define cdj       ((gx_device_cdj *)pdev)
 #define pjxl      ((gx_device_pjxl *)pdev)
 #define pj    ((gx_device_pj *)pdev)
+#define bj    ((gx_device_bj *)pdev)
 
 #define prn_hp_colour_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page)\
     prn_device_body(gx_device_printer, procs, dev_name,\
@@ -169,6 +235,11 @@
 { prn_hp_colour_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page), 0\
 }
 
+#define bj_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page, a, b, c, d,  
e, f, g)\
+{ prn_hp_colour_device(procs, dev_name, x_dpi, y_dpi, bpp, print_page),\
+    a, b, c, d, e, f, g\
+}
+
 #define hp_colour_procs(proc_colour_open, proc_get_props, proc_put_props) {\
        proc_colour_open,\
        gdev_pcl_get_initial_matrix,\
@@ -202,6 +273,15 @@
 private gx_device_procs pj_procs =
 hp_colour_procs(pj_open, pj_get_props, pj_put_props);
 
+private gx_device_procs dj505j_procs =
+hp_colour_procs(dj505j_open, cdj_get_props, cdj_put_props);
+
+private gx_device_procs bjc600j_procs =
+hp_colour_procs(bjc600j_open, bj_get_props, bj_put_props);
+
+private gx_device_procs escp_procs =
+hp_colour_procs(escp_open, ep_get_props, ep_put_props);
+
 gx_device_cdj far_data gs_cdjmono_device =
 cdj_device(cdj500_procs, "cdjmono", 300, 300, 1,
           dj500c_print_page, 4, 0, 1);
@@ -238,6 +318,30 @@
 pj_device(pj_procs, "declj250", 180, 180, BITSPERPIXEL,
           declj250_print_page);
 
+gx_device_cdj far_data gs_dj505j_device =
+cdj_device(dj505j_procs, "dj505j", 300, 300, 8,
+          dj505j_print_page, 4, 0, 1);
+
+gx_device_cdj far_data gs_dj505jc_device =
+cdj_device(dj505j_procs, "dj505jc", 300, 300, BITSPERPIXEL,
+          dj505j_print_page, 4, 2, 1);
+
+gx_device_cdj far_data gs_escp_device =
+cdj_device(escp_procs, "escp", 360, 360, 8,
+          escp_print_page, 0, 0, 1);
+
+gx_device_cdj far_data gs_escpc_device =
+cdj_device(escp_procs, "escpc", 360, 360, 32,
+          escp_print_page, 0, 0, 1);
+
+gx_device_bj far_data gs_bjc600j_device =
+bj_device(bjc600j_procs, "bjc600j", 360, 360, 8,
+          bjc600j_print_page, 0, 0, 0, 0, 0, 0, 0);
+
+gx_device_bj far_data gs_bjc600jc_device =
+bj_device(bjc600j_procs, "bjc600jc", 360, 360, 32,
+          bjc600j_print_page, 0, 0, 0, 0, 0, 0, 0);
+
 /* Forward references */
 private int gdev_pcl_mode1compress(P3(const byte *, const byte *, byte *));
 private int gdev_pcl_mode9compress(P4(int, const byte *, const byte *, byte  
*));
@@ -247,6 +351,7 @@
 private uint gdev_prn_rasterwidth(P2(const gx_device_printer *, int));
 private void set_bpp(P2(gx_device *, int));
 private void expand_line(P4(word *, int, int, int));
+private bj_paper_size();
 
 /* Open the printer and set up the margins. */
 private int
@@ -275,6 +380,21 @@
 }
 
 private int
+dj505j_open(gx_device *pdev)
+{ return hp_colour_open(pdev, DJ505J);
+}
+
+private int
+escp_open(gx_device *pdev)
+{ return hp_colour_open(pdev, ESC_P);
+}
+
+private int
+bjc600j_open(gx_device *pdev)
+{ return hp_colour_open(pdev, BJC600J);
+}
+
+private int
 hp_colour_open(gx_device *pdev, int ptype)
 {       /* Change the margins if necessary. */
   static const float pj_a4[4] = { PAINTJET_MARGINS_A4 };
@@ -282,6 +402,12 @@
   static const float pj_letter[4] = { PAINTJET_MARGINS_LETTER };
   static const float dj_a4[4] = { DESKJET_MARGINS_A4 };
   static const float dj_letter[4] = { DESKJET_MARGINS_LETTER };
+  static const float djj_a4[4] = { DJ505J_MARGINS_A4 };
+  static const float djj_letter[4] = { DJ505J_MARGINS_LETTER };
+  static const float ep_a4[4] = { ESC_P_MARGINS_A4 };
+  static const float ep_letter[4] = { ESC_P_MARGINS_LETTER };
+  static const float bj_a4[4] = { BJC600J_MARGINS_A4 };
+  static const float bj_letter[4] = { BJC600J_MARGINS_LETTER };
   const float _ds *m;
   int psize;
 
@@ -304,6 +430,36 @@
     m = ((psize = gdev_pcl_paper_size(pdev)) == PAPER_SIZE_A4 ? pj_a4 :
         (psize == PAPER_SIZE_A3) ? pj_a3 : pj_letter);
     break;
+  case DJ505J:
+    m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? djj_a4 :
+        djj_letter);
+    break;
+  case ESC_P:
+    m = (gdev_pcl_paper_size(pdev) == PAPER_SIZE_A4 ? ep_a4 :
+        ep_letter);
+    break;
+  case BJC600J:
+    switch ((psize = bj_paper_size(pdev))) {
+    case BJ_SIZE_A4:
+      m = bj_a4;
+      break;
+    case BJ_SIZE_B5:
+      m = bj_a4;
+      break;
+    case BJ_SIZE_PC:
+      m = bj_a4;
+      break;
+    case BJ_SIZE_LETTER:
+      m = bj_letter;
+      break;
+    case BJ_SIZE_LEGAL:
+      m = bj_letter;
+      break;
+    default:
+      m = bj_a4;
+    }
+    bj->papersize = psize;
+    break;
   }
   pdev->l_margin = m[0];
   pdev->b_margin = m[1];
@@ -486,6 +642,73 @@
        return code;
 }
 
+private const gs_prop_item props_bj[] = {
+  /* Read-write properties. */
+  prop_def("BitsPerPixel", prt_int),
+  prop_def("BJblackemphasis", prt_int),
+  prop_def("BJdraft", prt_int),
+  prop_def("BJcolor", prt_int),
+  prop_def("BJthickness", prt_int),
+  prop_def("BJpaperkind", prt_int),
+  prop_def("BJpapersize", prt_int), /* Not used yet */
+  prop_def("BJsheetfeeder", prt_int), /* Not used yet */
+};
+
+private int
+bj_get_props(gx_device *pdev, gs_prop_item *plist)
+{      int start = gdev_prn_get_props(pdev, plist);
+       if ( plist != 0 )
+          {    register gs_prop_item *pi = plist + start;
+               memcpy(pi, props_bj, sizeof(props_bj));
+               pi[0].value.i = bj->color_info.depth;
+               pi[1].value.i = bj->blackemphasis;
+               pi[2].value.i = bj->draft;
+               pi[3].value.i = bj->color;
+               pi[4].value.i = bj->thickness;
+               pi[5].value.i = bj->paperkind;
+               pi[6].value.i = bj->papersize;
+               pi[7].value.i = bj->sheetfeeder;
+          }
+       return start + sizeof(props_bj) / sizeof(gs_prop_item);
+}
+
+/* Put properties. */
+private int
+bj_put_props(gx_device *pdev, gs_prop_item *plist, int count)
+{      gs_prop_item *known[8];
+       int old_bpp = bj->color_info.depth;
+       int bpp = 0;
+       int code = 0;
+
+       props_extract(plist, count, props_bj, 8, known, 0);
+       code = gdev_prn_put_props(pdev, plist, count);
+       if ( code < 0 ) return code;
+
+       code = put_prop_int(known[0], &bpp, 1, 32, code);
+       code = put_prop_int(known[1], &bj->blackemphasis, 0, 1, code);
+       code = put_prop_int(known[2], &bj->draft, 0, 1, code);
+       code = put_prop_int(known[3], &bj->color, 0, 15, code);
+       code = put_prop_int(known[4], &bj->thickness, 0, 1, code);
+       code = put_prop_int(known[5], &bj->paperkind, 0, 3, code);
+       code = put_prop_int(known[6], &bj->papersize, 0, 4, code);
+       code = put_prop_int(known[7], &bj->sheetfeeder, 1, 3, code);
+
+       if ( code < 0 )
+         return_error(code);
+
+       if (bpp != 0) {
+         set_bpp(pdev, bpp);
+         
+         /* Close the device; gs_putdeviceprops will reopen it. */
+         if ( bpp != old_bpp && pdev->is_open )
+           { int ccode = gs_closedevice(pdev);
+             if ( ccode < 0 ) return ccode;
+           }
+       }
+       
+       return code;
+}
+
 /* ------ Internal routines ------ */
 
 /* The DeskJet500C can compress (mode 9) */
@@ -538,6 +761,27 @@
   return ret_code;
 }
 
+/* The DeskJet505J can compress (mode 2) */
+private int
+dj505j_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+  return hp_colour_print_page(pdev, prn_stream, DJ505J);
+}
+
+/* The BJC-600J cannot compress w/o raster image commands. */
+private int
+escp_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+  return hp_colour_print_page(pdev, prn_stream, ESC_P);
+}
+
+/* The BJC-600J can compress w/ raster image commands. */
+private int
+bjc600j_print_page(gx_device_printer * pdev, FILE * prn_stream)
+{
+  return hp_colour_print_page(pdev, prn_stream, BJC600J);
+}
+
 /* MACROS FOR DITHERING (we use macros for compact source and faster code) */
 /* Floyd-Steinberg dithering. Often results in a dramatic improvement in
  * subjective image quality, but can also produce dramatic increases in
@@ -641,6 +885,366 @@
 /* To calculate buffer size as next greater multiple of both parameter and W  
*/
 #define calc_buffsize(a, b) (((((a) + ((b) * W) - 1) / ((b) * W))) * W)
 
+/*
+ * Miscellaneous functions for Canon BJC-600J printers in raster command  
mode.
+ */
+#define fputshort(n, f) fputc((n)%256,f);fputc((n)/256,f)
+private
+int bj_paper_size(gx_device *dev)
+{      return
+         (dev->height / dev->y_pixels_per_inch >= 11.8 ? BJ_SIZE_LEGAL :
+          dev->height / dev->y_pixels_per_inch >= 11.1 ? BJ_SIZE_A4 :
+          dev->height / dev->y_pixels_per_inch >= 10.0 ? BJ_SIZE_LETTER :
+          dev->height / dev->y_pixels_per_inch >= 6.0 ? BJ_SIZE_B5 :
+          BJ_SIZE_PC
+          );
+}
+
+private
+bj_cmd(cmd, argsize, arg, pdev, stream)
+byte cmd;
+int argsize;
+byte *arg;
+gx_device_printer *pdev;
+FILE *stream;
+{
+  fputs("\033(", stream);
+  putc(cmd, stream);
+  fputshort(argsize, stream);
+  fwrite(arg, sizeof(byte), argsize, stream);
+}
+
+private
+bj_raster_cmd_sub(c, rastsize, data, stream)
+char c;
+int rastsize;
+byte *data;
+FILE *stream;
+{
+  fputs("\033(A", stream);
+  fputshort(rastsize+1, stream);
+  putc(c, stream);
+  fwrite(data, sizeof(byte), rastsize, stream);
+  putc('\015', stream);
+}
+
+private
+bj_raster_cmd(c_id, rastsize, data, pdev, stream)
+int c_id;
+int rastsize;
+byte *data;
+gx_device_printer *pdev;
+FILE *stream;
+{
+  char c;
+
+  if (pdev->color_info.num_components == 1) {
+    if (bj->color == 0) {
+      bj_raster_cmd_sub('K', rastsize, data, stream);
+    } else {
+      if (bj->color == 7) bj_raster_cmd_sub('K', rastsize, data, stream);
+      else {
+       if (bj->color & 1) bj_raster_cmd_sub('M', rastsize, data, stream);
+       if (bj->color & 2) bj_raster_cmd_sub('C', rastsize, data, stream);
+       if (bj->color & 4) bj_raster_cmd_sub('Y', rastsize, data, stream);
+      }
+    }
+  } else if (bj->color == 0) {
+    bj_raster_cmd_sub("YMCK"[c_id], rastsize, data, stream);
+  } else {                     /* Color decomposition */
+    if (bj->color & (int)"\004\001\002\010"[c_id]) {
+      if (bj->color & 010) bj_raster_cmd_sub('K', rastsize, data, stream);
+      else bj_raster_cmd_sub("YMCK"[c_id], rastsize, data, stream);
+    }
+  }
+}
+
+private
+bj_init_page(pdev, stream)
+gx_device_printer *pdev;
+FILE *stream;
+{
+  char papersize[3], resolution[2], param_c[3], param_l[2];
+
+  papersize[0] = (int)(pdev->height / pdev->y_pixels_per_inch * 10);
+  papersize[1] =  1;
+  papersize[2] = (int)(pdev->width / pdev->x_pixels_per_inch * 10);
+
+  resolution[0] = (int)pdev->x_pixels_per_inch / 256;
+  resolution[1] = (int)pdev->x_pixels_per_inch % 256;
+
+  param_c[0] = 0x10;
+  param_c[1] = bj->draft ? 2 : (bj->paperkind << 4) + 1;
+  param_c[2] = (bj->blackemphasis << 4) + bj->thickness;
+
+  param_l[0] = 0x14;
+  param_l[1] = (bj->paperkind > 2 ? 2 : bj->paperkind) << 4;
+
+/*  fputs("\033~Z", stream); fputshort(1, stream); putc(1, stream);*/
+  fputs("\033[K", stream); fputshort(2, stream); putc(0, stream); putc(15,  
stream);
+  bj_cmd('a', 1, "\001", pdev, stream);
+  bj_cmd('b', 1, "\001", pdev, stream);
+  bj_cmd('d', 2, resolution, pdev, stream);
+  bj_cmd('c', 3, param_c, pdev, stream);
+  bj_cmd('l', 2, param_l, pdev, stream);
+  bj_cmd('g', 3, papersize, pdev, stream);
+}
+
+private
+bj_v_skip(n, pdev, stream)
+int n;
+gx_device_printer *pdev;
+FILE *stream;
+{
+  if (n) {
+    fputs("\033(e", stream);
+    putc(2, stream);
+    putc(0, stream);
+    putc(n/256, stream);
+    putc(n%256, stream);
+  }
+}
+
+private
+bj_finish_page(pdev, stream)
+gx_device_printer *pdev;
+FILE *stream;
+{
+  bj_cmd('b', 1, "\000", pdev, stream);
+  bj_cmd('a', 1, "\000", pdev, stream);
+  fputs("\033@", stream);
+}
+
+/* 1D runlength compression for BJC-600J
+ * this code is borrowed from gdevpcl.c:gdev_pcl_mode2compress.
+ */
+private
+bj_compress(const byte *row, const byte *end_row, byte *compressed)
+{
+  register const byte *exam = row;
+  register byte *cptr = compressed; /* output pointer into compressed bytes  
*/
+  
+  while ( exam < end_row ) {
+    /* Search ahead in the input looking for a run */
+    /* of at least 4 identical bytes. */
+    const byte *compr = exam;
+    const byte *end_dis;
+    const byte *next;
+    register byte test, test2;
+    register word testw;
+    
+    test = *exam;
+    while ( exam < end_row ) {
+      test2 = *++exam;
+      if ( test == test2 )
+         break;
+      test = test2;
+    }
+    
+    /* Find out how long the run is */
+    end_dis = exam - 1;
+    if ( exam == end_row ) { /* no run */
+      next = --end_row;
+    } else { 
+      next = exam + 1;
+      while ( next < end_row && *next == test ) next++;
+    }
+    
+    /* Now [compr..end_dis) should be encoded as dissimilar, */
+    /* and [end_dis..next) should be encoded as similar. */
+    /* Note that either of these ranges may be empty. */
+    
+    for ( ; ; ) {      /* Encode up to 128 dissimilar bytes */
+      uint count = end_dis - compr; /* uint for faster switch */
+      switch ( count ) { /* Use memcpy only if it's worthwhile. */
+      case 6: cptr[6] = compr[5];
+      case 5: cptr[5] = compr[4];
+      case 4: cptr[4] = compr[3];
+      case 3: cptr[3] = compr[2];
+      case 2: cptr[2] = compr[1];
+      case 1: cptr[1] = compr[0];
+       *cptr = count - 1;
+       cptr += count + 1;
+      case 0: /* all done */
+       break;
+      default:
+       if ( count > 128 ) count = 128;
+       *cptr++ = count - 1;
+       memcpy(cptr, compr, count);
+       cptr += count, compr += count;
+       continue;
+      }
+      break;
+    }
+    
+    {  /* Encode up to 128 similar bytes. */
+      /* Note that count may be <0 at end of row. */
+      int count = next - end_dis;
+      if (next < end_row || test != 0)
+       while ( count > 0 ) { 
+         int this = (count > 128 ? 128 : count);
+         *cptr++ = 257 - this;
+         *cptr++ = (byte)test;
+         count -= this;
+       }
+      exam = next;
+    }
+  }
+  return cptr - compressed;
+}
+
+/*
+ * Canon BJC-600J features BJ raster image commands but currently not opened  
to
+ * public.  So we should transform raster image to serial printer image.
+ * Currently, resolution is fixed as 360dpi.
+ */
+private word *ep_storage;
+private uint ep_storage_size_words;
+private byte *ep_raster_buf[4][BJ_HEAD_ROWS_COLOUR], *ep_print_buf;
+private int ep_num_comps, ep_plane_size, img_rows=BJ_HEAD_ROWS_COLOUR;
+
+#define row_bytes (img_rows / 8)
+#define row_words (row_bytes / sizeof(word))
+#define min_rows (32)          /* for optimization of text image printing */
+
+private int
+ep_print_image(FILE *prn_stream, char cmd, byte *data, int size)
+{
+  static int ln_idx=0, vskip1=0, vskip2=0, real_rows;
+  int i;
+  static const char color[4] = {4,1,2,0};
+
+  switch (cmd) {
+  case 3:                      /* Black */
+  case 2:                      /* Cyan */
+  case 1:                      /* Magenta */
+  case 0:                      /* Yellow */
+    memcpy(ep_raster_buf[cmd][ln_idx+vskip2], data, size);
+    return 0;
+    break;
+  case 'B':                    /* blank line skip */
+    if (!ln_idx) {
+      vskip1 += size;
+    } else if (size >= img_rows - (ln_idx+vskip2) || ln_idx+vskip2 >=  
min_rows) {
+      /* The 'I' cmd must precede 'B' cmd! */
+      vskip2 += size;
+      ep_print_image(prn_stream, 'F', 0, 0); /* flush and reset status */
+    } else {
+      vskip2 += size;
+    }
+    return 0;
+    break;
+  case 'I':                    /* Increment index */
+    ln_idx += vskip2 + 1;
+    vskip2 = 0;
+    if (ln_idx < img_rows) return 0;
+    /* if ep_raster_buf filled up, then fall through here and flush buffer */
+  case 'F':                    /* flush print buffer */
+    if (!ln_idx) return 0;     /* The end of the page. */
+
+    /* before print the image, perform vertical skip. */
+    while (vskip1 >= (255*2)) {
+      fputs("\033J\377", prn_stream); /* n/180in. feeding */
+      vskip1 -= (255*2);
+    }
+    if (vskip1 > 255) {
+      fputs("\033J\200", prn_stream);
+      vskip1 -= 256;
+    }
+    if (vskip1) {
+      /* n/360in. feeding */
+      fputs("\033|J", prn_stream); putc(0, prn_stream); putc(vskip1,  
prn_stream);
+    }
+
+    /* Optimize the number of nozzles to be used. */
+    if (ln_idx > 56) {         /* use 64 nozzles */
+      real_rows = 64;
+    } else if (ln_idx > 48) {  /* use 56 nozzles */
+      real_rows = 56;
+    } else if (ln_idx > 32) {  /* use 48 nozzles */
+      real_rows = 48;
+    } else {                   /* use 32 nozzles */
+      real_rows = 32;
+    }
+
+    for (i = 0; i < ep_num_comps; i++) {
+      int lnum, hskip, print_size, img_rows;
+      byte *p0, *p1, *p2, *p3;
+      byte *inp, *inbuf, *outp, *outbuf;
+
+      img_rows = real_rows;    /* Note that this img_rows is not the one that
+                                * defined out of this function. */
+      outbuf = ep_print_buf;
+
+      /* Transpose raster image for serial printer image */
+      for (lnum=0; lnum < img_rows; lnum+=8, outbuf++) {
+       inbuf = inp = ep_raster_buf[i][lnum];
+       for (outp = outbuf; inp < inbuf+ep_plane_size; inp++, outp +=  
img_rows) {
+         memflip8x8(inp, ep_plane_size, outp, row_bytes);
+       }
+      }
+
+      /* Set color */
+      if (ep_num_comps == 1) {
+       /* Don't set color (to enable user setting). */
+       putc('\015', prn_stream);
+      } else {
+       /* set color to one of CMYK. */
+       fputs("\015\033r", prn_stream);
+       putc(color[i], prn_stream);
+      }
+
+      *(outp = ep_print_buf + ep_plane_size * img_rows) = 1; /* sentinel */
+
+      p0 = p3 = ep_print_buf;
+
+      /* print image p0 to p1 and h skip p1 to p2 if p2<outp,
+       * then make p0=p2 and continue */
+      while (p0 < outp) {
+       word zeros[8] = {0,0,0,0,0,0,0,0};
+
+       if (p3 < outp) {
+         /* p1 is the head of running zeros. */
+         /* note that h skip unit is 1/180inch */
+         for (p1 = p3; !memcmp(p3, zeros, row_bytes*2); p3 += row_bytes*2);
+         /* p2 is the head of non zero image. */
+         p2 = p3;
+       redo:
+         for (p3 += row_bytes; memcmp(p3, zeros, row_bytes); p3 +=  
row_bytes);
+         if (p3 < outp && memcmp(p3+row_bytes, zeros, row_bytes)) goto redo;
+       } else p1 = p2 = outp;
+
+       if (p0 < p1) {  /* print the image between p0 and p1 */
+         print_size = ((p1 < outp) ? p1 : outp) - p0;
+         fputs("\033|B", prn_stream); putc(img_rows, prn_stream);
+         fputshort(print_size, prn_stream);
+         fwrite(p0, sizeof(byte), print_size, prn_stream);
+       }
+       if (p1 < p2) {  /* skip running zeros from p1 to p2 */
+         hskip = (((p2 < outp) ? p2 : outp) - p1) / row_bytes / 2;
+         fputs("\033\\", prn_stream);
+         fputshort(hskip, prn_stream);
+       }
+       p0 = p2;
+      }
+    }
+    return ep_print_image(prn_stream, 'R', 0, vskip2 + ln_idx);        /*  
Reset status */
+    break;
+  case 'R':                    /* Reset status */
+    ln_idx = 0;
+    vskip1 = size;
+    vskip2 = 0;
+    memset(ep_storage, 0, ep_storage_size_words * W);
+    return 0;
+    break;
+  default:                     /* This should not happen */
+    fprintf(stderr, "ep_print_image: illegal command character `%c'.\n",  
cmd);
+    return 1;
+  }
+
+  /* NOT REACHED */
+}
+
 /* Send the page to the printer.  Compress each scan line. */
 private int
 hp_colour_print_page(gx_device_printer * pdev, FILE * prn_stream, int ptype)
@@ -673,6 +1277,13 @@
     if (num_comps == 3)
       num_comps = 4;                      /* 4-component printing */
     break;
+  case ESC_P:
+  case BJC600J:
+    if (bits_per_pixel == 24)  /* prefer 3-component printing for bpp=24. */
+      num_comps = 3;
+    else if (num_comps != 1)
+      num_comps = 4;
+    break;
   case PJXL300:
   case PJXL180:
     if (pjxl->rendertype > 0) {
@@ -693,6 +1304,7 @@
     bits_per_pixel = expanded_bpp = 3;  /* Only 3 bits of each byte used */
 
   plane_size = calc_buffsize(line_size, storage_bpp);
+  ep_plane_size = plane_size;
 
   if (bits_per_pixel == 1) {            /* Data printed direct from i/p */
     databuff_size = 0;                  /* so no data buffer required, */
@@ -712,6 +1324,9 @@
                        databuff_size + errbuff_size + outbuff_size) / W;
 
   storage = (ulong *) gs_malloc(storage_size_words, W,  
"hp_colour_print_page");
+  ep_storage_size_words = (plane_size * (num_comps + 1)) / W * img_rows
+      + 16;                    /* Redundant space for sentinel and aligning.  
*/
+  ep_storage = (word *) gs_malloc(ep_storage_size_words, W,  
"ep_print_buffer");
 
   /*
    * The principal data pointers are stored as pairs of values, with
@@ -727,11 +1342,12 @@
    *   plane_data:  4  (scan direction and alternating buffers)
    */
 
-  if (storage == 0)            /* can't allocate working area */
+  if (storage == 0 || ep_storage == 0) /* can't allocate working area */
     return_error(gs_error_VMerror);
   else {
-    int i;
-    byte *p = out_data = out_row = (byte *)storage;    
+    int i, j;
+    byte *p = out_data = out_row = (byte *)storage;
+    byte *ep_p = (byte *)ep_storage;
     data[0] = data[1] = data[2] = p;
     data[3] = p + databuff_size;
     out_row_alt = out_row + plane_size * 2;
@@ -758,18 +1374,42 @@
       data[1] += databuff_size;   /* coincides with plane_data pointers */
       data[3] += databuff_size;
     }
+    for (i = 0; i < num_comps; i++) {
+      for (j = 0; j < img_rows; j++) {
+       ep_raster_buf[i][j] = ep_p;
+       ep_p += plane_size;
+      }
+      /* Make a sentinel and align to word size.  */
+      ep_print_buf = (byte *)((word)(ep_p + sizeof(word)) &  
~(sizeof(word)-1));
+    }
+    ep_num_comps = num_comps;
   }
   
   /* Clear temp storage */
   memset(storage, 0, storage_size_words * W);
   
   /* Initialize printer. */
-  fputs("\033E", prn_stream);                     /* Reset printer */
-  fputs("\033*rbC", prn_stream);                   /* End raster graphics */
-  fprintf(prn_stream, "\033*t%dR", (int)x_dpi);           /* Set resolution  
*/
+  if (ptype == DJ505J) {
+    fputs("\x1B@", prn_stream);                      /* Reset printer */
+    fputs("\x1B_C", prn_stream);                     /* End raster graphics  
*/
+    fprintf(prn_stream, "\x1B_R%c%c",
+            ((int)x_dpi) % 256, ((int)x_dpi) / 256); /* Set resolution */
+  } else if (ptype == ESC_P) {
+      fputs("\033@", prn_stream); /* Reset printer */
+      ep_print_image(prn_stream, 'R', 0, 0); /* reset output routine */
+  } if (ptype == BJC600J) {
+    bj_init_page(pdev, prn_stream);
+  } else {
+    fputs("\033E", prn_stream);                             /* Reset printer  
*/
+    fputs("\033*rbC", prn_stream);                   /* End raster graphics  
*/
+    fprintf(prn_stream, "\033*t%dR", (int)x_dpi);    /* Set resolution */
+  }
 
 #define DOFFSET (pdev->t_margin - DESKJET_PRINT_LIMIT)  /* Print position */
 #define POFFSET (pdev->t_margin - PAINTJET_PRINT_LIMIT)
+#define JOFFSET (pdev->t_margin - DJ505J_PRINT_LIMIT)
+#define EOFFSET (pdev->t_margin - ESC_P_PRINT_LIMIT)
+#define BOFFSET (pdev->t_margin - BJC600J_PRINT_LIMIT)
   switch (ptype) {
   case DJ500C:
   case DJ550C:
@@ -849,6 +1489,38 @@
     /* Select data compression */
     compression = 1;
     break;
+  case DJ505J:
+    {
+      int neg_comps = num_comps * (-1);
+
+      /* Set depletion and shingling levels */
+      fprintf(prn_stream, "\x1B_D%c\x1B_E%c", cdj->depletion,  
cdj->shingling);
+      /* Move to top left of printed area */
+      fprintf(prn_stream, "\x1B_N%c", (int)(300 * JOFFSET));
+      /* Set number of planes ((-)1 is mono, (-)3 is (cmy)rgb */
+      fprintf(prn_stream, "\x1B_U%c%c",
+           (*(unsigned int *)&neg_comps) % 256,
+           (*(unsigned int *)&neg_comps) / 256);
+      /* Set raster width, then start raster graphics */
+      fprintf(prn_stream, "\x1B_S%c%c\x1B_A\x01",
+             raster_width % 256, raster_width / 256 );
+      /* Select data compression */
+      compression = 2;
+      /* No combined escapes for raster transfers */
+      combined_escapes = 0;
+    }
+    break;
+  case ESC_P:
+    /* Move to top left of printed area (must be modified for large  
movement(YK))*/
+    if ((int)(EOFFSET*360)) fprintf(prn_stream, "\033|J%c%c", 0,  
(int)(360*EOFFSET));
+    combined_escapes = 0;
+    break;
+  case BJC600J:
+    /* Move to top left of printed area */
+    bj_v_skip((int)(360*BOFFSET), pdev, prn_stream);
+    combined_escapes = 0;
+    compression = 2;           /* BJC600J uses the same method as mode 2  
compression */
+    break;
   }
 
   /* The XL300 PCL interpreter seems to be based on a rather old definition
@@ -869,8 +1541,13 @@
      /* Set compression if the mode has been defined. */
     if (compression)
       fprintf(prn_stream, "%dm", compression);
-  } else
+  } else if (ptype == DJ505J)
     if (compression)
+      fprintf(prn_stream, "\x1B_M%c", compression);
+  else if (ptype == BJC600J)
+      ;                                /* Currently, nothing to do. */
+  else
+    if (compression)
       fprintf(prn_stream, "\033*b%dM", compression);
 
   /* Send each scan line in turn */
@@ -915,7 +1592,11 @@
       }
       /* Skip blank lines if any */
       if (num_blank_lines > 0) {
-       if (num_blank_lines < this_pass) {
+       if (ptype == ESC_P) {
+         ep_print_image(prn_stream, 'B', 0, num_blank_lines);
+       } else if (ptype == BJC600J) {
+           bj_v_skip(num_blank_lines, pdev, prn_stream);
+       } else if (num_blank_lines < this_pass) {
          /* Moving down from current position
           * causes head motion on the DeskJets, so
           * if the number of lines is within the
@@ -926,6 +1607,9 @@
            fputc('y', prn_stream);   /* Clear current and seed rows */
            for (; num_blank_lines; num_blank_lines--)
              fputc('w', prn_stream);
+         } else if (ptype == DJ505J) {
+           for (; num_blank_lines; num_blank_lines--)
+             fprintf(prn_stream, "\x1B_W%c%c", 0, 0);
          } else {
            fputs("\033*bY", prn_stream);   /* Clear current and seed rows */
            for (; num_blank_lines; num_blank_lines--)
@@ -934,8 +1618,11 @@
        } else {
          if (combined_escapes)
            fprintf(prn_stream, "%dy", num_blank_lines);
-         else
-           fprintf(prn_stream, "\033*b%dY", num_blank_lines);
+         else if (ptype == DJ505J)
+           fprintf(prn_stream, "\x1B_Y%c%c",
+                   num_blank_lines % 256, num_blank_lines / 256);
+         else 
+             fprintf(prn_stream, "\033*b%dY", num_blank_lines);
        }
        memset(plane_data[1 - scan][0], 0, plane_size * num_comps);
        num_blank_lines = 0;
@@ -1112,16 +1799,49 @@
                }
            }
            break;
+         case DJ505J:
+           { const char *plane = (char *)plane_data[scan][i];
+             const word *row = (word *)plane;
+             const word *end_row = row + plane_size/W;
+             int count2 = gdev_pcl_mode2compress(row, end_row, out_row_alt);
+
+             out_data = out_row_alt;
+             out_count = count2;
+           }
+           break;
+         case BJC600J:
+           { const byte *plane = (byte *)plane_data[scan][i];
+             const word *row = (word *)plane;
+             const word *end_row = row + plane_size/W;
+             int count2 = bj_compress(plane, plane + plane_size,  
out_row_alt);
+
+             out_data = out_row_alt;
+             out_count = count2;
+           }
+           break;
          }
          if (output_plane) {
            if (combined_escapes)
              fprintf(prn_stream, "%d%c", out_count, "wvvv"[i]);
+           else if (ptype == DJ505J)
+             fprintf(prn_stream, "\x1B_%c%c%c", "WVVV"[i],
+                     out_count % 256, out_count / 256);
+           else if (ptype == BJC600J) {
+             if (out_count)
+                 bj_raster_cmd(num_comps == 1 ? 3 : i,
+                               out_count, out_data, pdev, prn_stream);
+             if (i == 0) bj_v_skip(1, pdev, prn_stream);
+           } else if (ptype == ESC_P)
+               ep_print_image(prn_stream, i, plane_data[scan][i],  
plane_size);
            else
              fprintf(prn_stream, "\033*b%d%c", out_count, "WVVV"[i]);
-           fwrite(out_data, sizeof(byte), out_count, prn_stream);
+           if (ptype < ESC_P)
+               fwrite(out_data, sizeof(byte), out_count, prn_stream);
          }
          
        } /* Transfer Raster Graphics ... */
+       if (ptype == ESC_P)
+           ep_print_image(prn_stream, 'I', 0, 0); /* increment line index */
        scan = 1 - scan;          /* toggle scan direction */
       }          /* Printing non-blank lines */
     }     /* for lnum ... */
@@ -1131,15 +1851,28 @@
     fputs("0M", prn_stream);
 
   /* end raster graphics & reset printer */
-  fputs("\033*rbC\033E", prn_stream);
+  if (ptype == DJ505J)
+    fputs("\x1B_C",prn_stream);                /* not reset yet */
+  else if (ptype == BJC600J)
+      bj_finish_page(pdev, prn_stream);
+  else if (ptype != ESC_P) 
+    fputs("\033*rbC\033E", prn_stream);
 
   /* eject page */
   if (ptype == PJ180)
     fputc('\f', prn_stream);
-  else
+  else if (ptype == DJ505J)
+    fputs("\x0C\x1B@", prn_stream);    /* reset after eject page */
+  else if (ptype == BJC600J)
+      ;                                /* Currently, nothing to do */
+  else if (ptype == ESC_P) {
+    ep_print_image(prn_stream, 'F', 0, 0); /* flush print buffer */
+    fputs("\014\033@", prn_stream);    /* reset after eject page */
+  } else 
     fputs("\033&l0H", prn_stream);
 
   /* free temporary storage */
+  gs_free((char *) ep_storage, ep_storage_size_words, W, "ep_print_buffer");
   gs_free((char *) storage, storage_size_words, W, "hp_colour_print_page");
 
   return 0;
SHAR_EOF
fi # end of overwriting check
#       End of shell archive
exit 0


--
Advocates for the C++ school claim that a well designed           Yves Arrouye
    program does not need the extra flexibility (a lie),  Yves.Arrouye@imag.fr
while advocates for the Objective-C school claim that         (33) 76 57 48 64
    the errors are no problem in practice (another lie).             NeXT Mail

------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: Linux-Development-Request@NEWS-DIGESTS.MIT.EDU

You can send mail to the entire list (and comp.os.linux.development) via:

    Internet: Linux-Development@NEWS-DIGESTS.MIT.EDU

Linux may be obtained via one of these FTP sites:
    nic.funet.fi				pub/OS/Linux
    tsx-11.mit.edu				pub/linux
    sunsite.unc.edu				pub/Linux

End of Linux-Development Digest
******************************
