80
77
/* Send the page to the printer. */
82
79
sj48_print_page(gx_device_printer *pdev, FILE *prn_stream)
83
80
{ int line_size = gx_device_raster((gx_device *)pdev, 0);
84
int xres = pdev->x_pixels_per_inch;
85
int yres = pdev->y_pixels_per_inch;
86
int mode = (yres == 180 ?
87
(xres == 180 ? 39 : 40) :
88
(xres == 180 ? 71 : 72));
89
int bytes_per_column = (yres == 180) ? 3 : 6;
90
int bits_per_column = bytes_per_column * 8;
91
int skip_unit = bytes_per_column * (xres == 180 ? 1 : 2); /* Skips in step of 1/180" */
92
byte *in = (byte *)gs_malloc(pdev->memory, 8, line_size, "sj48_print_page(in)");
93
byte *out = (byte *)gs_malloc(pdev->memory, bits_per_column, line_size, "sj48_print_page(out)");
98
int last_row = dev_print_scan_lines(pdev);
99
int limit = last_row - bits_per_column;
101
if ( in == 0 || out == 0 )
102
{ code = gs_error_VMerror;
107
/* Abort if the requested resolution is unsupported. */
108
if ((xres !=180 && xres != 360) || (yres !=180 && yres != 360))
109
{ code = gs_error_rangecheck;
114
/* Initialize the printer. */
115
fwrite("\033@\000\000", 1, 4, prn_stream); /* <Printer reset>, <0>, <0>. */
117
/* Transfer pixels to printer. The last row we can print is defined
118
by "last_row". Only the bottom of the print head can print at the
119
bottom margin, and so we align the final printing pass. The print
120
head is kept from moving below "limit", which is exactly one pass
121
above the bottom margin. Once it reaches this limit, we make our
122
final printing pass of a full "bits_per_column" rows. */
123
while ( lnum < last_row )
126
byte *in_end = in + line_size;
128
byte *out_end = out + bytes_per_column * pdev->width;
132
/* Copy 1 scan line and test for all zero. */
133
code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
134
if ( code < 0 ) goto xit;
135
/* The mem... or str... functions should be faster than */
136
/* the following code, but all systems seem to implement */
137
/* them so badly that this code is faster. */
138
{ register const long *zip = (const long *)in_data;
139
register int zcnt = line_size;
140
register const byte *zipb;
141
for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) )
142
{ if ( zip[0] | zip[1] | zip[2] | zip[3] )
145
zipb = (const byte *)zip;
146
while ( --zcnt >= 0 )
151
/* Line is all zero, skip */
81
int xres = pdev->x_pixels_per_inch;
82
int yres = pdev->y_pixels_per_inch;
83
int mode = (yres == 180 ?
84
(xres == 180 ? 39 : 40) :
85
(xres == 180 ? 71 : 72));
86
int bytes_per_column = (yres == 180) ? 3 : 6;
87
int bits_per_column = bytes_per_column * 8;
88
int skip_unit = bytes_per_column * (xres == 180 ? 1 : 2); /* Skips in step of 1/180" */
89
byte *in = (byte *)gs_malloc(pdev->memory, 8, line_size, "sj48_print_page(in)");
90
byte *out = (byte *)gs_malloc(pdev->memory, bits_per_column, line_size, "sj48_print_page(out)");
95
int last_row = dev_print_scan_lines(pdev);
96
int limit = last_row - bits_per_column;
98
if ( in == 0 || out == 0 )
99
{ code = gs_error_VMerror;
104
/* Abort if the requested resolution is unsupported. */
105
if ((xres !=180 && xres != 360) || (yres !=180 && yres != 360))
106
{ code = gs_error_rangecheck;
111
/* Initialize the printer. */
112
fwrite("\033@\000\000", 1, 4, prn_stream); /* <Printer reset>, <0>, <0>. */
114
/* Transfer pixels to printer. The last row we can print is defined
115
by "last_row". Only the bottom of the print head can print at the
116
bottom margin, and so we align the final printing pass. The print
117
head is kept from moving below "limit", which is exactly one pass
118
above the bottom margin. Once it reaches this limit, we make our
119
final printing pass of a full "bits_per_column" rows. */
120
while ( lnum < last_row )
123
byte *in_end = in + line_size;
125
byte *out_end = out + bytes_per_column * pdev->width;
129
/* Copy 1 scan line and test for all zero. */
130
code = gdev_prn_get_bits(pdev, lnum, in, &in_data);
131
if ( code < 0 ) goto xit;
132
/* The mem... or str... functions should be faster than */
133
/* the following code, but all systems seem to implement */
134
/* them so badly that this code is faster. */
135
{ register const long *zip = (const long *)in_data;
136
register int zcnt = line_size;
137
register const byte *zipb;
138
for ( ; zcnt >= 4 * sizeof(long); zip += 4, zcnt -= 4 * sizeof(long) )
139
{ if ( zip[0] | zip[1] | zip[2] | zip[3] )
142
zipb = (const byte *)zip;
143
while ( --zcnt >= 0 )
148
/* Line is all zero, skip */
158
/* Vertical tab to the appropriate position. Note here that
159
we make sure we don't move below limit. */
161
{ skip -= (limit - lnum);
165
/* The SJ48 can only skip in steps of 1/180" */
170
skip--; /* Makes skip even. */
155
/* Vertical tab to the appropriate position. Note here that
156
we make sure we don't move below limit. */
158
{ skip -= (limit - lnum);
162
/* The SJ48 can only skip in steps of 1/180" */
167
skip--; /* Makes skip even. */
176
while ( skips > 255 )
177
{ fputs("\033J\377", prn_stream);
181
fprintf(prn_stream, "\033J%c", skips);
183
/* If we've printed as far as "limit", then reset "limit"
184
to "last_row" for the final printing pass. */
189
/* Transpose in blocks of 8 scan lines. */
190
for ( bnum = 0; bnum < bits_per_column; bnum += 8 )
191
{ int lcnt = min(8, limit - lnum);
194
lcnt = gdev_prn_copy_scan_lines(pdev,
195
lnum, in, lcnt * line_size);
201
memset(in + lcnt * line_size, 0,
202
(8 - lcnt) * line_size);
203
for ( ; inp < in_end; inp++, outp += bits_per_column )
204
{ gdev_prn_transpose_8x8(inp, line_size,
205
outp, bytes_per_column);
212
/* Send the bits to the printer. We alternate horizontal
213
skips with the data. The horizontal skips are in units
214
of 1/180 inches, so we look at the data in groups of
215
1 or 2 columns depending on resolution (controlled
173
while ( skips > 255 )
174
{ fputs("\033J\377", prn_stream);
178
fprintf(prn_stream, "\033J%c", skips);
180
/* If we've printed as far as "limit", then reset "limit"
181
to "last_row" for the final printing pass. */
186
/* Transpose in blocks of 8 scan lines. */
187
for ( bnum = 0; bnum < bits_per_column; bnum += 8 )
188
{ int lcnt = min(8, limit - lnum);
191
lcnt = gdev_prn_copy_scan_lines(pdev,
192
lnum, in, lcnt * line_size);
198
memset(in + lcnt * line_size, 0,
199
(8 - lcnt) * line_size);
200
for ( ; inp < in_end; inp++, outp += bits_per_column )
201
{ gdev_prn_transpose_8x8(inp, line_size,
202
outp, bytes_per_column);
209
/* Send the bits to the printer. We alternate horizontal
210
skips with the data. The horizontal skips are in units
211
of 1/180 inches, so we look at the data in groups of
212
1 or 2 columns depending on resolution (controlled
216
213
by skip_unit). */
223
/* First look for blank groups of columns. */
224
while(outl < out_end)
225
{ n = count = min(out_end - outl, skip_unit);
227
while ( --count >= 0 )
239
{ count = (outl - out_beg) / skip_unit;
240
fprintf(prn_stream, "\033\\%c%c",
241
count & 0xff, count >> 8);
244
/* Next look for non-blank groups of columns. */
247
while(outl < out_end)
248
{ n = count = min(out_end - outl, skip_unit);
250
while ( --count >= 0 )
259
count = outl - out_beg;
261
/* What to transmit is the number of columns in the row.
262
Compare this with the <Esc>|*-command wich expects the
263
total number of bytes in the graphic row! */
264
int count1 = count/bytes_per_column;
265
fprintf(prn_stream, "\033*%c%c%c",
266
mode, count1 & 0xff, count1 >> 8);
268
fwrite(out_beg, 1, count, prn_stream);
272
while ( out_beg < out_end );
274
fputc('\r', prn_stream);
275
skip = bits_per_column; /* <CR> only moves to the beginning of the row. */
220
/* First look for blank groups of columns. */
221
while(outl < out_end)
222
{ n = count = min(out_end - outl, skip_unit);
224
while ( --count >= 0 )
236
{ count = (outl - out_beg) / skip_unit;
237
fprintf(prn_stream, "\033\\%c%c",
238
count & 0xff, count >> 8);
241
/* Next look for non-blank groups of columns. */
244
while(outl < out_end)
245
{ n = count = min(out_end - outl, skip_unit);
247
while ( --count >= 0 )
256
count = outl - out_beg;
258
/* What to transmit is the number of columns in the row.
259
Compare this with the <Esc>|*-command wich expects the
260
total number of bytes in the graphic row! */
261
int count1 = count/bytes_per_column;
262
fprintf(prn_stream, "\033*%c%c%c",
263
mode, count1 & 0xff, count1 >> 8);
265
fwrite(out_beg, 1, count, prn_stream);
269
while ( out_beg < out_end );
271
fputc('\r', prn_stream);
272
skip = bits_per_column; /* <CR> only moves to the beginning of the row. */
279
276
xit: fputc(014, prn_stream); /* form feed */
281
278
fin: if ( out != 0 )
282
gs_free(pdev->memory, (char *)out, bits_per_column, line_size,
283
"sj48_print_page(out)");
285
gs_free(pdev->memory, (char *)in, 8, line_size, "sj48_print_page(in)");
279
gs_free(pdev->memory, (char *)out, bits_per_column, line_size,
280
"sj48_print_page(out)");
282
gs_free(pdev->memory, (char *)in, 8, line_size, "sj48_print_page(in)");