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

« back to all changes in this revision

Viewing changes to base/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
}