~ubuntu-branches/ubuntu/raring/hplip/raring

« back to all changes in this revision

Viewing changes to prnt/hpcups/Pcl3Gui2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-12-14 20:08:44 UTC
  • mfrom: (2.1.118 lucid)
  • Revision ID: james.westby@ubuntu.com-20091214200844-z8qhqwgppbu3t7ze
Tags: 3.9.10-4
KBSD patch from KiBi (Closes: #560796)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************\
 
2
  Pcl3Gui2.cpp : Implementation of Pcl3Gui2 class
 
3
 
 
4
  Copyright (c) 1996 - 2009, Hewlett-Packard Co.
 
5
  All rights reserved.
 
6
 
 
7
  Redistribution and use in source and binary forms, with or without
 
8
  modification, are permitted provided that the following conditions
 
9
  are met:
 
10
  1. Redistributions of source code must retain the above copyright
 
11
     notice, this list of conditions and the following disclaimer.
 
12
  2. Redistributions in binary form must reproduce the above copyright
 
13
     notice, this list of conditions and the following disclaimer in the
 
14
     documentation and/or other materials provided with the distribution.
 
15
  3. Neither the name of Hewlett-Packard nor the names of its
 
16
     contributors may be used to endorse or promote products derived
 
17
     from this software without specific prior written permission.
 
18
 
 
19
  THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
 
20
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
21
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 
22
  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 
24
  TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 
25
  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 
26
  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
28
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
\*****************************************************************************/
 
30
 
 
31
#include "CommonDefinitions.h"
 
32
#include "Pcl3Gui2.h"
 
33
#include "ErnieFilter.h"
 
34
#include "Mode10.h"
 
35
#include "Mode9.h"
 
36
#include "PrinterCommands.h"
 
37
 
 
38
Pcl3Gui2::Pcl3Gui2() : Encapsulator()
 
39
{
 
40
    speed_mech_enabled = true;
 
41
    m_run_ernie_filter = true;
 
42
    crd_type = eCrd_both;
 
43
    strcpy(m_szLanguage, "PCL3GUI");
 
44
}
 
45
 
 
46
Pcl3Gui2::~Pcl3Gui2()
 
47
{
 
48
}
 
49
 
 
50
DRIVER_ERROR Pcl3Gui2::Configure(Pipeline **pipeline)
 
51
{
 
52
    Pipeline    *p = NULL;
 
53
    Pipeline    *head;
 
54
    unsigned int width;
 
55
    head = *pipeline;
 
56
    if (m_pJA->e_duplex_mode != DUPLEXMODE_NONE ||
 
57
        m_pJA->total_pages < 3) {
 
58
            speed_mech_enabled = false;
 
59
    }
 
60
 
 
61
    width = m_pMA->printable_width;;
 
62
    if (m_run_ernie_filter) {
 
63
            ErnieFilter    *pErnie;
 
64
 
 
65
       // Normal: threshold = (resolution) * (0.0876) - 2
 
66
       int threshold = ((m_pQA->horizontal_resolution * 876) / 10000) - 2;
 
67
 
 
68
       pErnie = new ErnieFilter (width, eBGRPixelData, threshold);
 
69
       p = new Pipeline (pErnie);
 
70
       if (head) {
 
71
          head->AddPhase (p);
 
72
       }
 
73
       else {
 
74
           head = p;
 
75
       }
 
76
    }
 
77
 
 
78
    if (crd_type != eCrd_black_only) {
 
79
        Mode10    *pMode10;
 
80
        pMode10 = new Mode10 (width * 3);
 
81
        pMode10->myplane = COLORTYPE_COLOR;
 
82
 
 
83
        p = new Pipeline (pMode10);
 
84
        if (head) {
 
85
            head->AddPhase (p);
 
86
        }
 
87
        else {
 
88
            head = p;
 
89
        }
 
90
    }
 
91
 
 
92
    width = (width + 7) / 8;
 
93
 
 
94
    if (width > 0 && crd_type != eCrd_color_only) {
 
95
        Mode9    *pMode9;
 
96
        // VIP black data is 1 bit here
 
97
        pMode9 = new Mode9 (width);
 
98
        pMode9->myplane = COLORTYPE_BLACK;
 
99
        p = new Pipeline (pMode9);
 
100
        if (head) {
 
101
            head->AddPhase (p);
 
102
        }
 
103
        else {
 
104
            head = p;
 
105
        }
 
106
    }
 
107
    *pipeline = head;
 
108
    return NO_ERROR;
 
109
}
 
110
 
 
111
DRIVER_ERROR Pcl3Gui2::StartPage(JobAttributes *pJA)
 
112
{
 
113
    DRIVER_ERROR    err = NO_ERROR;
 
114
    char            szStr[256];
 
115
    int             top_margin = 0;
 
116
    page_number++;
 
117
 
 
118
//  Under windows, pJA address may have changed, re-init here.
 
119
 
 
120
    m_pJA = pJA;
 
121
    m_pMA = &pJA->media_attributes;
 
122
    m_pQA = &pJA->quality_attributes;
 
123
 
 
124
//  Set media source, type, size and quality modes.
 
125
 
 
126
    sprintf(szStr, "\033&l%dH\033&l%dM\033&l%dA\033*o%dM", m_pJA->media_source, m_pQA->media_type,
 
127
            m_pMA->pcl_id, m_pQA->print_quality);
 
128
 
 
129
//  Now add media subtype
 
130
 
 
131
    int    i = strlen(szStr);
 
132
    memcpy(szStr+i, MediaSubtypeSeq, sizeof(MediaSubtypeSeq));
 
133
    i += sizeof(MediaSubtypeSeq);
 
134
    szStr[i++] = (char) (m_pQA->media_subtype & 0xFFFF) >> 8;
 
135
    szStr[i++] = (char) m_pQA->media_subtype & 0xFF;
 
136
    addToHeader((const BYTE *) szStr, i);
 
137
 
 
138
    if (m_pJA->e_duplex_mode != DUPLEXMODE_NONE) {
 
139
        addToHeader((const BYTE *) EnableDuplex, sizeof(EnableDuplex));
 
140
        speed_mech_enabled = false;
 
141
    }
 
142
 
 
143
    configureRasterData();
 
144
 
 
145
    if (m_pJA->color_mode != 0) {
 
146
//        GrayscaleSeq[9] = m_pJA->color_mode;
 
147
        addToHeader((const BYTE *) GrayscaleSeq, 9);
 
148
        *cur_pcl_buffer_ptr++ = (BYTE) m_pJA->color_mode;
 
149
    }
 
150
 
 
151
    sprintf(szStr,"\033&u%dD", m_pQA->horizontal_resolution);
 
152
    addToHeader((const BYTE *) szStr, strlen(szStr));
 
153
    sprintf(szStr,"\033*t%dR", m_pQA->actual_vertical_resolution);
 
154
    addToHeader((const BYTE *) szStr, strlen(szStr));
 
155
 
 
156
    // another command that helps PCLviewer
 
157
    unsigned int width = m_pMA->printable_width;
 
158
    sprintf(szStr, "\033*r%dS", width);
 
159
    addToHeader((const BYTE *) szStr, strlen(szStr));
 
160
 
 
161
/*
 
162
 *  Custom papersize command
 
163
 */
 
164
 
 
165
    if (m_pMA->pcl_id == CUSTOM_MEDIA_SIZE) {
 
166
        short   sWidth, sHeight;
 
167
        BYTE    b1, b2;
 
168
        sWidth  = static_cast<short>(m_pMA->physical_width);
 
169
        sHeight = static_cast<short>(m_pMA->physical_height);
 
170
        memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
 
171
        b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
 
172
        b2 = (BYTE) (sWidth & 0xFF);
 
173
        szStr[8] = b1;
 
174
        szStr[9] = b2;
 
175
        b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
 
176
        b2 = (BYTE) (sHeight & 0xFF);
 
177
        szStr[18] = b1;
 
178
        szStr[19] = b2;
 
179
        addToHeader((const BYTE *) szStr, 20);
 
180
    }
 
181
 
 
182
    if (m_pJA->print_borderless) {
 
183
        BYTE cBuf[4];
 
184
        BYTE TopOverSpraySeq[]  = {0x1b, 0x2A, 0x6F, 0x35, 0x57, 0x0E, 0x02, 0x00};
 
185
                                // "Esc*o5W 0E 02 00 00 00" Top edge overspray for full-bleed printing
 
186
 
 
187
        BYTE LeftOverSpraySeq[] = {0x1b, 0x2A, 0x6F, 0x35, 0x57, 0x0E, 0x01, 0x00};
 
188
                                // "Esc*o5W 0E 01 00 00 00" Left edge overspray for full-bleed printing
 
189
 
 
190
/*
 
191
 *      The vertical and horizontal overspray here are sum of overspray
 
192
 *      for two opposite edges. The overspray values are assumed to be
 
193
 *      the same for the opposite edges.
 
194
 */
 
195
 
 
196
        cBuf[1] = (m_pMA->vertical_overspray / 2) & 0xFF;
 
197
        cBuf[0] = (m_pMA->vertical_overspray / 2) >> 8;
 
198
 
 
199
        addToHeader((const BYTE *) TopOverSpraySeq, sizeof(TopOverSpraySeq));
 
200
        addToHeader((const BYTE *) cBuf, 2);
 
201
 
 
202
        cBuf[1] = (m_pMA->horizontal_overspray / 2) & 0xFF;
 
203
        cBuf[0] = (m_pMA->horizontal_overspray / 2) >> 8;
 
204
 
 
205
        addToHeader((const BYTE *) LeftOverSpraySeq, sizeof(LeftOverSpraySeq));
 
206
        addToHeader((const BYTE *) cBuf, 2);
 
207
    }
 
208
 
 
209
//  Now send media pre-load command
 
210
    addToHeader((const BYTE *) "\033&l-2H", 6);
 
211
 
 
212
//  Before sending speed mech commands, send the current buffer to the printer
 
213
    err = sendBuffer(static_cast<const BYTE *>(pcl_buffer), (cur_pcl_buffer_ptr - pcl_buffer));
 
214
    cur_pcl_buffer_ptr = pcl_buffer;
 
215
 
 
216
//  send speed mech commands
 
217
 
 
218
    if (speed_mech_enabled) {
 
219
        addToHeader(speed_mech_cmd, sizeof (speed_mech_cmd));
 
220
        *cur_pcl_buffer_ptr++ = (BYTE) ((m_pJA->total_pages & 0x0000FF00) >> 8);
 
221
        *cur_pcl_buffer_ptr++ = (BYTE) ((m_pJA->total_pages & 0x000000FF));
 
222
        if (page_number < m_pJA->total_pages) {
 
223
            addToHeader(speed_mech_continue, sizeof (speed_mech_continue));
 
224
        }
 
225
        else {
 
226
            addToHeader(speed_mech_end, sizeof (speed_mech_end));
 
227
        }
 
228
    }
 
229
 
 
230
    addToHeader((const BYTE *) grafStart, sizeof(grafStart));
 
231
 
 
232
    if (!m_pJA->print_borderless) {
 
233
        top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
 
234
    }
 
235
    addToHeader("\x1b*p%dY", top_margin);
 
236
    return err;
 
237
}
 
238
 
 
239
DRIVER_ERROR Pcl3Gui2::Encapsulate(RASTERDATA *InputRaster, bool bLastPlane)
 
240
{
 
241
    DRIVER_ERROR    err;
 
242
    if (crd_type != eCrd_color_only) {
 
243
        err = encapsulateRaster(InputRaster->rasterdata[COLORTYPE_BLACK], InputRaster->rastersize[COLORTYPE_BLACK], COLORTYPE_BLACK);
 
244
    }
 
245
    if (crd_type != eCrd_black_only) {
 
246
        err = encapsulateRaster(InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR], COLORTYPE_COLOR);
 
247
    }
 
248
    return err;
 
249
}
 
250
 
 
251
DRIVER_ERROR Pcl3Gui2::encapsulateRaster(BYTE *raster, unsigned int length, COLORTYPE c_type)
 
252
{
 
253
    DRIVER_ERROR     err;
 
254
    char    scratch[20];
 
255
    int     scratchLen;
 
256
    char    c = 'W';
 
257
    if (crd_type == eCrd_color_only) {
 
258
        return NO_ERROR;
 
259
    }
 
260
    if (c_type == COLORTYPE_BLACK && crd_type == eCrd_both) {
 
261
        c = 'V';
 
262
    }
 
263
    scratchLen = sprintf(scratch, "\033*b%u%c", length, c);
 
264
    err = this->Send((const BYTE*) scratch, scratchLen);
 
265
    if (err == NO_ERROR && length > 0)
 
266
    {
 
267
        err = this->Send(raster, length);
 
268
    }
 
269
    return err;
 
270
}
 
271
 
 
272
void Pcl3Gui2::configureRasterData()
 
273
{
 
274
    int    i;
 
275
    char   *p;
 
276
    char   sequences[3][64];
 
277
    int    seq_sizes[] = {sizeof(crd_sequence_k), sizeof(crd_sequence_color),
 
278
                          sizeof(crd_sequence_both)};
 
279
    memcpy(sequences[0], crd_sequence_k, seq_sizes[0]);
 
280
    memcpy(sequences[1], crd_sequence_color, seq_sizes[1]);
 
281
    memcpy(sequences[2], crd_sequence_both, seq_sizes[2]);
 
282
    // First, update the resolution entries. Currently, this assumes K & RGB
 
283
    // resolutions are the same.
 
284
    for (i = 0; i < 3; i++) {
 
285
        p = sequences[i] + 10;
 
286
        *p++ = m_pQA->horizontal_resolution / 256;
 
287
        *p++ = m_pQA->horizontal_resolution % 256;
 
288
        *p++ = m_pQA->vertical_resolution / 256;
 
289
        *p++ = m_pQA->vertical_resolution % 256;
 
290
    }
 
291
    p = &sequences[2][18];
 
292
    *p++ = m_pQA->horizontal_resolution / 256;
 
293
    *p++ = m_pQA->horizontal_resolution % 256;
 
294
    *p++ = m_pQA->vertical_resolution / 256;
 
295
    *p++ = m_pQA->vertical_resolution % 256;
 
296
 
 
297
    memcpy(cur_pcl_buffer_ptr, sequences[crd_type], seq_sizes[crd_type]);
 
298
    cur_pcl_buffer_ptr += seq_sizes[crd_type];
 
299
 
 
300
} //configureRasterData
 
301