~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to base/gdevo182.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
 
2
   All Rights Reserved.
 
3
  
 
4
   This software is provided AS-IS with no warranty, either express or
 
5
   implied.
 
6
 
 
7
   This software is distributed under license and may not be copied, modified
 
8
   or distributed except as expressly authorized under the terms of that
 
9
   license.  Refer to licensing information at http://www.artifex.com/
 
10
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
 
11
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
 
12
*/
 
13
/* $Id: gdevo182.c 8250 2007-09-25 13:31:24Z giles $*/
 
14
/* Okidata Microline 182 printer driver */
 
15
 
 
16
/* Contributed by Maarten Koning (smeg@bnr.ca) April 4, 1993 */
 
17
 
 
18
/****************************************************************
 
19
 
 
20
I use this driver from Unix with the following aliases:
 
21
 
 
22
alias psp "gs -q -sDEVICE=oki182 -sOutputFile=\|lpr - <\!*"
 
23
alias psphigh "gs -q -sDEVICE=oki182 -r144 -sOutputFile=\|lpr - <\!*"
 
24
 
 
25
ps. I have my printer DIP switches set to the following (as viewed
 
26
        while standing in front of your printer looking down into the
 
27
        config access hatch located at the top of your printer
 
28
        in the centre back).
 
29
 
 
30
Upper  Upper   Bottom
 
31
Left   Right   (at right)
 
32
 
 
33
 x      x        x
 
34
 x       x      x
 
35
 x       x       x
 
36
x        x      x
 
37
 x      x        x
 
38
 x      x        x
 
39
x        x      x
 
40
 x      x        x
 
41
 
 
42
The upper DIP switches are on a SuperSpeed Serial
 
43
card that will do 19200 baud.  I have it set at 9600
 
44
baud since that seems sufficient to keep the printer
 
45
busy.
 
46
 
 
47
The important thing is to be in 8-bit mode so that
 
48
the graphics data can't match any Okidata commands
 
49
(This driver sets the high bit of graphics data to 1).
 
50
 
 
51
****************************************************************/
 
52
 
 
53
#include "gdevprn.h"
 
54
 
 
55
/*
 
56
 *  Available resolutions are 72x72 or 144x144;
 
57
 *  (144x72) would be possible to do also, but I didn't bother)
 
58
 */
 
59
 
 
60
/* The device descriptor */
 
61
 
 
62
static dev_proc_print_page(oki_print_page);
 
63
 
 
64
const gx_device_printer far_data gs_oki182_device =
 
65
  prn_device(prn_std_procs, "oki182",
 
66
        80,                             /* width_10ths, 8.0" */
 
67
        110,                            /* height_10ths, 11" */
 
68
        72,                             /* x_dpi */
 
69
        72,                             /* y_dpi */
 
70
        0, 0, 0, 0,                     /* margins */
 
71
        1, oki_print_page);
 
72
 
 
73
/* ------ internal routines ------ */
 
74
 
 
75
/* out is a pointer to an array of 7 scan lines,
 
76
   lineSize is the number of bytes between a pixel and
 
77
   the pixel directly beneath it.
 
78
   scanBits is the number of bits in each scan line
 
79
   out is a pointer to an array of column data, which
 
80
   is how the Okidata wants the graphics image.
 
81
 
 
82
   each column of graphics data is 7 bits high and
 
83
   is encoded in a byte - highest pixel in the column
 
84
   is the lowest bit in the byte.  The upper bit of the
 
85
   byte is set so that the okidata doesn't mistake
 
86
   graphic image data for graphic commands.
 
87
*/
 
88
 
 
89
static void
 
90
oki_transpose(byte *in, byte *out, int scanBits, register int lineSize)
 
91
{
 
92
        register bitMask = 0x80;
 
93
        register byte *inPtr;
 
94
        register byte outByte;
 
95
 
 
96
        while (scanBits-- > 0) {
 
97
 
 
98
                inPtr = in;
 
99
 
 
100
                if (*inPtr & bitMask)
 
101
                        outByte = 0x81;
 
102
                else
 
103
                        outByte = 0x80;
 
104
                if (*(inPtr += lineSize) & bitMask)
 
105
                        outByte += 0x02;
 
106
                if (*(inPtr += lineSize) & bitMask)
 
107
                        outByte += 0x04;
 
108
                if (*(inPtr += lineSize) & bitMask)
 
109
                        outByte += 0x08;
 
110
                if (*(inPtr += lineSize) & bitMask)
 
111
                        outByte += 0x10;
 
112
                if (*(inPtr += lineSize) & bitMask)
 
113
                        outByte += 0x20;
 
114
                if (*(inPtr += lineSize) & bitMask)
 
115
                        outByte += 0x40;
 
116
 
 
117
                *out++ = outByte;
 
118
 
 
119
                if ((bitMask >>= 1) == 0) {
 
120
                        bitMask = 0x80;
 
121
                        in ++;
 
122
                }
 
123
        }
 
124
}
 
125
 
 
126
/* This routine tries to compress a sequence of okidata
 
127
   graphic bytes by trimming off leading and trailing
 
128
   zeros.  Trailing zeros can be thrown away and leading
 
129
   zeros can be replaced with a much smaller number of spaces.
 
130
 
 
131
   'in' is a pointer to the graphic bytes to be compressed.
 
132
   origWidth is the number of bytes pointed to by 'in'.
 
133
   highRes is non-zero when 144x144 mode is being used.
 
134
 
 
135
   numSpaces is set to the number of spaces that should
 
136
   be printed before the compressed image. newWidth is
 
137
   the new number of bytes that the return value of this
 
138
   function points to.
 
139
 
 
140
   xxx - A future enhancement would be to replace long sequences
 
141
   of embedded zeros with exit.graphics-<n> spaces-enter.graphics
 
142
*/
 
143
static byte *
 
144
oki_compress(byte *in, int origWidth, int highRes,
 
145
                        int *numSpaces, int *newWidth)
 
146
{
 
147
        int spaces = 0;
 
148
        int columns_per_space = 6;
 
149
 
 
150
        byte *in_end = in + origWidth;
 
151
 
 
152
        /* remove trailing zeros (which are realy 0x80's) */
 
153
        while (in_end > in && in_end[-1] == 0x80)
 
154
                in_end --;
 
155
 
 
156
        if (highRes)
 
157
                columns_per_space = 12;
 
158
 
 
159
        /* remove leading zeros that can be replaced by spaces */
 
160
        while(in < in_end && in[0] == 0x80 && memcmp((char *)in,
 
161
                                (char *)in + 1, columns_per_space - 1) == 0) {
 
162
                spaces++;
 
163
                in += columns_per_space;
 
164
        }
 
165
 
 
166
        *numSpaces = spaces;
 
167
 
 
168
        /* just in case we compressed this line out of existance */
 
169
        if (in_end > in)
 
170
                *newWidth = in_end - in;
 
171
        else
 
172
                *newWidth = 0;
 
173
 
 
174
        return(in);
 
175
}
 
176
 
 
177
/* Send the page to the printer. */
 
178
 
 
179
static int
 
180
oki_print_page(gx_device_printer *pdev, FILE *prn_stream)
 
181
{
 
182
        int highRes = pdev->y_pixels_per_inch > 100;
 
183
        int bits_per_column = 7;
 
184
        int i, spaces, width;
 
185
        int lcnt;
 
186
 
 
187
        int line_size = gdev_prn_raster((gx_device_printer *)pdev);
 
188
 
 
189
        byte *in = (byte *)gs_malloc(pdev->memory, 16, line_size, "oki_print_page(in)");
 
190
 
 
191
        byte *out1 = (byte *)gs_malloc(pdev->memory, 8, line_size, "oki_print_page(out1)");
 
192
        byte *out2 = (byte *)gs_malloc(pdev->memory, 8, line_size, "oki_print_page(out2)");
 
193
 
 
194
        byte *out3;
 
195
 
 
196
        int lnum = 0;
 
197
        int skip = 0;
 
198
        int code = 0;
 
199
 
 
200
        if ( in == 0 || out1 == 0 || out2 == 0)
 
201
        {       code = gs_error_VMerror;
 
202
                gs_note_error(code);
 
203
                goto bail;
 
204
        }
 
205
 
 
206
        /* Initialize the printer. */
 
207
        /* CAN; 72x72; left margin = 001; disable skip over perforation */
 
208
        fwrite("\030\034\033%C001\033%S0", 1, 12, prn_stream);
 
209
 
 
210
        if (highRes) {
 
211
                fwrite("\033R", 1, 2, prn_stream);
 
212
                bits_per_column = 14;
 
213
        }
 
214
 
 
215
        /* Transfer pixels to printer */
 
216
        while ( lnum < pdev->height ) {
 
217
 
 
218
                /* Copy 1 scan line and test for all zero. */
 
219
                code = gdev_prn_copy_scan_lines(pdev, lnum, in, line_size);
 
220
                if ( code < 0 )
 
221
                        goto xit;
 
222
 
 
223
                /* if line is all zero, skip */
 
224
                if ( in[0] == 0 && !memcmp((char *)in, (char *)in + 1,
 
225
                                                        line_size - 1)) {
 
226
                        lnum++;
 
227
                        if (highRes)
 
228
                                skip++;
 
229
                        else
 
230
                                skip += 2;
 
231
                        continue;
 
232
                }
 
233
 
 
234
                /* use fine line feed to get to the appropriate position. */
 
235
                while ( skip > 127 ) {
 
236
                        fputs("\033%5\177", prn_stream);
 
237
                        skip -= 127;
 
238
                }
 
239
                if ( skip )
 
240
                        fprintf(prn_stream, "\033%%5%c",
 
241
                                        (char) (skip & 0xff));
 
242
                skip = 0;
 
243
 
 
244
                /* get the rest of the scan lines */
 
245
                code = gdev_prn_copy_scan_lines(pdev, lnum + 1,
 
246
                        in + line_size, (bits_per_column - 1) * line_size);
 
247
 
 
248
                if ( code < 0 )
 
249
                        goto xit;
 
250
 
 
251
                lcnt = code + 1; /* since we already grabbed one line */
 
252
 
 
253
                if ( lcnt < bits_per_column )
 
254
                        memset(in + lcnt * line_size, 0,
 
255
                                        (bits_per_column - lcnt) * line_size);
 
256
 
 
257
                if (highRes) {
 
258
                        oki_transpose(in, out1, pdev->width, 2 * line_size);
 
259
                        oki_transpose(in + line_size, out2,
 
260
                                                pdev->width, 2 * line_size);
 
261
                } else
 
262
                        oki_transpose(in, out1, pdev->width, line_size);
 
263
 
 
264
                out3 = oki_compress(out1, pdev->width, highRes,
 
265
                                                &spaces, &width);
 
266
 
 
267
                for (i=0; i < spaces; i++)
 
268
                        putc(' ', prn_stream);
 
269
 
 
270
                fwrite("\003", 1, 1, prn_stream);
 
271
                fwrite(out3, 1, width, prn_stream);
 
272
 
 
273
                if (highRes) {
 
274
                        /* exit graphics; carriage return; 1 bit line feed */
 
275
                        fprintf(prn_stream, "\003\002\015\033%%5%c", (char) 1);
 
276
                        out3 = oki_compress(out2, pdev->width, highRes,
 
277
                                                        &spaces, &width);
 
278
                        for (i=0; i < spaces; i++)
 
279
                                putc(' ', prn_stream);
 
280
                        fwrite("\003", 1, 1, prn_stream);
 
281
                        fwrite(out3, 1, width, prn_stream);
 
282
                        fprintf(prn_stream, "\003\002\015\033%%5%c", (char) 13);
 
283
                } else
 
284
                        fwrite("\003\016\003\002", 1, 4, prn_stream);
 
285
 
 
286
                lnum += bits_per_column;
 
287
           }
 
288
 
 
289
        /* Eject the page */
 
290
xit:
 
291
        fputc(014, prn_stream); /* form feed */
 
292
        fflush(prn_stream);
 
293
 
 
294
bail:
 
295
        if ( out1 != 0 )
 
296
                gs_free(pdev->memory, (char *)out1, 8, line_size, "oki_print_page(out1)");
 
297
 
 
298
        if ( out2 != 0 )
 
299
                gs_free(pdev->memory, (char *)out2, 8, line_size, "oki_print_page(out2)");
 
300
 
 
301
        if ( in != 0 )
 
302
                gs_free(pdev->memory, (char *)in, 16, line_size, "oki_print_page(in)");
 
303
 
 
304
        return code;
 
305
}