Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpcups / Pcl3.cpp
1 /*****************************************************************************\
2   Pcl3.cpp : Implementation of Pcl3 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 "Pcl3.h"
33 #include "ColorMatcher.h"
34 #include "Halftoner.h"
35 #include "Mode9.h"
36 #include "resources.h"
37 #include "ColorMaps.h"
38 #include "PrinterCommands.h"
39 #include "Pcl3PrintModes.h"
40
41 Pcl3::Pcl3() : Encapsulator()
42 {
43     m_pPM = NULL;
44     strcpy(m_szLanguage, "PCL3");
45 }
46
47 Pcl3::~Pcl3()
48 {
49 }
50
51 DRIVER_ERROR Pcl3::Configure(Pipeline **pipeline)
52 {
53     Pipeline    *p = NULL;
54     Pipeline    *head;
55     unsigned int width;
56     ColorMatcher *pColorMatcher;
57     Mode9       *pMode9;
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     m_pHalftoner = new Halftoner (m_pPM, width, iRows, uiResBoost, m_pPM->eHT == MATRIX);
93     p = new Pipeline(m_pHalftoner);
94     head->AddPhase(p);
95     pMode9 = new Mode9(width, false);
96     p = new Pipeline(pMode9);
97     head->AddPhase(p);
98     pMode9->myplane = COLORTYPE_COLOR;
99
100     *pipeline = head;
101     return NO_ERROR;
102 }
103
104 DRIVER_ERROR Pcl3::StartPage(JobAttributes *pJA)
105 {
106     DRIVER_ERROR    err = NO_ERROR;
107     char            szStr[256];
108     int             top_margin = 0;
109     page_number++;
110
111 //  Under windows, pJA address may have changed, re-init here.
112
113     m_pJA = pJA;
114     m_pMA = &pJA->media_attributes;
115     m_pQA = &pJA->quality_attributes;
116
117 //  Set media source, type, size and quality modes.
118
119     sprintf(szStr, "\033&l%dH\033&l%dM\033&l%dA\033*o%dM", m_pJA->media_source, m_pQA->media_type,
120             m_pMA->pcl_id, m_pQA->print_quality);
121
122 //  Now add media subtype
123
124     int    i = strlen(szStr);
125     memcpy(szStr+i, MediaSubtypeSeq, sizeof(MediaSubtypeSeq));
126     i += sizeof(MediaSubtypeSeq);
127     szStr[i++] = (char) (m_pQA->media_subtype & 0xFFFF) >> 8;
128     szStr[i++] = (char) m_pQA->media_subtype & 0xFF;
129     addToHeader((const BYTE *) szStr, i);
130
131     configureRasterData();
132
133     addToHeader("\033&u%dD\033*t%dR", m_pPM->BaseResX, m_pPM->BaseResY);
134
135     // another command that helps PCLviewer
136     unsigned int width = m_pMA->printable_width;
137     addToHeader("\033*r%dS", width);
138
139 /*
140  *  Custom papersize command
141  */
142
143     if (m_pMA->pcl_id == CUSTOM_MEDIA_SIZE) {
144         short   sWidth, sHeight;
145         BYTE    b1, b2;
146         sWidth  = static_cast<short>(m_pMA->physical_width);
147         sHeight = static_cast<short>(m_pMA->physical_height);
148         memcpy (szStr, "\x1B*o5W\x0E\x05\x00\x00\x00\x1B*o5W\x0E\x06\x00\x00\x00", 20);
149         b1 = (BYTE) ((sWidth & 0xFF00) >> 8);
150         b2 = (BYTE) (sWidth & 0xFF);
151         szStr[8] = b1;
152         szStr[9] = b2;
153         b1 = (BYTE) ((sHeight & 0xFF00) >> 8);
154         b2 = (BYTE) (sHeight & 0xFF);
155         szStr[18] = b1;
156         szStr[19] = b2;
157         addToHeader((const BYTE *) szStr, 20);
158     }
159
160     if (m_pPM->dyeCount != 3)
161     {
162         addToHeader((const BYTE *) black_extract_off, sizeof(black_extract_off));
163     }
164
165     addToHeader("\x1B&l0L", 5);    // perforation skip off
166
167 /*
168  *  Calculate top margin:
169  *     This is given in terms of text line spacing, the smallest available
170  *     granularity of which is 48.
171  *     There is a starting unprintable distance, which is platform dependent.
172  *  So our formula is: marginvalue = granularity * (startY/verticalres - unprintable)
173  */
174
175     top_margin = m_pMA->printable_start_y - ((m_pJA->mech_offset * m_pQA->actual_vertical_resolution)/1000);
176     top_margin = (top_margin * 48) / m_pQA->actual_vertical_resolution;
177     addToHeader("\x1B&l48D", 6);    // granularity
178     addToHeader("\x1B&l%dE", top_margin);
179     addToHeader((const BYTE *) grafStart, sizeof(grafStart));
180     addToHeader((const BYTE *) grafMode9, sizeof(grafMode9));
181     addToHeader((const BYTE *) seedSame, sizeof(seedSame));
182
183     addToHeader("\x1b*p0Y", 5);
184
185 //  Now send media pre-load command
186     addToHeader((const BYTE *) "\033&l-2H", 6);
187
188     err = Cleanup();
189     return err;
190 }
191
192 DRIVER_ERROR Pcl3::Encapsulate(RASTERDATA *InputRaster, bool bLastPlane)
193 {
194     DRIVER_ERROR    err = NO_ERROR;
195     char            tmpStr[16];
196     int             iLen;
197     BYTE            c = m_pHalftoner->LastPlane() ? 'W' : 'V';
198     iLen = sprintf (tmpStr, "\x1b*b%u%c", InputRaster->rastersize[COLORTYPE_COLOR], c);
199     err = this->Send((const BYTE *) tmpStr, iLen);
200     if (err == NO_ERROR && InputRaster->rastersize[COLORTYPE_COLOR] > 0)
201     {
202         err = this->Send(InputRaster->rasterdata[COLORTYPE_COLOR],
203                          InputRaster->rastersize[COLORTYPE_COLOR]);
204     }
205     return err;
206 }
207
208 int  Pcl3::colorLevels(int color_plane)
209 {
210     int    bit_depth = m_pPM->ColorDepth[color_plane];
211     int    levels = 1;
212     for (int i = 0; i < bit_depth; i++)
213     {
214         levels *= 2;
215     }
216     return levels;
217 }
218
219 void Pcl3::configureRasterData()
220 {
221     if (m_pPM == NULL)
222     {
223         dbglog("configureRasterData: m_pPM is NULL");
224         return;
225     }
226     BYTE    *p = cur_pcl_buffer_ptr;
227
228     *p++ = 0x1b;
229     *p++ = '*';
230     *p++ = 'g';
231     p += sprintf((char *) p, "%d", m_pPM->dyeCount * MAXCOLORPLANES + 2);
232     *p++ = 'W';
233     *p++ = 2;    // crdFormat
234     *p++ = m_pPM->dyeCount;
235     int    start = K;
236     if (m_pPM->dyeCount == 3)
237         start = C;
238
239     int    depth;
240     for (unsigned int color = start; color < (start + m_pPM->dyeCount); color++)
241     {
242         *p++ = m_pPM->ResolutionX[color] / 256;
243         *p++ = m_pPM->ResolutionX[color] % 256;
244         *p++ = m_pPM->ResolutionY[color] / 256;
245         *p++ = m_pPM->ResolutionY[color] % 256;
246         depth = colorLevels(color);
247         *p++ = depth / 256;
248         *p++ = depth % 256;
249     }
250
251     cur_pcl_buffer_ptr = p;
252 } //configureRasterData
253
254 bool Pcl3::selectPrintMode()
255 {
256     if (m_pJA->printer_platform[0] == 0)
257     {
258         dbglog("printer_platform is undefined");
259         return false;
260     }
261     for (unsigned int i = 0; i < sizeof(pcl3_print_modes_table) / sizeof(pcl3_print_modes_table[0]); i++)
262     {
263         if (!strcmp(m_pJA->printer_platform, pcl3_print_modes_table[i].printer_platform_name))
264         {
265             return selectPrintMode(i);
266         }
267     }
268     dbglog("Unsupported printer_platform: %s", m_pJA->printer_platform);
269     return false;
270 }
271
272 bool Pcl3::selectPrintMode(int index)
273 {
274     PrintMode    *p = pcl3_print_modes_table[index].print_modes;
275     for (int i = 0; i < pcl3_print_modes_table[index].count; i++, p++)
276     {
277         if (!strcmp(m_pJA->quality_attributes.print_mode_name, p->name))
278         {
279             m_pPM = p;
280             return true;
281         }
282     }
283     return false;
284 }
285