Code sync
[external/hplip.git] / prnt / hpcups / Pcl3Gui.cpp
1 /*****************************************************************************\
2   Pcl3Gui.cpp : Implementation of Pcl3Gui 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 "Pcl3Gui.h"
33 #include "ColorMatcher.h"
34 #include "Halftoner.h"
35 #include "Mode2.h"
36 #include "resources.h"
37 #include "ColorMaps.h"
38 #include "PrinterCommands.h"
39 #include "Pcl3GuiPrintModes.h"
40
41 Pcl3Gui::Pcl3Gui() : Encapsulator()
42 {
43     m_pPM = NULL;
44     strcpy(m_szLanguage, "PCL3GUI");
45 }
46
47 Pcl3Gui::~Pcl3Gui()
48 {
49 }
50
51 DRIVER_ERROR Pcl3Gui::Configure(Pipeline **pipeline)
52 {
53     Pipeline    *p = NULL;
54     Pipeline    *head;
55     unsigned int width;
56     ColorMatcher *pColorMatcher;
57     Mode2        *pMode2;
58     int          iRows[MAXCOLORPLANES];
59     unsigned int uiResBoost;
60     head = *pipeline;
61
62 /*
63  *  I need a flag in the printmode structure to whether create a CMYGraymap
64  *  and set the ulMap1 to it.
65  */
66
67     if (!selectPrintMode())
68     {
69         dbglog("selectPrintMode failed, PrintMode name = %s", m_pQA->print_mode_name);
70         return UNSUPPORTED_PRINTMODE;
71     }
72     if (m_pPM->BaseResX != m_pQA->horizontal_resolution ||
73         m_pPM->BaseResY != m_pQA->vertical_resolution)
74     {
75         dbglog("Requested resolution not supported with requested printmode");
76     return UNSUPPORTED_PRINTMODE;
77     }
78
79     for (int i = 0; i < MAXCOLORPLANES; i++)
80     {
81         iRows[i] = m_pPM->ResolutionX[i] / m_pPM->BaseResX;
82     }
83     uiResBoost = m_pPM->BaseResX / m_pPM->BaseResY;
84     if (uiResBoost == 0)
85         uiResBoost = 1;
86
87     width = m_pMA->printable_width;
88 //    unsigned int SeedBufferSize = m_pMA->printable_width * 3;
89
90     pColorMatcher = new ColorMatcher(m_pPM->cmap, m_pPM->dyeCount, width);
91     head = new Pipeline(pColorMatcher);
92
93     m_pHalftoner = new Halftoner (m_pPM, width, iRows, uiResBoost, m_pPM->eHT == MATRIX);
94     p = new Pipeline(m_pHalftoner);
95     head->AddPhase(p);
96
97     pMode2 = new Mode2(width);
98     p = new Pipeline(pMode2);
99     head->AddPhase(p);
100     pMode2->myplane = COLORTYPE_COLOR;
101
102     *pipeline = head;
103     return NO_ERROR;
104 }
105
106 DRIVER_ERROR Pcl3Gui::StartPage(JobAttributes *pJA)
107 {
108     DRIVER_ERROR    err = NO_ERROR;
109     char            szStr[256];
110     int             top_margin = 0;
111     page_number++;
112
113 //  Under windows, pJA address may have changed, re-init here.
114
115     m_pJA = pJA;
116     m_pMA = &pJA->media_attributes;
117     m_pQA = &pJA->quality_attributes;
118
119 //  Set media source, type, size and quality modes.
120
121     sprintf(szStr, "\033&l%dH\033&l%dM\033&l%dA\033*o%dM", m_pJA->media_source, m_pQA->media_type,
122             m_pMA->pcl_id, m_pQA->print_quality);
123
124 //  Now add media subtype
125
126     int    i = strlen(szStr);
127     memcpy(szStr+i, MediaSubtypeSeq, sizeof(MediaSubtypeSeq));
128     i += sizeof(MediaSubtypeSeq);
129     szStr[i++] = (char) (m_pQA->media_subtype & 0xFFFF) >> 8;
130     szStr[i++] = (char) m_pQA->media_subtype & 0xFF;
131     addToHeader((const BYTE *) szStr, i);
132
133     if (m_pJA->e_duplex_mode != DUPLEXMODE_NONE) {
134         addToHeader((const BYTE *) EnableDuplex, sizeof(EnableDuplex));
135     }
136
137     configureRasterData();
138
139     if (m_pJA->color_mode != 0) {
140 //        GrayscaleSeq[9] = m_pJA->color_mode;
141         addToHeader((const BYTE *) GrayscaleSeq, 9);
142         *cur_pcl_buffer_ptr++ = (BYTE) m_pJA->color_mode;
143     }
144
145     if (!m_pPM->MixedRes)
146     {
147         sprintf(szStr,"\033&u%dD", m_pPM->BaseResX);
148         addToHeader((const BYTE *) szStr, strlen(szStr));
149         sprintf(szStr,"\033*t%dR", m_pPM->BaseResY);
150         addToHeader((const BYTE *) szStr, strlen(szStr));
151     }
152
153     // another command that helps PCLviewer
154     unsigned int width = m_pMA->printable_width;
155     sprintf(szStr, "\033*r%dS", width);
156     addToHeader((const BYTE *) szStr, strlen(szStr));
157
158 /*
159  *  Custom papersize command
160  */
161
162     if (m_pMA->pcl_id == CUSTOM_MEDIA_SIZE) {
163         short   sWidth, sHeight;
164         BYTE    b1, b2;
165         sWidth  = static_cast<short>(m_pMA->physical_width);
166         sHeight = static_cast<short>(m_pMA->physical_height);
167         memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
168         b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
169         b2 = (BYTE) (sWidth & 0xFF);
170         szStr[8] = b1;
171         szStr[9] = b2;
172         b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
173         b2 = (BYTE) (sHeight & 0xFF);
174         szStr[18] = b1;
175         szStr[19] = b2;
176         addToHeader((const BYTE *) szStr, 20);
177     }
178
179     addToHeader((const BYTE *) grafStart, sizeof(grafStart));
180     addToHeader((const BYTE *) grafMode2, sizeof(grafMode2));
181     addToHeader((const BYTE *) seedSame, sizeof(seedSame));
182
183     top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
184     sprintf(szStr, "\x1b*p%dY", top_margin);
185     addToHeader((const BYTE *) szStr, strlen(szStr));
186
187 //  Now send media pre-load command
188     addToHeader((const BYTE *) "\033&l-2H", 6);
189
190     err = sendBuffer(static_cast<const BYTE *>(pcl_buffer), (cur_pcl_buffer_ptr - pcl_buffer));
191     cur_pcl_buffer_ptr = pcl_buffer;
192     return err;
193 }
194
195 DRIVER_ERROR Pcl3Gui::Encapsulate(RASTERDATA *InputRaster, bool bLastPlane)
196 {
197     DRIVER_ERROR    err = NO_ERROR;
198     char            tmpStr[16];
199     int             iLen;
200     BYTE            c = m_pHalftoner->LastPlane() ? 'W' : 'V';
201
202     iLen = sprintf (tmpStr, "\x1b*b%u%c", InputRaster->rastersize[COLORTYPE_COLOR], c);
203     err = this->Send((const BYTE *) tmpStr, iLen);
204     if (err == NO_ERROR && InputRaster->rastersize[COLORTYPE_COLOR] > 0)
205     {
206         err = this->Send(InputRaster->rasterdata[COLORTYPE_COLOR],
207                          InputRaster->rastersize[COLORTYPE_COLOR]);
208     }
209     return err;
210 }
211
212 int  Pcl3Gui::colorLevels(int color_plane)
213 {
214     int    bit_depth = m_pPM->ColorDepth[color_plane];
215     int    levels = 1;
216     for (int i = 0; i < bit_depth; i++)
217     {
218         levels *= 2;
219     }
220     return levels;
221 }
222
223 void Pcl3Gui::configureRasterData()
224 {
225     if (m_pPM == NULL)
226     {
227         dbglog("configureRasterData: m_pPM is NULL");
228         return;
229     }
230     BYTE    *p = cur_pcl_buffer_ptr;
231
232     *p++ = 0x1b;
233     *p++ = '*';
234     *p++ = 'g';
235     p += sprintf((char *) p, "%d", m_pPM->dyeCount * MAXCOLORPLANES + 2);
236     *p++ = 'W';
237     *p++ = 2;    // crdFormat
238     *p++ = m_pPM->dyeCount;
239     int    start = K;
240     if (m_pPM->dyeCount == 3)
241         start = C;
242
243     int    depth;
244     for (unsigned int color = start; color < (start + m_pPM->dyeCount); color++)
245     {
246         *p++ = m_pPM->ResolutionX[color] / 256;
247         *p++ = m_pPM->ResolutionX[color] % 256;
248         *p++ = m_pPM->ResolutionY[color] / 256;
249         *p++ = m_pPM->ResolutionY[color] % 256;
250         depth = colorLevels(color);
251         *p++ = depth / 256;
252         *p++ = depth % 256;
253     }
254
255     cur_pcl_buffer_ptr = p;
256 } //configureRasterData
257
258 bool Pcl3Gui::selectPrintMode()
259 {
260     if (m_pJA->printer_platform[0] == 0)
261     {
262         dbglog("printer_platform is undefined");
263         return false;
264     }
265     for (unsigned int i = 0; i < sizeof(pcl3_gui_print_modes_table) / sizeof(pcl3_gui_print_modes_table[0]); i++)
266     {
267         if (!strcmp(m_pJA->printer_platform, pcl3_gui_print_modes_table[i].printer_platform_name))
268         {
269             return selectPrintMode(i);
270         }
271     }
272     dbglog("Unsupported printer_platform: %s", m_pJA->printer_platform);
273     return false;
274 }
275
276 bool Pcl3Gui::selectPrintMode(int index)
277 {
278     PrintMode    *p = pcl3_gui_print_modes_table[index].print_modes;
279     for (int i = 0; i < pcl3_gui_print_modes_table[index].count; i++, p++)
280     {
281         if (!strcmp(m_pJA->quality_attributes.print_mode_name, p->name))
282         {
283             m_pPM = p;
284             return true;
285         }
286     }
287     return false;
288 }
289