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

« back to all changes in this revision

Viewing changes to base/gdevatx.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: gdevatx.c 8250 2007-09-25 13:31:24Z giles $ */
 
14
/* Practical Automation ATX-23, -24, and -38 driver */
 
15
#include "math_.h"
 
16
#include "gdevprn.h"
 
17
 
 
18
/*
 
19
 * All of the ATX printers have an unprintable margin of 0.125" at the top
 
20
 * and bottom of the page.  They also have unprintable left/right margins:
 
21
 *      ATX-23  0.25"
 
22
 *      ATX-24  0.193"
 
23
 *      ATS-38  0.25"
 
24
 * The code below assumes that coordinates refer only to the *printable*
 
25
 * part of each page.  This is wrong and must eventually be changed.
 
26
 */
 
27
 
 
28
/* Define the printer commands. */
 
29
#define ATX_SET_PAGE_LENGTH "\033f"  /* + 2-byte length */
 
30
#define ATX_VERTICAL_TAB "\033L"  /* + 2-byte count */
 
31
#define ATX_UNCOMPRESSED_DATA "\033d"  /* + 2-byte count */
 
32
#define ATX_COMPRESSED_DATA "\033x"  /* + 1-byte word count */
 
33
#define ATX_END_PAGE "\033e"
 
34
 
 
35
/* The device descriptors */
 
36
static dev_proc_print_page(atx23_print_page);
 
37
static dev_proc_print_page(atx24_print_page);
 
38
static dev_proc_print_page(atx38_print_page);
 
39
 
 
40
#define ATX_DEVICE(dname, w10, h10, dpi, lrm, btm, print_page)\
 
41
  prn_device_margins(prn_std_procs, dname, w10, h10, dpi, dpi, 0, 0,\
 
42
                     lrm, btm, lrm, btm, 1, print_page)
 
43
 
 
44
const gx_device_printer gs_atx23_device = /* real width = 576 pixels */
 
45
ATX_DEVICE("atx23", 28 /* 2.84" */, 35 /* (minimum) */,
 
46
           203, 0.25, 0.125, atx23_print_page);
 
47
 
 
48
const gx_device_printer gs_atx24_device = /* real width = 832 pixels */
 
49
ATX_DEVICE("atx24", 41 /* 4.1" */, 35 /* (minimum) */,
 
50
           203, 0.193, 0.125, atx24_print_page);
 
51
 
 
52
const gx_device_printer gs_atx38_device = /* real width = 2400 pixels */
 
53
ATX_DEVICE("atx38", 80 /* 8.0" */, 35 /* (minimum) */,
 
54
           300, 0.25, 0.125, atx38_print_page);
 
55
 
 
56
/* Output a printer command with a 2-byte, little-endian numeric argument. */
 
57
static void
 
58
fput_atx_command(FILE *f, const char *str, int value)
 
59
{
 
60
    fputs(str, f);
 
61
    fputc((byte)value, f);
 
62
    fputc((byte)(value >> 8), f);
 
63
}
 
64
 
 
65
/*
 
66
 * Attempt to compress a scan line of data.  in_size and out_size are even.
 
67
 * Return -1 if the compressed data would exceed out_size, otherwise the
 
68
 * size of the compressed data (always even).
 
69
 */
 
70
#define MIN_IN_SIZE_TO_COMPRESS 50
 
71
#define MAX_COMPRESSED_SEGMENT_PAIRS 127
 
72
#define MAX_UNCOMPRESSED_SEGMENT_PAIRS 255
 
73
#define COMPRESSED_SEGMENT_COMMAND 0x80 /* + # of repeated pairs */
 
74
#define UNCOMPRESSED_SEGMENT_COMMAND 0x7f /* followed by # of pairs */
 
75
static int
 
76
atx_compress(const byte *in_buf, int in_size, byte *out_buf, int out_size)
 
77
{
 
78
    const byte *const in_end = in_buf + in_size;
 
79
    byte *const out_end = out_buf + out_size;
 
80
    const byte *in = in_buf;
 
81
    byte *out = out_buf;
 
82
    byte *out_command;
 
83
    int pair_count;
 
84
 
 
85
    if (in_size < MIN_IN_SIZE_TO_COMPRESS)
 
86
        return -1;                      /* not worth compressing */
 
87
 
 
88
    /* Start a new segment. */
 
89
 New_Segment:
 
90
    if (in == in_end)           /* end of input data */
 
91
        return out - out_buf;
 
92
    if (out == out_end)         /* output buffer full */
 
93
        return -1;
 
94
    out_command = out;
 
95
    out += 2;
 
96
    if (in[1] == in[0]) {               /* start compressed segment */
 
97
        /* out[-2] will be compressed segment command */
 
98
        out[-1] = in[0];
 
99
        pair_count = 1;
 
100
        goto Scan_Compressed_Pair;
 
101
    } else {                    /* start uncompressed segment */
 
102
        out[-2] = UNCOMPRESSED_SEGMENT_COMMAND;
 
103
        /* out[-1] will be pair count */
 
104
        pair_count = 0;
 
105
        goto Scan_Uncompressed_Pair;
 
106
    }
 
107
 
 
108
    /* Scan compressed data. */
 
109
 Scan_Compressed:
 
110
    if (pair_count == MAX_COMPRESSED_SEGMENT_PAIRS ||
 
111
        in == in_end || in[0] != in[-1] || in[1] != in[0]
 
112
        ) {                     /* end the segment */
 
113
        out_command[0] = COMPRESSED_SEGMENT_COMMAND + pair_count;
 
114
        goto New_Segment;
 
115
    }
 
116
    ++pair_count;
 
117
 Scan_Compressed_Pair:
 
118
    in += 2;
 
119
    goto Scan_Compressed;
 
120
 
 
121
    /* Scan uncompressed data. */
 
122
 Scan_Uncompressed:
 
123
    if (pair_count == MAX_UNCOMPRESSED_SEGMENT_PAIRS ||
 
124
        in == in_end || in[1] == in[0]
 
125
        ) {                     /* end the segment */
 
126
        out_command[1] = pair_count;
 
127
        goto New_Segment;
 
128
    }
 
129
 Scan_Uncompressed_Pair:
 
130
    if (out == out_end)         /* output buffer full */
 
131
        return -1;
 
132
    out[0] = in[0], out[1] = in[1];
 
133
    in += 2;
 
134
    out += 2;
 
135
    ++pair_count;
 
136
    goto Scan_Uncompressed;
 
137
  
 
138
}
 
139
 
 
140
/* Send the page to the printer. */
 
141
static int
 
142
atx_print_page(gx_device_printer *pdev, FILE *f, int max_width_bytes)
 
143
{
 
144
    /*
 
145
     * The page length command uses 16 bits to represent the length in
 
146
     * units of 0.01", so the maximum representable page length is 
 
147
     * 655.35", including the unprintable top and bottom margins.
 
148
     * Compute the maximum height of the printable area in pixels.
 
149
     */
 
150
    float top_bottom_skip = (pdev->HWMargins[1] + pdev->HWMargins[3]) / 72.0;
 
151
    int max_height = (int)(pdev->HWResolution[1] * 655 - top_bottom_skip);
 
152
    int height = min(pdev->height, max_height);
 
153
    int page_length_100ths =
 
154
        (int)ceil((height / pdev->HWResolution[1] + top_bottom_skip) * 100);
 
155
    gs_memory_t *mem = pdev->memory;
 
156
    int raster = gx_device_raster((gx_device *)pdev, true);
 
157
    byte *buf;
 
158
    /*
 
159
     * ATX_COMPRESSED_DATA only takes a 1-byte (word) count.
 
160
     * Thus no compressed scan line can take more than 510 bytes.
 
161
     */
 
162
    int compressed_raster = min(raster / 2, 510); /* require 50% compression */
 
163
    byte *compressed;
 
164
    int blank_lines, lnum;
 
165
    int code = 0;
 
166
 
 
167
    /* Enforce a minimum 3" page length. */
 
168
    if (page_length_100ths < 300)
 
169
        page_length_100ths = 300;
 
170
    buf = gs_alloc_bytes(mem, raster, "atx_print_page(buf)");
 
171
    compressed = gs_alloc_bytes(mem, compressed_raster,
 
172
                                "atx_print_page(compressed)");
 
173
    if (buf == 0 || compressed == 0) {
 
174
        code = gs_note_error(gs_error_VMerror);
 
175
        goto done;
 
176
    }
 
177
    fput_atx_command(f, ATX_SET_PAGE_LENGTH, page_length_100ths);
 
178
    for (blank_lines = 0, lnum = 0; lnum < height; ++lnum) {
 
179
        byte *row;
 
180
        byte *end;
 
181
        int count;
 
182
 
 
183
        gdev_prn_get_bits(pdev, lnum, buf, &row);
 
184
        /* Find the end of the non-blank data. */
 
185
        for (end = row + raster; end > row && end[-1] == 0 && end[-2] == 0; )
 
186
            end -= 2;
 
187
        if (end == row) {               /* blank line */
 
188
            ++blank_lines;
 
189
            continue;
 
190
        }
 
191
        if (blank_lines) {              /* skip vertically */
 
192
            fput_atx_command(f, ATX_VERTICAL_TAB, blank_lines + 1);
 
193
            blank_lines = 0;
 
194
        }
 
195
        /* Truncate the line to the maximum printable width. */
 
196
        if (end - row > max_width_bytes)
 
197
            end = row + max_width_bytes;
 
198
        count = atx_compress(row, end - row, compressed, compressed_raster);
 
199
        if (count >= 0) {               /* compressed line */
 
200
            /*
 
201
             * Note that since compressed_raster can't exceed 510, count
 
202
             * can't exceed 510 either.
 
203
             */
 
204
            fputs(ATX_COMPRESSED_DATA, f);
 
205
            fputc(count / 2, f);
 
206
            fwrite(compressed, 1, count, f);
 
207
        } else {                        /* uncompressed line */
 
208
            int num_bytes = end - row;
 
209
 
 
210
            fput_atx_command(f, ATX_UNCOMPRESSED_DATA, num_bytes);
 
211
            fwrite(row, 1, num_bytes, f);
 
212
        }
 
213
    }
 
214
 
 
215
#if 0   /**************** MAY NOT BE NEEDED ****************/
 
216
    /* Enforce the minimum page length, and skip any final blank lines. */
 
217
    {
 
218
        int paper_length = (int)(pdev->HWResolution[1] * 3 + 0.5);
 
219
        int printed_length = height - blank_lines;
 
220
 
 
221
        if (height > paper_length)
 
222
            paper_length = height;
 
223
        if (printed_length < paper_length)
 
224
            fput_atx_command(f, ATX_VERTICAL_TAB,
 
225
                             paper_length - printed_length + 1);
 
226
    }
 
227
#endif
 
228
 
 
229
    /* End the page. */
 
230
    fputs(ATX_END_PAGE, f);
 
231
 
 
232
 done:
 
233
    gs_free_object(mem, compressed, "atx_print_page(compressed)");
 
234
    gs_free_object(mem, buf, "atx_print_page(buf)");
 
235
    return code;
 
236
}
 
237
 
 
238
/* Print pages with specified maximum pixel widths. */
 
239
static int
 
240
atx23_print_page(gx_device_printer *pdev, FILE *f)
 
241
{
 
242
    return atx_print_page(pdev, f, 576 / 8);
 
243
}
 
244
static int
 
245
atx24_print_page(gx_device_printer *pdev, FILE *f)
 
246
{
 
247
    return atx_print_page(pdev, f, 832 / 8);
 
248
}
 
249
static int
 
250
atx38_print_page(gx_device_printer *pdev, FILE *f)
 
251
{
 
252
    return atx_print_page(pdev, f, 2400 / 8);
 
253
}