Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpcups / Pcl3Gui2.cpp
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         cBuf[1] = (m_pMA->top_overspray) & 0xFF;
191         cBuf[0] = (m_pMA->top_overspray) >> 8;
192
193         addToHeader((const BYTE *) TopOverSpraySeq, sizeof(TopOverSpraySeq));
194         addToHeader((const BYTE *) cBuf, 2);
195
196         cBuf[1] = (m_pMA->left_overspray) & 0xFF;
197         cBuf[0] = (m_pMA->left_overspray) >> 8;
198
199         addToHeader((const BYTE *) LeftOverSpraySeq, sizeof(LeftOverSpraySeq));
200         addToHeader((const BYTE *) cBuf, 2);
201     }
202
203 //  Now send media pre-load command
204     addToHeader((const BYTE *) "\033&l-2H", 6);
205
206 //  Before sending speed mech commands, send the current buffer to the printer
207     err = sendBuffer(static_cast<const BYTE *>(pcl_buffer), (cur_pcl_buffer_ptr - pcl_buffer));
208     cur_pcl_buffer_ptr = pcl_buffer;
209
210 //  send speed mech commands
211
212     if (speed_mech_enabled) {
213         addToHeader(speed_mech_cmd, sizeof (speed_mech_cmd));
214         *cur_pcl_buffer_ptr++ = (BYTE) ((m_pJA->total_pages & 0x0000FF00) >> 8);
215         *cur_pcl_buffer_ptr++ = (BYTE) ((m_pJA->total_pages & 0x000000FF));
216         if (page_number < m_pJA->total_pages) {
217             addToHeader(speed_mech_continue, sizeof (speed_mech_continue));
218         }
219         else {
220             addToHeader(speed_mech_end, sizeof (speed_mech_end));
221         }
222     }
223
224     addToHeader((const BYTE *) grafStart, sizeof(grafStart));
225
226     if (!m_pJA->print_borderless) {
227         top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
228     }
229     addToHeader("\x1b*p%dY", top_margin);
230     return err;
231 }
232
233 DRIVER_ERROR Pcl3Gui2::Encapsulate(RASTERDATA *InputRaster, bool bLastPlane)
234 {
235     DRIVER_ERROR    err;
236     if (crd_type != eCrd_color_only) {
237         err = encapsulateRaster(InputRaster->rasterdata[COLORTYPE_BLACK], InputRaster->rastersize[COLORTYPE_BLACK], COLORTYPE_BLACK);
238     }
239     if (crd_type != eCrd_black_only) {
240         err = encapsulateRaster(InputRaster->rasterdata[COLORTYPE_COLOR], InputRaster->rastersize[COLORTYPE_COLOR], COLORTYPE_COLOR);
241     }
242     return err;
243 }
244
245 DRIVER_ERROR Pcl3Gui2::encapsulateRaster(BYTE *raster, unsigned int length, COLORTYPE c_type)
246 {
247     DRIVER_ERROR     err;
248     char    scratch[20];
249     int     scratchLen;
250     char    c = 'W';
251     if (crd_type == eCrd_color_only) {
252         return NO_ERROR;
253     }
254     if (c_type == COLORTYPE_BLACK && crd_type == eCrd_both) {
255         c = 'V';
256     }
257     scratchLen = sprintf(scratch, "\033*b%u%c", length, c);
258     err = this->Send((const BYTE*) scratch, scratchLen);
259     if (err == NO_ERROR && length > 0)
260     {
261         err = this->Send(raster, length);
262     }
263     return err;
264 }
265
266 void Pcl3Gui2::configureRasterData()
267 {
268     int    i;
269     char   *p;
270     char   sequences[3][64];
271     int    seq_sizes[] = {sizeof(crd_sequence_k), sizeof(crd_sequence_color),
272                           sizeof(crd_sequence_both)};
273     memcpy(sequences[0], crd_sequence_k, seq_sizes[0]);
274     memcpy(sequences[1], crd_sequence_color, seq_sizes[1]);
275     memcpy(sequences[2], crd_sequence_both, seq_sizes[2]);
276     // First, update the resolution entries. Currently, this assumes K & RGB
277     // resolutions are the same.
278     for (i = 0; i < 3; i++) {
279         p = sequences[i] + 10;
280         *p++ = m_pQA->horizontal_resolution / 256;
281         *p++ = m_pQA->horizontal_resolution % 256;
282         *p++ = m_pQA->vertical_resolution / 256;
283         *p++ = m_pQA->vertical_resolution % 256;
284     }
285     p = &sequences[2][18];
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     memcpy(cur_pcl_buffer_ptr, sequences[crd_type], seq_sizes[crd_type]);
292     cur_pcl_buffer_ptr += seq_sizes[crd_type];
293
294 } //configureRasterData
295