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

« back to all changes in this revision

Viewing changes to src/gdevokii.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: gdevokii.c 8250 2007-09-25 13:31:24Z giles $*/
14
 
/*
15
 
 * Okidata IBM compatible dot-matrix printer driver for Ghostscript.
16
 
 *
17
 
 * This device is for the Okidata Microline IBM compatible 9 pin dot
18
 
 * matrix printers.  It is derived from the Epson 9 pin printer driver
19
 
 * using the standard 1/72" vertical pin spacing and the 60/120/240
20
 
 * dpi horizontal resolutions.  The vertical feed resolution however
21
 
 * is 1/144" and the Okidata implements the standard 1/216" requests
22
 
 * through "scaling":
23
 
 *
24
 
 *   (power on)
25
 
 *   "\033J\001" (vertical feed 1/216")  => Nothing happens
26
 
 *   "\033J\001" (vertical feed 1/216")  => Advance 1/144"
27
 
 *   "\033J\001" (vertical feed 1/216")  => Advance 1/144"
28
 
 *   "\033J\001" (vertical feed 1/216")  => Nothing happens
29
 
 *   (and so on)
30
 
 *
31
 
 * The simple minded accounting used here keep track of when the
32
 
 * page actually advances assumes the printer starts in a "power on"
33
 
 * state.
34
 
 * 
35
 
 * Supported resolutions are:
36
 
 *
37
 
 *    60x72      60x144
38
 
 *   120x72     120x144
39
 
 *   240x72     240x144
40
 
 *
41
 
 */
42
 
#include "gdevprn.h"
43
 
 
44
 
/*
45
 
 * Valid values for X_DPI:
46
 
 *
47
 
 *     60, 120, 240
48
 
 *
49
 
 * The value specified at compile time is the default value used if the
50
 
 * user does not specify a resolution at runtime.
51
 
 */
52
 
 
53
 
#ifndef X_DPI
54
 
#  define X_DPI 120
55
 
#endif
56
 
 
57
 
/*
58
 
 * Valid values for Y_DPI:
59
 
 *
60
 
 *     72, 144
61
 
 *
62
 
 * The value specified at compile time is the default value used if the
63
 
 * user does not specify a resolution at runtime.
64
 
 */
65
 
 
66
 
#ifndef Y_DPI
67
 
#  define Y_DPI 72
68
 
#endif
69
 
 
70
 
/* The device descriptor */
71
 
static dev_proc_print_page(okiibm_print_page);
72
 
 
73
 
/* Okidata IBM device */
74
 
const gx_device_printer far_data gs_okiibm_device =
75
 
  prn_device(prn_std_procs, "okiibm",
76
 
        DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
77
 
        X_DPI, Y_DPI,
78
 
        0.25, 0.0, 0.25, 0.0,                   /* margins */
79
 
        1, okiibm_print_page);
80
 
 
81
 
/* ------ Internal routines ------ */
82
 
 
83
 
/* Forward references */
84
 
static void okiibm_output_run(byte *, int, int, char, FILE *, int);
85
 
 
86
 
/* Send the page to the printer. */
87
 
static int
88
 
okiibm_print_page1(gx_device_printer *pdev, FILE *prn_stream, int y_9pin_high,
89
 
  const char *init_string, int init_length,
90
 
  const char *end_string, int end_length)
91
 
{       
92
 
        static const char graphics_modes_9[5] =
93
 
        {       
94
 
        -1, 0 /*60*/, 1 /*120*/, -1, 3 /*240*/
95
 
        };
96
 
 
97
 
        int in_y_mult = (y_9pin_high ? 2 : 1);
98
 
        int line_size = gdev_mem_bytes_per_scan_line((gx_device *)pdev);
99
 
        /* Note that in_size is a multiple of 8. */
100
 
        int in_size = line_size * (8 * in_y_mult);
101
 
        byte *buf1 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf1)");
102
 
        byte *buf2 = (byte *)gs_malloc(pdev->memory, in_size, 1, "okiibm_print_page(buf2)");
103
 
        byte *in = buf1;
104
 
        byte *out = buf2;
105
 
        int out_y_mult = 1;
106
 
        int x_dpi = pdev->x_pixels_per_inch;
107
 
        char start_graphics = graphics_modes_9[x_dpi / 60];
108
 
        int first_pass = (start_graphics == 3 ? 1 : 0);
109
 
        int last_pass = first_pass * 2;
110
 
        int y_passes = (y_9pin_high ? 2 : 1);
111
 
        int skip = 0, lnum = 0, pass, ypass;
112
 
        int y_step = 0;
113
 
 
114
 
        /* Check allocations */
115
 
        if ( buf1 == 0 || buf2 == 0 )
116
 
        {       if ( buf1 ) 
117
 
                  gs_free(pdev->memory, (char *)buf1, in_size, 1, "okiibm_print_page(buf1)");
118
 
                if ( buf2 ) 
119
 
                  gs_free(pdev->memory, (char *)buf2, in_size, 1, "okiibm_print_page(buf2)");
120
 
                return_error(gs_error_VMerror);
121
 
        }
122
 
 
123
 
        /* Initialize the printer. */
124
 
        fwrite(init_string, 1, init_length, prn_stream);
125
 
 
126
 
        /* Print lines of graphics */
127
 
        while ( lnum < pdev->height )
128
 
        {       
129
 
                byte *in_data;
130
 
                byte *inp;
131
 
                byte *in_end;
132
 
                byte *out_end;
133
 
                int lcnt;
134
 
 
135
 
                /* Copy 1 scan line and test for all zero. */
136
 
                gdev_prn_get_bits(pdev, lnum, in, &in_data);
137
 
                if ( in_data[0] == 0 &&
138
 
                     !memcmp((char *)in_data, (char *)in_data + 1, line_size - 1)
139
 
                   )
140
 
                {       
141
 
                        lnum++;
142
 
                        skip += 2 / in_y_mult;
143
 
                        continue;
144
 
                }
145
 
 
146
 
                /*
147
 
                 * Vertical tab to the appropriate position.
148
 
                 * The skip count is in 1/144" steps.  If total
149
 
                 * vertical request is not a multiple od 1/72"
150
 
                 * we need to make sure the page is actually
151
 
                 * going to advance.
152
 
                 */
153
 
                if ( skip & 1 )
154
 
                {
155
 
                        int n = 1 + (y_step == 0 ? 1 : 0);
156
 
                        fprintf(prn_stream, "\033J%c", n);
157
 
                        y_step = (y_step + n) % 3;
158
 
                        skip -= 1;
159
 
                }
160
 
                skip = skip / 2 * 3;
161
 
                while ( skip > 255 )
162
 
                {       
163
 
                        fputs("\033J\377", prn_stream);
164
 
                        skip -= 255;
165
 
                }
166
 
                if ( skip )
167
 
                {
168
 
                        fprintf(prn_stream, "\033J%c", skip);
169
 
                }
170
 
 
171
 
                /* Copy the the scan lines. */
172
 
                lcnt = gdev_prn_copy_scan_lines(pdev, lnum, in, in_size);
173
 
                if ( lcnt < 8 * in_y_mult )
174
 
                {       /* Pad with lines of zeros. */
175
 
                        memset(in + lcnt * line_size, 0,
176
 
                               in_size - lcnt * line_size);
177
 
                }
178
 
 
179
 
                if ( y_9pin_high )
180
 
                {       /* Shuffle the scan lines */
181
 
                        byte *p;
182
 
                        int i;
183
 
                        static const char index[] =
184
 
                        {  0, 2, 4, 6, 8, 10, 12, 14,
185
 
                           1, 3, 5, 7, 9, 11, 13, 15
186
 
                        };
187
 
                        for ( i = 0; i < 16; i++ )
188
 
                        {
189
 
                                memcpy( out + (i * line_size),
190
 
                                        in + (index[i] * line_size),
191
 
                                        line_size);
192
 
                        }
193
 
                        p = in;
194
 
                        in = out;
195
 
                        out = p;
196
 
                }
197
 
 
198
 
        for ( ypass = 0; ypass < y_passes; ypass++ )
199
 
        {
200
 
            for ( pass = first_pass; pass <= last_pass; pass++ )
201
 
            {
202
 
                /* We have to 'transpose' blocks of 8 pixels x 8 lines, */
203
 
                /* because that's how the printer wants the data. */
204
 
 
205
 
                if ( pass == first_pass )
206
 
                {
207
 
                    out_end = out;
208
 
                    inp = in;
209
 
                    in_end = inp + line_size;
210
 
    
211
 
                    for ( ; inp < in_end; inp++, out_end += 8 )
212
 
                    { 
213
 
                        gdev_prn_transpose_8x8(inp + (ypass * 8 * line_size), 
214
 
                                               line_size, out_end, 1);
215
 
                    }
216
 
                    /* Remove trailing 0s. */
217
 
                    while ( out_end > out && out_end[-1] == 0 )
218
 
                    {
219
 
                        out_end--;
220
 
                    }
221
 
                }
222
 
 
223
 
                /* Transfer whatever is left and print. */
224
 
                if ( out_end > out )
225
 
                {
226
 
                    okiibm_output_run(out, (int)(out_end - out),
227
 
                                   out_y_mult, start_graphics,
228
 
                                   prn_stream, pass);
229
 
                }
230
 
                fputc('\r', prn_stream);
231
 
            }
232
 
            if ( ypass < y_passes - 1 )
233
 
            {
234
 
                int n = 1 + (y_step == 0 ? 1 : 0);
235
 
                fprintf(prn_stream, "\033J%c", n);
236
 
                y_step = (y_step + n) % 3;
237
 
            }
238
 
        }
239
 
        skip = 16 - y_passes + 1;               /* no skip on last Y pass */
240
 
        lnum += 8 * in_y_mult;
241
 
        }
242
 
 
243
 
        /* Reinitialize the printer. */
244
 
        fwrite(end_string, 1, end_length, prn_stream);
245
 
        fflush(prn_stream);
246
 
 
247
 
        gs_free(pdev->memory, (char *)buf2, in_size, 1, "okiibm_print_page(buf2)");
248
 
        gs_free(pdev->memory, (char *)buf1, in_size, 1, "okiibm_print_page(buf1)");
249
 
        return 0;
250
 
}
251
 
 
252
 
/* Output a single graphics command. */
253
 
/* pass=0 for all columns, 1 for even columns, 2 for odd columns. */
254
 
static void
255
 
okiibm_output_run(byte *data, int count, int y_mult,
256
 
  char start_graphics, FILE *prn_stream, int pass)
257
 
{       
258
 
        int xcount = count / y_mult;
259
 
 
260
 
        fputc(033, prn_stream);
261
 
        fputc("KLYZ"[start_graphics], prn_stream);
262
 
        fputc(xcount & 0xff, prn_stream);
263
 
        fputc(xcount >> 8, prn_stream);
264
 
        if ( !pass )
265
 
        {
266
 
                fwrite(data, 1, count, prn_stream);
267
 
        }
268
 
        else
269
 
        {       
270
 
                /* Only write every other column of y_mult bytes. */
271
 
                int which = pass;
272
 
                register byte *dp = data;
273
 
                register int i, j;
274
 
 
275
 
                for ( i = 0; i < xcount; i++, which++ )
276
 
                {
277
 
                        for ( j = 0; j < y_mult; j++, dp++ )
278
 
                        {
279
 
                                putc(((which & 1) ? *dp : 0), prn_stream);
280
 
                        }
281
 
                }
282
 
        }
283
 
}
284
 
 
285
 
/* The print_page procedures are here, to avoid a forward reference. */
286
 
 
287
 
static const char okiibm_init_string[]  = { 0x18 };
288
 
static const char okiibm_end_string[]   = { 0x0c };
289
 
static const char okiibm_one_direct[]   = { 0x1b, 0x55, 0x01 };
290
 
static const char okiibm_two_direct[]   = { 0x1b, 0x55, 0x00 };
291
 
 
292
 
static int
293
 
okiibm_print_page(gx_device_printer *pdev, FILE *prn_stream)
294
 
{
295
 
        char init_string[16], end_string[16];
296
 
        int init_length, end_length;
297
 
 
298
 
        init_length = sizeof(okiibm_init_string);
299
 
        memcpy(init_string, okiibm_init_string, init_length);
300
 
 
301
 
        end_length = sizeof(okiibm_end_string);
302
 
        memcpy(end_string, okiibm_end_string, end_length);
303
 
 
304
 
        if ( pdev->y_pixels_per_inch > 72 &&
305
 
             pdev->x_pixels_per_inch > 60 )
306
 
        {
307
 
                /* Unidirectional printing for the higher resolutions. */
308
 
                memcpy( init_string + init_length, okiibm_one_direct,
309
 
                        sizeof(okiibm_one_direct) );
310
 
                init_length += sizeof(okiibm_one_direct);
311
 
 
312
 
                memcpy( end_string + end_length, okiibm_two_direct,
313
 
                        sizeof(okiibm_two_direct) );
314
 
                end_length += sizeof(okiibm_two_direct);
315
 
        }
316
 
        
317
 
        return okiibm_print_page1( pdev, prn_stream, 
318
 
                                   pdev->y_pixels_per_inch > 72 ? 1 : 0,
319
 
                                   init_string, init_length,
320
 
                                   end_string, end_length );
321
 
}