1
2 /*
3 *
4 * Print plug-in Lexmark driver for the GIMP.
5 *
6 * Copyright 2000 Richard Wisenoecker (richard.wisenoecker@gmx.at) and
7 * Alwin Stolk (p.a.stolk@tmx.nl)
8 *
9 * The plug-in is based on the code of the CANON BJL plugin for the GIMP
10 * of Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu).
11 *
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 */
26
27 /*
28 * This file must include only standard C header files. The core code must
29 * compile on generic platforms that don't support glib, gimp, gtk, etc.
30 */
31
32 /*
33 * !!! IMPORTANT !!! Some short information: Border and page offsets
34 * are defined in 1/72 DPI. This mean, that the parameter defined at
35 * lexmark_cap_t which defines positions are in 1/72 DPI. At
36 * lexmark_print the unit will be changed dependent on the printer,
37 * according to the value defined at lexmark_cap_t.x_raster_res and
38 * lexmark_cap_t.y_raster_res. These two parameters are specifying the
39 * resolution used for positioning the printer head (it is not the
40 * resolution used for printing!).
41 */
42
43 /* TODO-LIST
44 *
45 * * implement the left border
46 *
47 */
48
49 /*#define DEBUG 1*/
50 #define USEEPSEWAVE 1
51
52 #ifdef __GNUC__
53 #define inline __inline__
54 #endif
55
56 #ifdef HAVE_CONFIG_H
57 #include <config.h>
58 #endif
59 #include <gutenprint/gutenprint.h>
60 #include <gutenprint/gutenprint-intl-internal.h>
61 #include "gutenprint-internal.h"
62 #include <string.h>
63 #ifdef DEBUG
64 #include <stdio.h>
65 #endif
66
67 #define STP_ECOLOR_LC 4
68 #define STP_ECOLOR_LM 5
69 #define STP_ECOLOR_LY 6
70
71 #define false 0
72 #define true 1
73
74 #define max(a, b) ((a > b) ? (a) : (b))
75 #define INCH(x) (72 * x)
76
77 static const stp_dotsize_t single_dotsize[] =
78 {
79 { 0x1, 1.0 }
80 };
81
82 static const stp_shade_t photo_dither_shades[] =
83 {
84 { 1.0000, 1, single_dotsize },
85 { 0.3333, 1, single_dotsize },
86 };
87
88
89 typedef enum Lex_model { m_lex7500, m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
90
91 #define NCHANNELS (7)
92
93 typedef union { /* Offsets from the start of each line */
94 unsigned long v[NCHANNELS]; /* (really pass) */
95 struct { /* IMPORTANT: order corresponds to STP_ECOLOR_* */
96 unsigned long k;
97 unsigned long c;
98 unsigned long m;
99 unsigned long y;
100 unsigned long C;
101 unsigned long M;
102 unsigned long Y;
103 } p;
104 } lexmark_lineoff_t;
105
106 typedef union { /* Base pointers for each pass */
107 unsigned char *v[NCHANNELS];
108 struct { /* IMPORTANT: order corresponds to STP_ECOLOR_* */
109 unsigned char *k;
110 unsigned char *c;
111 unsigned char *m;
112 unsigned char *y;
113 unsigned char *C;
114 unsigned char *M;
115 unsigned char *Y;
116 } p;
117 } lexmark_linebufs_t;
118
119
120
121 #ifdef DEBUG
122 typedef struct testdata {
123 FILE *ifile;
124 int x, y, cols, deep;
125 char colchar[16];
126 char *input_line;
127 } testdata;
128
129 const stp_vars_t **dbgfileprn;
130 int lex_show_lcount, lex_show_length;
131
132 const stp_vars_t *lex_open_tmp_file();
133 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length);
134 static void testprint(testdata *td);
135 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
136 #endif
137
138 static void
139 flush_pass(stp_vars_t *v, int passno, int vertical_subpass);
140
141 /*** resolution specific parameters */
142 #define DPI300 0
143 #define DPI600 1
144 #define DPI1200 2
145 #define DPI2400 3
146 #define DPItest 4
147
148 #define V_NOZZLE_MASK 0x3
149 #define H_NOZZLE_MASK 0xc
150 #define NOZZLE_MASK 0xf
151
152 #define PRINT_MODE_300 0x100
153 #define PRINT_MODE_600 0x200
154 #define PRINT_MODE_1200 0x300
155 #define PRINT_MODE_2400 0x400
156
157 #define COLOR_MODE_K 0x1000
158 #define COLOR_MODE_C 0x2000
159 #define COLOR_MODE_Y 0x4000
160 #define COLOR_MODE_M 0x8000
161 #define COLOR_MODE_LC 0x10000
162 #define COLOR_MODE_LY 0x20000
163 #define COLOR_MODE_LM 0x40000
164 #define COLOR_MODE_CMYK (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
165 #define COLOR_MODE_CMY (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
166 #define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
167 #define COLOR_MODE_CcMcY (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
168
169 #define COLOR_MODE_MASK 0x7f000
170 #define PRINT_MODE_MASK 0xf00
171 #define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
172
173 #define BWR 0
174 #define BWL 1
175 #define CR 2
176 #define CL 3
177
178
179 static const char standard_sat_adjustment[] =
180 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
181 "<gutenprint>\n"
182 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
183 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
184 /* C */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* B */
185 /* B */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* M */
186 /* M */ "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 " /* R */
187 /* R */ "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 " /* Y */
188 /* Y */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* G */
189 /* G */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* C */
190 "</sequence>\n"
191 "</curve>\n"
192 "</gutenprint>\n";
193
194 static const char standard_lum_adjustment[] =
195 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
196 "<gutenprint>\n"
197 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
198 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
199 /* C */ "0.65 0.67 0.70 0.72 0.77 0.80 0.82 0.85 " /* B */
200 /* B */ "0.87 0.86 0.82 0.79 0.79 0.82 0.85 0.88 " /* M */
201 /* M */ "0.92 0.95 0.96 0.97 0.97 0.97 0.96 0.96 " /* R */
202 /* R */ "0.96 0.97 0.97 0.98 0.99 1.00 1.00 1.00 " /* Y */
203 /* Y */ "1.00 0.97 0.95 0.94 0.93 0.92 0.90 0.86 " /* G */
204 /* G */ "0.79 0.76 0.71 0.68 0.68 0.68 0.68 0.66 " /* C */
205 "</sequence>\n"
206 "</curve>\n"
207 "</gutenprint>\n";
208
209 static const char standard_hue_adjustment[] =
210 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
211 "<gutenprint>\n"
212 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
213 "<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
214 /* C */ "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 " /* B */
215 /* B */ "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 " /* M */
216 /* M */ "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 " /* R */
217 /* R */ "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 " /* Y */
218 /* Y */ "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 " /* G */
219 /* G */ "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 " /* C */
220 "</sequence>\n"
221 "</curve>\n"
222 "</gutenprint>\n";
223
224
225 /* Codes for possible ink-tank combinations.
226 * Each combo is represented by the colors that can be used with
227 * the installed ink-tank(s)
228 * Combinations of the codes represent the combinations allowed for a model
229 */
230 #define LEXMARK_INK_K 1
231 #define LEXMARK_INK_CMY 2
232 #define LEXMARK_INK_CMYK 4
233 #define LEXMARK_INK_CcMmYK 8
234 #define LEXMARK_INK_CcMmYy 16
235 #define LEXMARK_INK_CcMmYyK 32
236
237 #define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
238 LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
239
240 #define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
241 LEXMARK_INK_CcMmYyK)
242
243 /* document feeding */
244 #define LEXMARK_SLOT_ASF1 1
245 #define LEXMARK_SLOT_ASF2 2
246 #define LEXMARK_SLOT_MAN1 4
247 #define LEXMARK_SLOT_MAN2 8
248
249 /* model peculiarities */
250 #define LEXMARK_CAP_DMT 1<<0 /* Drop Modulation Technology */
251 #define LEXMARK_CAP_MSB_FIRST 1<<1 /* how to send data */
252 #define LEXMARK_CAP_CMD61 1<<2 /* uses command #0x61 */
253 #define LEXMARK_CAP_CMD6d 1<<3 /* uses command #0x6d */
254 #define LEXMARK_CAP_CMD70 1<<4 /* uses command #0x70 */
255 #define LEXMARK_CAP_CMD72 1<<5 /* uses command #0x72 */
256
257
258 static const int lr_shift_color[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd inkjet (related to resolution) */
259 static const int lr_shift_black[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd inkjet (related to resolution) */
260
261 static const stp_parameter_t the_parameters[] =
262 {
263 {
264 "PageSize", N_("Page Size"), "Color=No,Category=Basic Printer Setup",
265 N_("Size of the paper being printed to"),
266 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
267 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
268 },
269 {
270 "MediaType", N_("Media Type"), "Color=Yes,Category=Basic Printer Setup",
271 N_("Type of media (plain paper, photo paper, etc.)"),
272 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
273 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
274 },
275 {
276 "InputSlot", N_("Media Source"), "Color=No,Category=Basic Printer Setup",
277 N_("Source (input slot) of the media"),
278 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
279 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
280 },
281 {
282 "Resolution", N_("Resolution"), "Color=Yes,Category=Basic Printer Setup",
283 N_("Resolution and quality of the print"),
284 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
285 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
286 },
287 {
288 "InkType", N_("Ink Type"), "Color=Yes,Category=Advanced Printer Setup",
289 N_("Type of ink in the printer"),
290 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
291 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
292 },
293 {
294 "InkChannels", N_("Ink Channels"), "Color=Yes,Category=Advanced Printer Functionality",
295 N_("Ink Channels"),
296 STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
297 STP_PARAMETER_LEVEL_INTERNAL, 0, 0, STP_CHANNEL_NONE, 0, 0
298 },
299 {
300 "PrintingMode", N_("Printing Mode"), "Color=Yes,Category=Core Parameter",
301 N_("Printing Output Mode"),
302 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
303 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0
304 },
305 };
306
307 static const int the_parameter_count =
308 sizeof(the_parameters) / sizeof(const stp_parameter_t);
309
310 typedef struct
311 {
312 const stp_parameter_t param;
313 double min;
314 double max;
315 double defval;
316 int color_only;
317 } float_param_t;
318
319 static const float_param_t float_parameters[] =
320 {
321 {
322 {
323 "CyanDensity", N_("Cyan Density"), "Color=Yes,Category=Output Level Adjustment",
324 N_("Adjust the cyan density"),
325 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
326 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
327 }, 0.0, 2.0, 1.0, 1
328 },
329 {
330 {
331 "MagentaDensity", N_("Magenta Density"), "Color=Yes,Category=Output Level Adjustment",
332 N_("Adjust the magenta density"),
333 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
334 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
335 }, 0.0, 2.0, 1.0, 1
336 },
337 {
338 {
339 "YellowDensity", N_("Yellow Density"), "Color=Yes,Category=Output Level Adjustment",
340 N_("Adjust the yellow density"),
341 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
342 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
343 }, 0.0, 2.0, 1.0, 1
344 },
345 {
346 {
347 "BlackDensity", N_("Black Density"), "Color=Yes,Category=Output Level Adjustment",
348 N_("Adjust the black density"),
349 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
350 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
351 }, 0.0, 2.0, 1.0, 1
352 },
353 {
354 {
355 "LightCyanTrans", N_("Light Cyan Transition"), "Color=Yes,Category=Advanced Ink Adjustment",
356 N_("Light Cyan Transition"),
357 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
358 STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0
359 }, 0.0, 5.0, 1.0, 1
360 },
361 {
362 {
363 "LightMagentaTrans", N_("Light Magenta Transition"), "Color=Yes,Category=Advanced Ink Adjustment",
364 N_("Light Magenta Transition"),
365 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
366 STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0
367 }, 0.0, 5.0, 1.0, 1
368 },
369 };
370
371 static const int float_parameter_count =
372 sizeof(float_parameters) / sizeof(const float_param_t);
373
374 /* returns the offset of the first jet when printing in the other direction */
get_lr_shift(int mode)375 static int get_lr_shift(int mode)
376 {
377
378 const int *ptr_lr_shift;
379
380 /* K could only be present if black is printed only. */
381 if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
382 ptr_lr_shift = lr_shift_black;
383 } else {
384 ptr_lr_shift = lr_shift_color;
385 }
386
387 switch(mode & PRINT_MODE_MASK) {
388 case PRINT_MODE_300:
389 return ptr_lr_shift[0];
390 break;
391 case PRINT_MODE_600:
392 return ptr_lr_shift[1];
393 break;
394 case PRINT_MODE_1200:
395 return ptr_lr_shift[2];
396 break;
397 case PRINT_MODE_2400:
398 return ptr_lr_shift[2];
399 break;
400 }
401 return 0;
402 }
403
404
405 /*
406 * head offsets for z52:
407 *
408 * black black color photo
409 * cartridge cartridge cartridge cartridge
410 * mode I mode II
411 *
412 * v +-----+ -- +-----+ ---
413 * --- +-----+ --- v | | ^ | | ^
414 * ^ | | --- +-----+ --- -- | C | 64 | LC | |
415 * | | | ^ | | ^ 40 | | v v | | |
416 * | | | | | | -- +-----+ -- -- +-----+ |
417 * | | | | | | ^ 28 |
418 * | | | | | | +-----+ -- -- +-----+ |
419 * | | | | | | | ^ ^ | | |
420 * 208 | K | | K | 192 | M | 64 | LM | 240
421 * | | | | | | | v v | | |
422 * | | | | | | +-----+ -- -- +-----+ |
423 * | | | | | | v 28 |
424 * | | | | | | -- +-----+ -- -- +-----+ |
425 * | | | | | v 40 | | ^ ^ | | |
426 * v | | +-----+ --- -- | Y | 64 | K | |
427 * --- +-----+ ^ | | v | | v
428 * +-----+ -- +-----+ ---
429 *
430 */
431
432 static const int head_offset_cmyk[] =
433 {70, 368, 184, 0, 368, 184, 0}; /* k, m, c, y, M, C, Y */
434 /* the head_offset_cmy is needed because the dithering code is going into troubles if there is an offset different from 0 for the unused black color */
435 static const int head_offset_cmy[] =
436 {0, 368, 184, 0, 368, 184, 0}; /* k, m, c, y, M, C, Y */
437 static const int head_offset_cCmMyk[] =
438 {0, 368, 184, 0, 368, 184, 0}; /* k, m, c, y, M, C, Y */
439
440
441
442
443 /**************************************************************************/
444 /**** Data structures which are describing printer specific parameters ****/
445
446 /* resolution specific parameters (substructure of lexmark_cap_t) */
447 typedef struct {
448 const char *name;
449 const char *text;
450 int hres;
451 int vres;
452 int softweave;
453 int vertical_passes;
454 int vertical_oversample;
455 int unidirectional; /* print bi/unidirectional */
456 int resid; /* resolution id */
457 } lexmark_res_t;
458
459 #define LEXM_RES_COUNT 30
460 typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
461
462
463 /* ink type parameters (substructure of lexmark_cap_t) */
464 typedef struct {
465 int ncolors;
466 unsigned int used_colors; /* specifies the head colors to be used (e.g. COLOR_MODE_K */
467 unsigned int pass_length; /* available jets for one color */
468 int v_top_head_offset; /* offset from top, where the first jet will be found */
469 int h_catridge_offset; /* horizontal offset of cartridges */
470 int h_direction_offset; /* Offset when printing in the other direction */
471 const int *head_offset; /* specifies the offset of head colors */
472 } lexmark_inkparam_t;
473
474 typedef struct
475 {
476 const char *name;
477 const char *text;
478 lexmark_inkparam_t ink_parameter[2];
479 } lexmark_inkname_t;
480
481
482 /* main structure which describes all printer specific parameters */
483 typedef struct {
484 Lex_model model; /* printer model */
485 int max_paper_width; /* maximum printable paper size in 1/72 inch */
486 int max_paper_height;
487 int min_paper_width; /* Maximum paper width, in points */
488 int min_paper_height; /* Maximum paper height, in points */
489 int max_xdpi;
490 int max_ydpi;
491 int max_quality;
492 int border_left; /* unit is 72 DPI */
493 int border_right;
494 int border_top;
495 int border_bottom;
496 int inks; /* installable cartridges (LEXMARK_INK_*) */
497 int slots; /* available paperslots */
498 int features; /* special bjl settings */
499 /*** printer internal parameters ***/
500 /* the unit of the following parameters is identical with max phys unit of the printer */
501 int offset_left_border; /* Offset to the left paper border (== border_left=0) */
502 int offset_top_border; /* Offset to the top paper border (== border_top=0) */
503 int x_raster_res; /* horizontal resolution for positioning of the printer head in DPI */
504 int y_raster_res; /* vertical resolution for positioning of the printer head in DPI */
505 const lexmark_res_t_array *res_parameters; /* resolution specific parameters; last entry has resid = -1 */
506 const lexmark_inkname_t *ink_types; /* type of supported inks */
507 const char *lum_adjustment;
508 const char *hue_adjustment;
509 const char *sat_adjustment;
510 } lexmark_cap_t;
511
512
513 /*****************************************************************/
514 /**** initialize printer specific data structures ****/
515
516 /*
517 * z52 specific parameters
518 */
519 #define LX_Z52_300_DPI 1
520 #define LX_Z52_600_DPI 3
521 #define LX_Z52_1200_DPI 4
522 #define LX_Z52_2400_DPI 5
523
524 #define LX_Z52_COLOR_PRINT 0
525 #define LX_Z52_BLACK_PRINT 1
526
527 #define LX_PSHIFT 0x13
528 #define LX_Z52_COLOR_MODE_POS 0x9
529 #define LX_Z52_RESOLUTION_POS 0x7
530 #define LX_Z52_PRINT_DIRECTION_POS 0x8
531
532 /*static const int IDX_Z52ID =2;*/
533 static const int IDX_SEQLEN=3;
534
535 /*
536 head:
537 1 .. black,
538 0 .. color
539
540 resolution:
541 1 .. 300 dpi (for black ?)
542 2 .. like 1
543 3 .. 600 dpi (color&black)
544 4 .. 1200 dpi
545 5 .. ? like 1
546 */
547
548 #define LXM_Z52_HEADERSIZE 34
549 static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
550 {
551 0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF, /* number of packets ---- vvvvvvvvv */
552 0x01,0x01,0x01,0x1a,0x03,0x01, /* 0x7-0xc: resolution, direction, head */
553 0x03,0x60, /* 0xd-0xe HE */
554 0x04,0xe0, /* 0xf-0x10 HS vertical pos */
555 0x19,0x5c, /* 0x11-0x12 */
556 0x0,0x0, /* 0x13-0x14 VO between packages*/
557 0x0,0x80, /* 0x15-0x16 */
558 0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0 /* 0x17-0x21 */
559 };
560
561 #define LXM_Z42_HEADERSIZE 34
562 static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
563 {
564 0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
565 0x01,0x01,0x01,0x18,0x00,0x01,0x00,
566 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
567 0x00,0x00,0x00,0x00,0x00,0x00,0x00,
568 0x00,0x00,0x00,0x00,0x00,0x00
569 };
570
571
572 static const lexmark_res_t_array lexmark_reslist_z52 = /* LEXM_RES_COUNT entries are allowed !! */
573 {
574 /* name hres vres softw v_pass overs unidir resid */
575 { "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
576 { "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
577 { "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
578 { "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
579 { "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
580 { "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
581 { "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
582 { "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
583 { "2400x1200dpi", N_ ("2400 DPI x 1200 DPI"), 2400, 1200, 1, 1, 1, 0, DPI1200},
584 { "2400x1200hq", N_ ("2400 DPI x 1200 DPI high quality"), 2400, 1200, 1, 1, 1, 0, DPI600 },
585 { "2400x1200hq2", N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200, 1, 1, 1, 0, DPI300},
586 #ifdef DEBUG
587 { "testprint", N_ ("test print"), 1200, 1200, 1, 1, 1, 0, DPItest},
588 #endif
589 { "", "", 0, 0, 0, 0, 0, -1 }
590 };
591
592
593 static const lexmark_inkname_t ink_types_z52[] =
594 {
595 /* output_type ncolors used_colors pass_length v_top_head_offset
596 * h_cartridge_offset
597 * h_direction_offset
598 * head_offset */
599 { "CMYK", N_("Four Color Standard"),
600 {{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
601 { 4, COLOR_MODE_CMYK, 192/3, 0, 0, 10, head_offset_cmyk }}},
602 { "RGB", N_("Three Color Composite"),
603 {{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk }, /* we ignore CMY, use black */
604 { 4, COLOR_MODE_CMY, 192/3, 0, 0, 10, head_offset_cmy }}},
605 { "PhotoCMYK", N_("Six Color Photo"),
606 {{ 1, COLOR_MODE_K, 192/3, 0, 0, 10, head_offset_cCmMyk },
607 { 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 10, head_offset_cCmMyk }}},
608 { "PhotoCMY", N_("Five Color Photo Composite"),
609 {{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cCmMyk },
610 { 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 10, head_offset_cCmMyk }}}, /* we ignore CMY, use black */
611 { "Gray", N_("Black"),
612 {{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
613 { 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk }}},
614 { NULL, NULL }
615 };
616
617
618
619 /*
620 * 3200 specific stuff
621 */
622 #define LXM3200_LEFTOFFS 6254
623 #define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
624
625 static int lxm3200_headpos = 0;
626 static int lxm3200_linetoeject = 0;
627
628 #define LXM_3200_HEADERSIZE 24
629 static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
630 {
631 0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
634 };
635
636 static inline int
lexmark_calc_3200_checksum(unsigned char * data)637 lexmark_calc_3200_checksum(unsigned char *data)
638 {
639 int ck, i;
640
641 ck = 0;
642 for(i=1; i<7; i++)ck += data[i];
643
644 return(ck & 255);
645 }
646
647
648 static const lexmark_res_t_array lexmark_reslist_3200 = /* LEXM_RES_COUNT entries are allowed !! */
649 {
650 /* name hres vres softw v_pass overs unidir resid */
651 { "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
652 { "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
653 { "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
654 { "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
655 { "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
656 { "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
657 { "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
658 { "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
659 { "", "", 0, 0, 0, 0, 0, -1 }
660 };
661
662
663 static const lexmark_inkname_t ink_types_3200[] =
664 {
665 /* output_type ncolors used_colors pass_length v_top_head_offset
666 * h_cartridge_offset
667 * h_direction_offset
668 * head_offset */
669 { "CMYK", N_("Four Color Standard"),
670 {{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
671 { 4, COLOR_MODE_CMYK, 192/3, 0, 0, 12, head_offset_cmyk }}},
672 { "RGB", N_("Three Color Composite"),
673 {{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk }, /* we ignore CMY, use black */
674 { 4, COLOR_MODE_CMY, 192/3, 0, 0, 12, head_offset_cmy }}},
675 { "PhotoCMYK", N_("Six Color Photo"),
676 {{ 1, COLOR_MODE_K, 192/3, 0, 0, 12, head_offset_cCmMyk },
677 { 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
678 { "PhotoCMY", N_("Five Color Photo Composite"),
679 {{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cCmMyk }, /* we ignore CMY, use black */
680 { 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
681 { NULL, NULL }
682 };
683
684
685
686
687
688 /* main structure */
689 static const lexmark_cap_t lexmark_model_capabilities[] =
690 {
691 /* default settings for unknown models */
692
693 { (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
694
695 /* tested models */
696
697 { /* Lexmark z52 */
698 m_z52,
699 618, 936, /* max paper size *//* 8.58" x 13 " */
700 INCH(2), INCH(4), /* min paper size */
701 2400, 1200, 2, /* max resolution */
702 0, 0, 5, 15, /* 15 36 border l,r,t,b unit is 1/72 DPI */
703 LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
704 LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
705 LEXMARK_CAP_DMT,
706 /*** printer internal parameters ***/
707 20, /* real left paper border */
708 123, /* real top paper border */
709 2400, /* horizontal resolution of 2400 dpi for positioning */
710 1200, /* use a vertical resolution of 1200 dpi for positioning */
711 &lexmark_reslist_z52, /* resolution specific parameters of z52 */
712 ink_types_z52, /* supported inks */
713 standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
714 },
715 { /* Lexmark z42 */
716 m_z42,
717 618, 936, /* max paper size *//* 8.58" x 13 " */
718 INCH(2), INCH(4), /* min paper size */
719 2400, 1200, 2, /* max resolution */
720 0, 0, 5, 41, /* border l,r,t,b unit is 1/72 DPI */
721 LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
722 LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
723 LEXMARK_CAP_DMT,
724 /*** printer internal parameters ***/
725 20, /* real left paper border */
726 123, /* real top paper border */
727 2400, /* horizontal resolution of 2400 dpi for positioning */
728 1200, /* use a vertical resolution of 1200 dpi for positioning */
729 &lexmark_reslist_z52, /* resolution specific parameters of z52 */
730 ink_types_z52, /* supported inks */
731 standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
732 },
733 { /* Lexmark 3200 */
734 m_3200,
735 618, 936, /* 8.58" x 13 " */
736 INCH(2), INCH(4), /* min paper size */
737 1200, 1200, 2,
738 11, 9, 10, 18,
739 LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
740 LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
741 LEXMARK_CAP_DMT,
742 /*** printer internal parameters ***/
743 0, /* real left paper border */
744 300, /* real top paper border */
745 1200, /* horizontal resolution of ?? dpi for positioning */
746 1200, /* use a vertical resolution of 1200 dpi for positioning */
747 &lexmark_reslist_3200, /* resolution specific parameters of 3200 */
748 ink_types_3200, /* supported inks */
749 standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
750 },
751 { /* */
752 m_lex7500,
753 618, 936, /* 8.58" x 13 " */
754 INCH(2), INCH(4), /* min paper size */
755 2400, 1200, 2,
756 11, 9, 10, 18,
757 LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
758 LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
759 LEXMARK_CAP_DMT,
760 /*** printer internal parameters ***/
761 0, /* real left paper border */
762 300, /* real top paper border */
763 1200, /* horizontal resolution of ??? dpi for positioning */
764 1200, /* use a vertical resolution of 1200 dpi for positioning */
765 &lexmark_reslist_3200, /* resolution specific parameters of ?? */
766 ink_types_3200, /* supported inks */
767 standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
768 },
769 };
770
771
772
773
774
775 typedef struct lexm_privdata_weave {
776 const lexmark_inkparam_t *ink_parameter;
777 int bidirectional; /* tells us if we are allowed to print bidirectional */
778 int direction; /* stores the last direction or print head */
779 int hoffset;
780 int model;
781 int width;
782 int ydpi;
783 int xdpi;
784 int physical_xdpi;
785 int last_pass_offset;
786 int jets;
787 int bitwidth;
788 int ncolors;
789 int horizontal_weave;
790 unsigned char *outbuf;
791 } lexm_privdata_weave;
792
793
794 /*
795 * internal functions
796 */
model_to_index(int model)797 static int model_to_index(int model)
798 {
799 int i;
800 int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
801 for (i=0; i<models; i++) {
802 if (lexmark_model_capabilities[i].model == model) {
803 return i;
804 }
805 }
806 return -1;
807 }
808
809
810 static const lexmark_cap_t *
lexmark_get_model_capabilities(const stp_vars_t * v,int model)811 lexmark_get_model_capabilities(const stp_vars_t *v, int model)
812 {
813 int i = model_to_index(model);
814
815 if (i != -1) {
816 return &(lexmark_model_capabilities[i]);
817 }
818 stp_dprintf(STP_DBG_LEXMARK, v,
819 "lexmark: model %d not found in capabilities list.\n",model);
820 return &(lexmark_model_capabilities[0]);
821 }
822
823
824
825 typedef struct
826 {
827 const char *name;
828 const char *text;
829 int paper_feed_sequence;
830 int platen_gap;
831 double base_density;
832 double k_lower_scale;
833 double k_upper;
834 double cyan;
835 double magenta;
836 double yellow;
837 double p_cyan;
838 double p_magenta;
839 double p_yellow;
840 double saturation;
841 double gamma;
842 int feed_adjustment;
843 int vacuum_intensity;
844 int paper_thickness;
845 const char *hue_adjustment;
846 const char *lum_adjustment;
847 const char *sat_adjustment;
848 } paper_t;
849
850
851
852 static const paper_t lexmark_paper_list[] =
853 {
854 { "Plain", N_("Plain Paper"),
855 1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
856 1, 1.0, 0x6b, 0x1a, 0x01,
857 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
858 { "GlossyFilm", N_("Glossy Film"),
859 3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
860 1, 1.0, 0x6d, 0x00, 0x01,
861 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
862 { "Transparency", N_("Transparencies"),
863 3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
864 1.0, 1.0, 0x6d, 0x00, 0x02,
865 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
866 { "Envelope", N_("Envelopes"),
867 4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
868 1, 1.0, 0x6b, 0x1a, 0x01,
869 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
870 { "Matte", N_("Matte Paper"),
871 7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
872 1, 1.0, 0x00, 0x00, 0x02,
873 standard_hue_adjustment, standard_sat_adjustment, standard_sat_adjustment},
874 { "Inkjet", N_("Inkjet Paper"),
875 7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
876 1, 1.0, 0x6b, 0x1a, 0x01,
877 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
878 { "Coated", N_("Photo Quality Inkjet Paper"),
879 7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
880 1, 1.0, 0x6b, 0x1a, 0x01,
881 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
882 { "Photo", N_("Photo Paper"),
883 8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
884 1, 1.0, 0x67, 0x00, 0x02,
885 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
886 { "GlossyPhoto", N_("Premium Glossy Photo Paper"),
887 8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
888 1, 1.0, 0x80, 0x00, 0x02,
889 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
890 { "Luster", N_("Premium Luster Photo Paper"),
891 8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
892 1.0, 1.0, 0x80, 0x00, 0x02,
893 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
894 { "GlossyPaper", N_("Photo Quality Glossy Paper"),
895 6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
896 1.0, 1.0, 0x6b, 0x1a, 0x01,
897 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
898 { "Ilford", N_("Ilford Heavy Paper"),
899 8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
900 1, 1.0, 0x80, 0x00, 0x02,
901 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
902 { "Other", N_("Other"),
903 0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
904 1, 1.0, 0x6b, 0x1a, 0x01,
905 standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
906 };
907
908 static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
909
910 static const lexmark_inkname_t *
lexmark_get_ink_type(const char * name,int printing_color,const lexmark_cap_t * caps)911 lexmark_get_ink_type(const char *name, int printing_color, const lexmark_cap_t * caps)
912 {
913 int i = 0;
914 const lexmark_inkname_t *ink_type = caps->ink_types;
915
916 if (name)
917 for (i=0; ((ink_type[i].name != NULL) &&
918 (strcmp(name, ink_type[i].name) != 0)); i++) ;
919 return &(ink_type[i]);
920
921 }
922
923 static const lexmark_inkparam_t *
lexmark_get_ink_parameter(const char * name,int printing_color,const lexmark_cap_t * caps,const stp_vars_t * nv)924 lexmark_get_ink_parameter(const char *name, int printing_color, const lexmark_cap_t * caps, const stp_vars_t *nv)
925 {
926 const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, printing_color, caps);
927
928 if (ink_type->name == NULL) {
929 return (NULL); /* not found ! */
930 }
931
932 return &(ink_type->ink_parameter[printing_color]);
933 }
934
935
936 static const paper_t *
get_media_type(const char * name,const lexmark_cap_t * caps)937 get_media_type(const char *name, const lexmark_cap_t * caps)
938 {
939 int i;
940 if (name)
941 {
942 for (i = 0; i < paper_type_count; i++)
943 {
944 if (!strcmp(name, lexmark_paper_list[i].name))
945 return &(lexmark_paper_list[i]);
946 }
947 }
948 return NULL;
949 }
950
951 #pragma GCC diagnostic push
952 #pragma GCC diagnostic ignored "-Wunused-function"
953 #pragma GCC diagnostic ignored "-Wpedantic"
954 static inline int
lexmark_source_type(const stp_vars_t * v,const char * name,const lexmark_cap_t * caps)955 lexmark_source_type(const stp_vars_t *v, const char *name, const lexmark_cap_t * caps)
956 {
957 if (name)
958 {
959 if (!strcmp(name,"Auto")) return 4;
960 if (!strcmp(name,"Manual")) return 0;
961 if (!strcmp(name,"ManualNP")) return 1;
962 }
963
964 stp_dprintf(STP_DBG_LEXMARK, v,
965 "lexmark: Unknown source type '%s' - reverting to auto\n",name);
966
967 return 4;
968 }
969 #pragma GCC diagnostic pop
970
971
972
973 /*******************************
974 lexmark_head_offset
975 *******************************/
976 static const lexmark_lineoff_t *
lexmark_head_offset(const stp_vars_t * v,int ydpi,const char * ink_type,const lexmark_cap_t * caps,const lexmark_inkparam_t * ink_parameter,lexmark_lineoff_t * lineoff_buffer)977 lexmark_head_offset(const stp_vars_t *v,
978 int ydpi, /* i */
979 const char *ink_type, /* i */
980 const lexmark_cap_t * caps, /* i */
981 const lexmark_inkparam_t *ink_parameter, /* i */
982 lexmark_lineoff_t *lineoff_buffer) /* o */
983 {
984 int i;
985
986 stp_dprintf(STP_DBG_LEXMARK, v, " size %d, size_v %d, size_v[0] %d\n", (int)sizeof(*lineoff_buffer), (int)sizeof(lineoff_buffer->v), (int)sizeof(lineoff_buffer->v[0]));
987 memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
988
989 for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
990 lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
991 }
992 return (lineoff_buffer);
993 }
994
995
996 #if 0
997 /*******************************
998 lexmark_size_type
999 *******************************/
1000 /* This method is actually not used.
1001 Is there a possibility to set such value ???????????? */
1002 static unsigned char
1003 lexmark_size_type(const stp_vars_t *v, const lexmark_cap_t * caps)
1004 {
1005 const stp_papersize_t *pp = stpi_get_papersize_by_size(v, stp_get_page_height(v),
1006 stp_get_page_width(v));
1007 if (pp)
1008 {
1009 const char *name = pp->name;
1010 /* built ins: */
1011 if (!strcmp(name,"A5")) return 0x01;
1012 if (!strcmp(name,"A4")) return 0x03;
1013 if (!strcmp(name,"B5")) return 0x08;
1014 if (!strcmp(name,"Letter")) return 0x0d;
1015 if (!strcmp(name,"Legal")) return 0x0f;
1016 if (!strcmp(name,"COM10")) return 0x16;
1017 if (!strcmp(name,"DL")) return 0x17;
1018 if (!strcmp(name,"LetterExtra")) return 0x2a;
1019 if (!strcmp(name,"A4Extra")) return 0x2b;
1020 if (!strcmp(name,"w288h144")) return 0x2d;
1021 /* custom */
1022
1023 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: Unknown paper size '%s' - using custom\n",name);
1024 } else {
1025 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: Couldn't look up paper size %dx%d - "
1026 "using custom\n",stp_get_page_height(v), stp_get_page_width(v));
1027 }
1028 return 0;
1029 }
1030 #endif
1031
1032
lexmark_get_phys_resolution_vertical(int model)1033 static int lexmark_get_phys_resolution_vertical(int model)
1034 {
1035 return 600;
1036 }
1037
1038 #if 0
1039 static int lexmark_get_phys_resolution_horizontal(int model)
1040 {
1041 return 1200;
1042 }
1043 #endif
1044
1045 static const lexmark_res_t
lexmark_get_resolution_para(const stp_vars_t * v,int model,const char * resolution)1046 *lexmark_get_resolution_para(const stp_vars_t *v, int model, const char *resolution)
1047 {
1048 const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
1049
1050 const lexmark_res_t *res = *(caps->res_parameters); /* get the resolution specific parameters of printer */
1051
1052 if (resolution)
1053 {
1054 while (res->hres)
1055 {
1056 if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
1057 (res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
1058 (!strcmp(resolution, res->name)))
1059 {
1060 return res;
1061 }
1062 res++;
1063 }
1064 }
1065 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
1066 return NULL;
1067 }
1068
1069
1070 static int
lexmark_print_bidirectional(const stp_vars_t * v,int model,const char * resolution)1071 lexmark_print_bidirectional(const stp_vars_t *v, int model, const char *resolution)
1072 {
1073 const lexmark_res_t *res_para = lexmark_get_resolution_para(v, model, resolution);
1074 return !res_para->unidirectional;
1075 }
1076
1077 static const char *
lexmark_lum_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1078 lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1079 {
1080 return (caps->lum_adjustment);
1081 }
1082
1083 static const char *
lexmark_hue_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1084 lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1085 {
1086 return (caps->hue_adjustment);
1087 }
1088
1089 static const char *
lexmark_sat_adjustment(const lexmark_cap_t * caps,const stp_vars_t * v)1090 lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
1091 {
1092 return (caps->sat_adjustment);
1093 }
1094
1095
1096 static void
lexmark_describe_resolution(const stp_vars_t * v,stp_resolution_t * x,stp_resolution_t * y)1097 lexmark_describe_resolution(const stp_vars_t *v,
1098 stp_resolution_t *x, stp_resolution_t *y)
1099 {
1100 const char *resolution = stp_get_string_parameter(v, "Resolution");
1101 const lexmark_res_t *res =
1102 lexmark_get_resolution_para(v, stp_get_model_id(v), resolution);
1103
1104 if (res)
1105 {
1106 *x = res->hres;
1107 *y = res->vres;
1108 return;
1109 }
1110 *x = -1;
1111 *y = -1;
1112 }
1113
1114
1115 static stp_param_string_t media_sources[] =
1116 {
1117 { "Auto", N_("Auto Sheet Feeder") },
1118 { "Manual", N_("Manual with Pause") },
1119 { "ManualNP", N_("Manual without Pause") }
1120 };
1121
1122
1123 /*
1124 * 'lexmark_parameters()' - Return the parameter values for the given parameter.
1125 */
1126
1127 static stp_parameter_list_t
lexmark_list_parameters(const stp_vars_t * v)1128 lexmark_list_parameters(const stp_vars_t *v)
1129 {
1130 stp_parameter_list_t *ret = stp_parameter_list_create();
1131 stp_parameter_list_t *tmp_list;
1132
1133 int i;
1134
1135 /* Set up dithering */
1136 tmp_list = stp_dither_list_parameters(v);
1137 stp_parameter_list_append(ret, tmp_list);
1138 stp_parameter_list_destroy(tmp_list);
1139
1140 for (i = 0; i < the_parameter_count; i++)
1141 stp_parameter_list_add_param(ret, &(the_parameters[i]));
1142 for (i = 0; i < float_parameter_count; i++)
1143 stp_parameter_list_add_param(ret, &(float_parameters[i].param));
1144 return ret;
1145 }
1146
1147 static const char *
lexmark_describe_output(const stp_vars_t * v)1148 lexmark_describe_output(const stp_vars_t *v)
1149 {
1150 int printing_color = 0;
1151 int model = stp_get_model_id(v);
1152 const lexmark_cap_t *caps = lexmark_get_model_capabilities(v, model);
1153 const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
1154 const char *ink_type = stp_get_string_parameter(v, "InkType");
1155 const lexmark_inkparam_t *ink_parameter;
1156
1157 if (!print_mode || strcmp(print_mode, "Color") == 0)
1158 printing_color = 1;
1159
1160 ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
1161
1162 if (!ink_parameter || ink_parameter->used_colors == COLOR_MODE_K ||
1163 caps->inks == LEXMARK_INK_K || !printing_color)
1164 return "Grayscale";
1165 else if (!(ink_parameter->used_colors & COLOR_MODE_K))
1166 return "CMY";
1167 else
1168 return "CMYK";
1169 }
1170
1171 static void
lexmark_parameters(const stp_vars_t * v,const char * name,stp_parameter_t * description)1172 lexmark_parameters(const stp_vars_t *v, const char *name,
1173 stp_parameter_t *description)
1174 {
1175 int i;
1176
1177 const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, stp_get_model_id(v));
1178 description->p_type = STP_PARAMETER_TYPE_INVALID;
1179
1180 if (name == NULL)
1181 return;
1182
1183 for (i = 0; i < float_parameter_count; i++)
1184 if (strcmp(name, float_parameters[i].param.name) == 0)
1185 {
1186 stp_fill_parameter_settings(description,
1187 &(float_parameters[i].param));
1188 description->deflt.dbl = float_parameters[i].defval;
1189 description->bounds.dbl.upper = float_parameters[i].max;
1190 description->bounds.dbl.lower = float_parameters[i].min;
1191 return;
1192 }
1193
1194 for (i = 0; i < the_parameter_count; i++)
1195 if (strcmp(name, the_parameters[i].name) == 0)
1196 {
1197 stp_fill_parameter_settings(description, &(the_parameters[i]));
1198 break;
1199 }
1200
1201 if (strcmp(name, "PageSize") == 0)
1202 {
1203 unsigned int height_limit, width_limit;
1204 unsigned int min_height_limit, min_width_limit;
1205 const stp_papersize_list_t *paper_sizes = stpi_get_standard_papersize_list();
1206 const stp_papersize_list_item_t *ptli =
1207 stpi_papersize_list_get_start(paper_sizes);
1208 description->bounds.str = stp_string_list_create();
1209
1210 width_limit = caps->max_paper_width;
1211 height_limit = caps->max_paper_height;
1212 min_width_limit = caps->min_paper_width;
1213 min_height_limit = caps->min_paper_height;
1214
1215 while (ptli)
1216 {
1217 const stp_papersize_t *pt = stpi_paperlist_item_get_data(ptli);
1218
1219 if (pt->paper_size_type == PAPERSIZE_TYPE_STANDARD ||
1220 pt->paper_size_type == PAPERSIZE_TYPE_ENVELOPE) {
1221
1222 if (strlen(pt->name) > 0 &&
1223 pt->width <= width_limit && pt->height <= height_limit &&
1224 (pt->height >= min_height_limit || pt->height == 0) &&
1225 (pt->width >= min_width_limit || pt->width == 0))
1226 {
1227 if (stp_string_list_count(description->bounds.str) == 0)
1228 description->deflt.str = pt->name;
1229 stp_string_list_add_string(description->bounds.str,
1230 pt->name, gettext(pt->text));
1231 }
1232 }
1233 ptli = stpi_paperlist_item_next(ptli);
1234 }
1235 }
1236 else if (strcmp(name, "Resolution") == 0)
1237 {
1238 const lexmark_res_t *res;
1239 description->bounds.str = stp_string_list_create();
1240
1241 res = *(caps->res_parameters); /* get resolution specific parameters of printer */
1242
1243 /* check for allowed resolutions */
1244 while (res->hres)
1245 {
1246 if (stp_string_list_count(description->bounds.str) == 0)
1247 description->deflt.str = res->name;
1248 stp_string_list_add_string(description->bounds.str,
1249 res->name, gettext(res->text));
1250 res++;
1251 }
1252 }
1253 else if (strcmp(name, "InkType") == 0)
1254 {
1255 description->bounds.str = stp_string_list_create();
1256 description->deflt.str = caps->ink_types[0].name;
1257 for (i = 0; caps->ink_types[i].name != NULL; i++)
1258 stp_string_list_add_string(description->bounds.str,
1259 caps->ink_types[i].name,
1260 gettext(caps->ink_types[i].text));
1261 }
1262 else if (strcmp(name, "MediaType") == 0)
1263 {
1264 description->bounds.str = stp_string_list_create();
1265 description->deflt.str = lexmark_paper_list[0].name;
1266 for (i = 0; i < paper_type_count; i++)
1267 stp_string_list_add_string(description->bounds.str,
1268 lexmark_paper_list[i].name,
1269 gettext(lexmark_paper_list[i].text));
1270 }
1271 else if (strcmp(name, "InputSlot") == 0)
1272 {
1273 description->bounds.str = stp_string_list_create();
1274 description->deflt.str = media_sources[0].name;
1275 for (i = 0; i < sizeof(media_sources) / sizeof(stp_param_string_t); i++)
1276 stp_string_list_add_string(description->bounds.str,
1277 media_sources[i].name,
1278 gettext(media_sources[i].name));
1279 }
1280 else if (strcmp(name, "InkChannels") == 0)
1281 {
1282 if (caps->inks & LEXMARK_INK_CcMmYyK)
1283 description->deflt.integer = 7;
1284 else if (caps->inks & LEXMARK_INK_CcMmYK)
1285 description->deflt.integer = 6;
1286 else if (caps->inks & LEXMARK_INK_CMYK)
1287 description->deflt.integer = 4;
1288 else if (caps->inks & LEXMARK_INK_CMY)
1289 description->deflt.integer = 3;
1290 else
1291 description->deflt.integer = 1;
1292 description->bounds.integer.lower = -1;
1293 description->bounds.integer.upper = -1;
1294 }
1295 else if (strcmp(name, "PrintingMode") == 0)
1296 {
1297 description->bounds.str = stp_string_list_create();
1298 if (caps->inks != LEXMARK_INK_K)
1299 stp_string_list_add_string
1300 (description->bounds.str, "Color", _("Color"));
1301 stp_string_list_add_string
1302 (description->bounds.str, "BW", _("Black and White"));
1303 description->deflt.str =
1304 stp_string_list_param(description->bounds.str, 0)->name;
1305 }
1306 }
1307
1308 /*
1309 * 'lexmark_imageable_area()' - Return the imageable area of the page.
1310 */
1311
1312 static void
internal_imageable_area(const stp_vars_t * v,int use_paper_margins,stp_dimension_t * left,stp_dimension_t * right,stp_dimension_t * bottom,stp_dimension_t * top)1313 internal_imageable_area(const stp_vars_t *v, /* I */
1314 int use_paper_margins,
1315 stp_dimension_t *left, /* O - Left position in points */
1316 stp_dimension_t *right, /* O - Right position in points */
1317 stp_dimension_t *bottom, /* O - Bottom position in points */
1318 stp_dimension_t *top) /* O - Top position in points */
1319 {
1320 stp_dimension_t width, length; /* Size of page */
1321 stp_dimension_t left_margin = 0;
1322 stp_dimension_t right_margin = 0;
1323 stp_dimension_t bottom_margin = 0;
1324 stp_dimension_t top_margin = 0;
1325 const char *media_size = stp_get_string_parameter(v, "PageSize");
1326 const stp_papersize_t *pt = NULL;
1327 const lexmark_cap_t *caps =
1328 lexmark_get_model_capabilities(v, stp_get_model_id(v));
1329
1330
1331 if (media_size && use_paper_margins)
1332 pt = stp_describe_papersize(v, media_size);
1333
1334 stp_default_media_size(v, &width, &length);
1335 if (pt)
1336 {
1337 left_margin = pt->left;
1338 right_margin = pt->right;
1339 bottom_margin = pt->bottom;
1340 top_margin = pt->top;
1341 }
1342 left_margin = max(left_margin, caps->border_left);
1343 right_margin = max(right_margin, caps->border_right);
1344 top_margin = max(top_margin, caps->border_top);
1345 bottom_margin = max(bottom_margin, caps->border_bottom);
1346
1347 *left = left_margin;
1348 *right = width - right_margin;
1349 *top = top_margin;
1350 *bottom = length - bottom_margin;
1351 }
1352
1353 static void
lexmark_imageable_area(const stp_vars_t * v,stp_dimension_t * left,stp_dimension_t * right,stp_dimension_t * bottom,stp_dimension_t * top)1354 lexmark_imageable_area(const stp_vars_t *v, /* I */
1355 stp_dimension_t *left, /* O - Left position in points */
1356 stp_dimension_t *right, /* O - Right position in points */
1357 stp_dimension_t *bottom, /* O - Bottom position in points */
1358 stp_dimension_t *top) /* O - Top position in points */
1359 {
1360 internal_imageable_area(v, 1, left, right, bottom, top);
1361 }
1362
1363 static void
lexmark_limit(const stp_vars_t * v,stp_dimension_t * width,stp_dimension_t * height,stp_dimension_t * min_width,stp_dimension_t * min_height)1364 lexmark_limit(const stp_vars_t *v, /* I */
1365 stp_dimension_t *width,
1366 stp_dimension_t *height,
1367 stp_dimension_t *min_width,
1368 stp_dimension_t *min_height)
1369 {
1370 const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, stp_get_model_id(v));
1371 *width = caps->max_paper_width;
1372 *height = caps->max_paper_height;
1373 *min_width = caps->min_paper_width;
1374 *min_height = caps->min_paper_height;
1375 }
1376
1377
1378
1379 static int
lexmark_init_printer(const stp_vars_t * v,const lexmark_cap_t * caps,int printing_color,const char * source_str,int xdpi,int ydpi,int page_width,int page_height,int top,int left,int use_dmt)1380 lexmark_init_printer(const stp_vars_t *v, const lexmark_cap_t * caps,
1381 int printing_color,
1382 const char *source_str,
1383 int xdpi, int ydpi,
1384 int page_width, int page_height,
1385 int top, int left,
1386 int use_dmt)
1387 {
1388
1389 /* because the details of the header sequence are not known, we simply write it as one image. */
1390
1391 #define LXM_Z52_STARTSIZE 0x35
1392 /* 300 dpi */
1393 unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
1394 0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
1395 0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
1396 0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
1397 0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
1398 0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
1399 0xf0,0x1b,0x2a,0x07,0x63};
1400
1401 #define LXM_Z42_STARTSIZE 0x30
1402 /* 600 dpi */
1403 unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
1404 0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
1405 0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
1406 0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
1407 0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
1408 0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
1409
1410 #define ESC2a "\033\052"
1411
1412
1413
1414 #define LXM_3200_STARTSIZE 32
1415
1416 unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
1417 {
1418 0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1419 0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
1420 0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
1421 0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
1422 };
1423
1424 /* write init sequence */
1425 switch(caps->model)
1426 {
1427 case m_z52:
1428 stp_zfwrite((const char *) startHeader_z52,
1429 LXM_Z52_STARTSIZE,1,v);
1430 #ifdef DEBUG
1431 lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
1432 #endif
1433 break;
1434
1435 case m_z42:
1436 stp_zfwrite((const char *) startHeader_z42,
1437 LXM_Z42_STARTSIZE,1,v);
1438 #ifdef DEBUG
1439 lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
1440 #endif
1441 break;
1442
1443 case m_3200:
1444 stp_zfwrite((const char *) startHeader_3200,
1445 LXM_3200_STARTSIZE, 1, v);
1446 break;
1447
1448 default:
1449 stp_eprintf(v, "Unknown printer !! %i\n", caps->model);
1450 return 0;
1451 }
1452
1453
1454
1455 /*
1456 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: printable size = %dx%d (%dx%d) %02x%02x %02x%02x\n",
1457 page_width,page_height,printable_width,printable_length,
1458 arg_70_1,arg_70_2,arg_70_3,arg_70_4);
1459 */
1460 return 1;
1461 }
1462
lexmark_deinit_printer(const stp_vars_t * v,const lexmark_cap_t * caps)1463 static void lexmark_deinit_printer(const stp_vars_t *v, const lexmark_cap_t * caps)
1464 {
1465
1466 switch(caps->model) {
1467 case m_z52:
1468 {
1469 char buffer[40];
1470
1471 memcpy(buffer, ESC2a, 2);
1472 buffer[2] = 0x7;
1473 buffer[3] = 0x65;
1474
1475 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: <<eject page.>> %x %x %x %x\n", buffer[0], buffer[1], buffer[2], buffer[3]);
1476 #ifdef DEBUG
1477 lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
1478 #endif
1479 /* eject page */
1480 stp_zfwrite(buffer, 1, 4, v);
1481 }
1482 break;
1483
1484 case m_z42:
1485 {
1486 unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
1487 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: <<eject page.>>\n");
1488 #ifdef DEBUG
1489 lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
1490 #endif
1491 /* eject page */
1492 stp_zfwrite((char *)buffer, 1, 12, v);
1493 }
1494 break;
1495
1496 case m_3200:
1497 {
1498 unsigned char buffer[24] =
1499 {
1500 0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1501 0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
1502 0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
1503 };
1504
1505 stp_dprintf(STP_DBG_LEXMARK, v, "Headpos: %d\n", lxm3200_headpos);
1506
1507 lxm3200_linetoeject += 2400;
1508 buffer[3] = lxm3200_linetoeject >> 8;
1509 buffer[4] = lxm3200_linetoeject & 0xff;
1510 buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
1511 buffer[11] = lxm3200_headpos >> 8;
1512 buffer[12] = lxm3200_headpos & 0xff;
1513 buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
1514
1515 stp_zfwrite((const char *)buffer, 24, 1, v);
1516 }
1517 break;
1518
1519 case m_lex7500:
1520 break;
1521 }
1522
1523 }
1524
1525
1526 /* paper_shift() -- shift paper in printer -- units are unknown :-)
1527 */
paper_shift(const stp_vars_t * v,int offset,const lexmark_cap_t * caps)1528 static void paper_shift(const stp_vars_t *v, int offset, const lexmark_cap_t * caps)
1529 {
1530 switch(caps->model) {
1531 case m_z52:
1532 case m_z42:
1533 {
1534 unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
1535 if(offset == 0)return;
1536 buf[3] = (unsigned char)(offset >> 8);
1537 buf[4] = (unsigned char)(offset & 0xFF);
1538 stp_zfwrite((const char *)buf, 1, 5, v);
1539 #ifdef DEBUG
1540 lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
1541 #endif
1542 }
1543 break;
1544
1545 case m_3200:
1546 {
1547 unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
1548 if(offset == 0)return;
1549 lxm3200_linetoeject -= offset;
1550 buf[3] = (unsigned char)(offset >> 8);
1551 buf[4] = (unsigned char)(offset & 0xff);
1552 buf[7] = lexmark_calc_3200_checksum(buf);
1553 stp_zfwrite((const char *)buf, 1, 8, v);
1554 }
1555 break;
1556
1557 case m_lex7500:
1558 break;
1559 }
1560
1561 stp_dprintf(STP_DBG_LEXMARK, v, "Lines to eject: %d\n", lxm3200_linetoeject);
1562 }
1563
1564 /*
1565 * 'advance_buffer()' - Move (num) lines of length (len) down one line
1566 * and sets first line to 0s
1567 * accepts NULL pointers as buf
1568 * !!! buf must contain more than (num) lines !!!
1569 * also sets first line to 0s if num<1
1570 */
1571 #if 0
1572 static void
1573 lexmark_advance_buffer(unsigned char *buf, int len, int num)
1574 {
1575 if (!buf || !len) return;
1576 if (num>0) memmove(buf+len,buf,len*num);
1577 memset(buf,0,len);
1578 }
1579 #endif
1580
1581 static double
get_double_param(stp_vars_t * v,const char * param)1582 get_double_param(stp_vars_t *v, const char *param)
1583 {
1584 if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
1585 return stp_get_float_parameter(v, param);
1586 else
1587 return 1.0;
1588 }
1589
1590 /**********************************************************
1591 * lexmark_print() - Print an image to a LEXMARK printer.
1592 **********************************************************/
1593 /* This method should not be printer dependent (maybe it is because of nozzle count and other things) */
1594 /* The method will set the printing method depending on the selected printer.
1595 It will define the colors to be used and the resolution.
1596 Additionally the pass_length will be defined.
1597 The method lexmark_write() is responsible to handle the received lines
1598 in a correct way.
1599 */
1600 static int
lexmark_do_print(stp_vars_t * v,stp_image_t * image)1601 lexmark_do_print(stp_vars_t *v, stp_image_t *image)
1602 {
1603 int status = 1;
1604 int y; /* Looping vars */
1605 stp_resolution_t xdpi, ydpi; /* Resolution */
1606 stp_dimension_t page_width, /* Width of page */
1607 page_height, /* Length of page */
1608 page_left,
1609 page_top,
1610 page_right,
1611 page_bottom,
1612 page_true_width, /* True length of page */
1613 page_true_height; /* True length of page */
1614 int
1615 out_width, /* Width of image on page in pixels */
1616 out_height, /* Length of image on page */
1617 length, /* Length of raster data in bytes*/
1618 buf_length, /* Length of raster data buffer (dmt) */
1619 errdiv, /* Error dividend */
1620 errmod, /* Error modulus */
1621 errval, /* Current error value */
1622 errline, /* Current raster line */
1623 errlast; /* Last raster line loaded */
1624 unsigned zero_mask;
1625 int image_height;
1626 int use_dmt = 0;
1627 int pass_length=0; /* count of inkjets for one pass */
1628 int add_top_offset=0; /* additional top offset */
1629 int printMode = 0;
1630 /* Lexmark do not have different pixel sizes. We have to correct the density according the print resolution. */
1631 double densityDivisor; /* This parameter is will adapt the density according the resolution */
1632 double k_lower, k_upper;
1633 int physical_xdpi = 0;
1634 int physical_ydpi = 0;
1635 int i;
1636
1637 stp_curve_t *lum_adjustment = NULL;
1638 stp_curve_t *hue_adjustment = NULL;
1639 stp_curve_t *sat_adjustment = NULL;
1640
1641 /* weave parameters */
1642 lexmark_linebufs_t cols;
1643 int nozzle_separation;
1644 int horizontal_passes;
1645 int ncolors;
1646 lexm_privdata_weave privdata;
1647
1648 lexmark_lineoff_t lineoff_buffer; /* holds the line offsets of each color */
1649 #ifdef DEBUG
1650 testdata td;
1651 #endif
1652
1653
1654 int model = stp_get_model_id(v);
1655 const char *resolution = stp_get_string_parameter(v, "Resolution");
1656 const char *media_type = stp_get_string_parameter(v, "MediaType");
1657 const char *media_source = stp_get_string_parameter(v, "InputSlot");
1658 const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
1659 int printing_color = 0;
1660 const char *ink_type = stp_get_string_parameter(v, "InkType");
1661 stp_dimension_t top = stp_get_top(v);
1662 stp_dimension_t left = stp_get_left(v);
1663
1664 const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
1665 const lexmark_res_t *res_para_ptr =
1666 lexmark_get_resolution_para(v, model, resolution);
1667 const paper_t *media = get_media_type(media_type,caps);
1668 const lexmark_inkparam_t *ink_parameter;
1669
1670 #ifdef DEBUG
1671 dbgfileprn = lex_open_tmp_file(); /* open file with xx */
1672 #endif
1673
1674 if (!stp_verify(v))
1675 {
1676 stp_eprintf(v, "Print options not verified; cannot print.\n");
1677 return 0;
1678 }
1679 if (strcmp(print_mode, "Color") == 0)
1680 printing_color = 1;
1681
1682 ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
1683
1684 if (ink_parameter == NULL)
1685 {
1686 stp_eprintf(v, "Illegal Ink Type specified; cannot print.\n");
1687 return 0;
1688 }
1689
1690 stp_image_init(image);
1691
1692 /* force grayscale if image is grayscale
1693 * or single black cartridge installed
1694 */
1695
1696 if ((ink_parameter->used_colors == COLOR_MODE_K) ||
1697 (caps->inks == LEXMARK_INK_K))
1698 {
1699 printing_color = 0;
1700 stp_set_string_parameter(v, "PrintingMode", "BW");
1701 }
1702
1703 /*
1704 * Choose the correct color conversion function...
1705 */
1706
1707
1708 ncolors = ink_parameter->ncolors;
1709 printMode = ink_parameter->used_colors;
1710 pass_length = ink_parameter->pass_length;
1711 add_top_offset = ink_parameter->v_top_head_offset;
1712
1713
1714 /*
1715 * Figure out the output resolution...
1716 */
1717
1718 stp_describe_resolution(v, &xdpi, &ydpi);
1719 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: resolution=%dx%d\n",(int)xdpi,(int)ydpi);
1720
1721 switch (res_para_ptr->resid) {
1722 case DPI300:
1723 physical_xdpi = 300;
1724 physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1725 break;
1726 case DPI600:
1727 physical_xdpi = 600;
1728 physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1729 break;
1730 case DPI1200:
1731 case DPItest:
1732 physical_xdpi = 1200;
1733 physical_ydpi = lexmark_get_phys_resolution_vertical(model);
1734 break;
1735 default:
1736 return 0;
1737 break;
1738 }
1739 /* adapt the density */
1740 densityDivisor = ((xdpi / 300)*(ydpi/ 600));
1741
1742 #ifdef DEBUG
1743 if (res_para_ptr->resid == DPItest) {
1744 stp_dprintf(STP_DBG_LEXMARK, v, "Start test print1\n");
1745 doTestPrint = 1;
1746 }
1747 #endif
1748
1749 if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
1750 /* in case of photo mode we have to go a bit lighter */
1751 densityDivisor /= 1.2;
1752 }
1753
1754 nozzle_separation = ydpi / physical_ydpi;
1755
1756 horizontal_passes = xdpi / physical_xdpi;
1757 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: horizontal_passes %i, xdpi %d, physical_xdpi %i\n",
1758 horizontal_passes, (int)xdpi, physical_xdpi);
1759
1760
1761
1762
1763 if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
1764 (caps->features & LEXMARK_CAP_DMT)) {
1765 use_dmt= 1;
1766 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: using drop modulation technology\n");
1767 }
1768
1769 /*
1770 * Compute the output size...
1771 */
1772
1773 out_width = stp_get_width(v);
1774 out_height = stp_get_height(v);
1775
1776 internal_imageable_area(v, 0, &page_left, &page_right,
1777 &page_bottom, &page_top);
1778 left -= page_left;
1779 top -= page_top;
1780 page_width = page_right - page_left;
1781 page_height = page_bottom - page_top;
1782
1783 stp_dprintf(STP_DBG_LEXMARK, v, "page_right %f, page_left %f, page_top %f, page_bottom %f, left %f, top %f\n",page_right, page_left, page_top, page_bottom,left, top);
1784
1785 image_height = stp_image_height(image);
1786
1787 stp_default_media_size(v, &page_true_width, &page_true_height);
1788 lxm3200_linetoeject = (page_true_height * 1200) / 72;
1789
1790
1791 if (!lexmark_init_printer(v, caps, printing_color,
1792 media_source,
1793 xdpi, ydpi, page_width, page_height,
1794 top,left,use_dmt))
1795 return 0;
1796
1797 /*
1798 * Convert image size to printer resolution...
1799 */
1800
1801 out_width = xdpi * out_width / 72;
1802 out_height = ydpi * out_height / 72;
1803
1804
1805 stp_dprintf(STP_DBG_LEXMARK, v, "border: left %f, x_raster_res %d, offset_left %d\n", left, caps->x_raster_res, caps->offset_left_border);
1806
1807 left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
1808
1809 stp_dprintf(STP_DBG_LEXMARK, v, "border: left %f\n", left);
1810
1811
1812
1813 #ifdef DEBUG
1814 if (doTestPrint == 1) {
1815 stp_dprintf(STP_DBG_LEXMARK, v, "Start test print\n");
1816 testprint(&td);
1817 out_width = td.x;
1818 out_height = td.y;
1819 if (td.cols != 7) {
1820 printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
1821 } else {
1822 printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
1823 }
1824 }
1825 #endif
1826
1827 /*
1828 * Allocate memory for the raster data...
1829 */
1830
1831 length = (out_width + 7) / 8;
1832
1833
1834
1835 if (use_dmt) {
1836 /* buf_length= length*2; */
1837 buf_length= length;
1838 } else {
1839 buf_length= length;
1840 }
1841
1842 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: buflength is %d!\n",buf_length);
1843
1844
1845 /* Now we know the color which are used, let's get the memory for every color image */
1846 cols.p.k = NULL;
1847 cols.p.c = NULL;
1848 cols.p.y = NULL;
1849 cols.p.m = NULL;
1850 cols.p.C = NULL;
1851 cols.p.M = NULL;
1852 cols.p.Y = NULL;
1853
1854
1855 if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
1856 cols.p.c = stp_zalloc(buf_length+10);
1857 }
1858 if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
1859 cols.p.y = stp_zalloc(buf_length+10);
1860 }
1861 if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
1862 cols.p.m = stp_zalloc(buf_length+10);
1863 }
1864 if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
1865 cols.p.k = stp_zalloc(buf_length+10);
1866 }
1867 if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
1868 cols.p.C = stp_zalloc(buf_length+10);
1869 }
1870 if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
1871 cols.p.Y = stp_zalloc(buf_length+10);
1872 }
1873 if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
1874 cols.p.M = stp_zalloc(buf_length+10);
1875 }
1876
1877 if (cols.p.k)
1878 {
1879 if (cols.p.c)
1880 stp_set_string_parameter(v, "STPIOutputType", "KCMY");
1881 else
1882 stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
1883 }
1884 else
1885 stp_set_string_parameter(v, "STPIOutputType", "CMY");
1886
1887 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: driver will use colors %c%c%c%c%c%c%c\n",
1888 (cols.p.c) ? 'c' : ' ',
1889 (cols.p.C) ? 'C' : ' ',
1890 (cols.p.m) ? 'm' : ' ',
1891 (cols.p.M) ? 'M' : ' ',
1892 (cols.p.y) ? 'y' : ' ',
1893 (cols.p.Y) ? 'Y' : ' ',
1894 (cols.p.k) ? 'k' : ' ');
1895
1896 /* initialize soft weaving */
1897 privdata.ink_parameter = ink_parameter;
1898 privdata.bidirectional = lexmark_print_bidirectional(v, model, resolution);
1899 privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
1900 privdata.direction = 0;
1901 stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
1902 /* lxm_nozzles_used = 1;*/
1903
1904 stp_initialize_weave(v,
1905 pass_length, /* jets */
1906 nozzle_separation, /* separation */
1907 horizontal_passes, /* h oversample */
1908 res_para_ptr->vertical_passes, /* v passes */
1909 res_para_ptr->vertical_oversample, /* v oversample */
1910 ncolors, /* colors */
1911 1, /* bits/pixel */
1912 out_width, /* line width */
1913 out_height,
1914 ((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
1915 /caps->y_raster_res),
1916 (page_height * ydpi) / 72,
1917 (const int *) lexmark_head_offset(v, ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
1918 STP_WEAVE_ZIGZAG, /* weave_strategy */
1919 flush_pass,
1920 stp_fill_uncompressed, /* fill_start */
1921 stp_pack_uncompressed, /* pack */
1922 stp_compute_uncompressed_linewidth); /* compute_linewidth */
1923 privdata.last_pass_offset = 0;
1924 privdata.jets = pass_length;
1925 privdata.ncolors = ncolors;
1926 privdata.horizontal_weave = horizontal_passes;
1927
1928
1929 if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
1930 {
1931 stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
1932 stp_set_float_parameter(v, "Density", 1.0);
1933 }
1934
1935 stp_dprintf(STP_DBG_LEXMARK, v, "density is %f\n",
1936 stp_get_float_parameter(v, "Density"));
1937
1938 stp_dprintf(STP_DBG_LEXMARK, v, "density is %f and will be changed to %f (%f)\n",
1939 stp_get_float_parameter(v, "Density"),
1940 stp_get_float_parameter(v, "Density") / densityDivisor,
1941 densityDivisor);
1942
1943 /* Lexmark do not have different pixel sizes. We have to correct the density according the print resolution. */
1944 stp_scale_float_parameter(v, "Density", 1.0 / densityDivisor);
1945
1946
1947 /*
1948 * Compute the LUT. For now, it's 8 bit, but that may eventually
1949 * sometimes change.
1950 */
1951 if (ncolors > 4)
1952 k_lower = .5;
1953 else
1954 k_lower = .25;
1955
1956 if (media)
1957 {
1958 stp_scale_float_parameter(v, "Density", media->base_density);
1959 stp_scale_float_parameter(v, "Cyan", media->p_cyan);
1960 stp_scale_float_parameter(v, "Magenta", media->p_magenta);
1961 stp_scale_float_parameter(v, "Yellow", media->p_yellow);
1962 k_lower *= media->k_lower_scale;
1963 k_upper = media->k_upper;
1964 }
1965 else
1966 {
1967 stp_scale_float_parameter(v, "Density", .8);
1968 k_lower *= .1;
1969 k_upper = .5;
1970 }
1971 if (stp_get_float_parameter(v, "Density") > 1.0)
1972 stp_set_float_parameter(v, "Density", 1.0);
1973
1974 stp_dprintf(STP_DBG_LEXMARK, v, "density is %f\n",stp_get_float_parameter(v, "Density"));
1975
1976
1977 if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
1978 stp_set_default_float_parameter(v, "GCRLower", k_lower);
1979 if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
1980 stp_set_default_float_parameter(v, "GCRUpper", k_upper);
1981 stp_dither_init(v, image, out_width, xdpi, ydpi);
1982
1983 /*
1984 stpi_dither_set_black_lower(dither, .8 / ((1 << (use_dmt+1)) - 1));*/
1985 /*stpi_dither_set_black_levels(dither, 0.5, 0.5, 0.5);
1986 stpi_dither_set_black_lower(dither, 0.4);*/
1987 /*
1988 if (use_glossy_film)
1989 */
1990 if (cols.p.k)
1991 {
1992 stp_dither_add_channel(v, cols.p.k, STP_ECOLOR_K, 0);
1993 stp_channel_set_black_channel(v, STP_ECOLOR_K);
1994 }
1995 if (cols.p.c)
1996 stp_dither_add_channel(v, cols.p.c, STP_ECOLOR_C, 0);
1997 if (cols.p.C)
1998 stp_dither_add_channel(v, cols.p.C, STP_ECOLOR_C, 1);
1999 if (cols.p.m)
2000 stp_dither_add_channel(v, cols.p.m, STP_ECOLOR_M, 0);
2001 if (cols.p.M)
2002 stp_dither_add_channel(v, cols.p.M, STP_ECOLOR_M, 1);
2003 if (cols.p.y)
2004 stp_dither_add_channel(v, cols.p.y, STP_ECOLOR_Y, 0);
2005 if (cols.p.Y)
2006 stp_dither_add_channel(v, cols.p.Y, STP_ECOLOR_Y, 1);
2007
2008 if (!use_dmt) {
2009 if (cols.p.C)
2010 {
2011 stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
2012 0.31 / .5);
2013 }
2014 if (cols.p.M)
2015 {
2016 stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
2017 0.61 / .97);
2018 }
2019 if (cols.p.Y)
2020 {
2021 stp_dither_set_inks_full(v, STP_ECOLOR_Y, 2, photo_dither_shades, 1.0,
2022 0.08);
2023 }
2024 }
2025
2026 stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
2027 get_double_param(v, "BlackDensity") *
2028 get_double_param(v, "Density"));
2029 stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
2030 get_double_param(v, "CyanDensity") *
2031 get_double_param(v, "Density"));
2032 stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
2033 get_double_param(v, "MagentaDensity") *
2034 get_double_param(v, "Density"));
2035 stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
2036 get_double_param(v, "YellowDensity") *
2037 get_double_param(v, "Density"));
2038 if (!use_dmt) {
2039 if (cols.p.C)
2040 {
2041 stp_channel_set_density_adjustment
2042 (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
2043 get_double_param(v, "LightCyanTrans") *
2044 get_double_param(v, "Density")));
2045 }
2046 if (cols.p.M)
2047 {
2048 stp_channel_set_density_adjustment
2049 (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
2050 get_double_param(v, "LightMagentaTrans") *
2051 get_double_param(v, "Density")));
2052 }
2053 if (cols.p.Y)
2054 {
2055 stp_channel_set_density_adjustment
2056 (v, STP_ECOLOR_Y, 1, (get_double_param(v, "YellowDensity") *
2057 get_double_param(v, "LightYellowTrans") *
2058 get_double_param(v, "Density")));
2059 }
2060 }
2061
2062 /*
2063 * Output the page...
2064 */
2065
2066 if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE) &&
2067 media->hue_adjustment)
2068 {
2069 hue_adjustment = stp_read_and_compose_curves
2070 (lexmark_hue_adjustment(caps, v),
2071 media ? media->hue_adjustment : NULL, STP_CURVE_COMPOSE_ADD, 384);
2072 stp_set_curve_parameter(v, "HueMap", hue_adjustment);
2073 stp_curve_destroy(hue_adjustment);
2074 }
2075 if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE) &&
2076 media->lum_adjustment)
2077 {
2078 lum_adjustment = stp_read_and_compose_curves
2079 (lexmark_lum_adjustment(caps, v),
2080 media ? media->lum_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
2081 stp_set_curve_parameter(v, "LumMap", lum_adjustment);
2082 stp_curve_destroy(lum_adjustment);
2083 }
2084 if (!stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_ACTIVE) &&
2085 media->sat_adjustment)
2086 {
2087 sat_adjustment = stp_read_and_compose_curves
2088 (lexmark_sat_adjustment(caps, v),
2089 media ? media->sat_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
2090 stp_set_curve_parameter(v, "SatMap", sat_adjustment);
2091 stp_curve_destroy(sat_adjustment);
2092 }
2093
2094 (void) stp_color_init(v, image, 65536);
2095
2096 /* calculate the memory we need for one line of the printer image (hopefully we are right) */
2097 stp_dprintf(STP_DBG_LEXMARK, v, "---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
2098
2099 errdiv = image_height / out_height;
2100 errmod = image_height % out_height;
2101 errval = 0;
2102 errlast = -1;
2103 errline = 0;
2104
2105 privdata.hoffset = left;
2106 privdata.ydpi = ydpi;
2107 privdata.model = model;
2108 privdata.width = out_width;
2109 privdata.xdpi = xdpi;
2110 privdata.physical_xdpi = physical_xdpi;
2111 privdata.bitwidth = 1;
2112
2113 for (y = 0; y < out_height; y ++)
2114 {
2115 int duplicate_line = 1;
2116
2117 if (errline != errlast)
2118 {
2119 errlast = errline;
2120 duplicate_line = 0;
2121 if (stp_color_get_row(v, image, errline, &zero_mask))
2122 {
2123 status = 2;
2124 break;
2125 }
2126 }
2127 stp_dither(v, y, duplicate_line, zero_mask, NULL);
2128 stp_write_weave(v, (unsigned char **)cols.v);
2129
2130 errval += errmod;
2131 errline += errdiv;
2132 if (errval >= out_height)
2133 {
2134 errval -= out_height;
2135 errline ++;
2136 }
2137 }
2138 stp_image_conclude(image);
2139
2140 stp_flush_all(v);
2141
2142 lexmark_deinit_printer(v, caps);
2143
2144 /*
2145 * Cleanup...
2146 */
2147 if (privdata.outbuf != NULL) {
2148 stp_free(privdata.outbuf);/* !!!!!!!!!!!!!! */
2149 }
2150
2151 for (i = 0; i < NCHANNELS; i++)
2152 if (cols.v[i])
2153 stp_free(cols.v[i]);
2154
2155 #ifdef DEBUG
2156 lex_tmp_file_deinit(dbgfileprn);
2157 #endif
2158
2159 return status;
2160 }
2161
2162 static int
lexmark_print(const stp_vars_t * v,stp_image_t * image)2163 lexmark_print(const stp_vars_t *v, stp_image_t *image)
2164 {
2165 int status;
2166 stp_vars_t *nv = stp_vars_create_copy(v);
2167 stp_prune_inactive_options(nv);
2168 status = lexmark_do_print(nv, image);
2169 stp_vars_destroy(nv);
2170 return status;
2171 }
2172
2173 static const stp_printfuncs_t print_lexmark_printfuncs =
2174 {
2175 lexmark_list_parameters,
2176 lexmark_parameters,
2177 stp_default_media_size,
2178 lexmark_imageable_area,
2179 lexmark_imageable_area,
2180 lexmark_limit,
2181 lexmark_print,
2182 lexmark_describe_resolution,
2183 lexmark_describe_output,
2184 stp_verify_printer_params,
2185 NULL,
2186 NULL,
2187 NULL,
2188 stpi_standard_describe_papersize
2189 };
2190
2191
2192
2193 /* lexmark_init_line
2194 This method is printer type dependent code.
2195
2196 This method initializes the line to be printed. It will set
2197 the printer specific initialization which has to be done before
2198 the pixels of the image could be printed.
2199 */
2200 static unsigned char *
lexmark_init_line(const stp_vars_t * v,int mode,unsigned char * prnBuf,int pass_length,int offset,int width,int direction,const lexmark_inkparam_t * ink_parameter,const lexmark_cap_t * caps)2201 lexmark_init_line(const stp_vars_t *v,
2202 int mode, unsigned char *prnBuf,
2203 int pass_length,
2204 int offset, /* offset from left in 1/"x_raster_res" DIP (printer resolution)*/
2205 int width, int direction,
2206 const lexmark_inkparam_t *ink_parameter,
2207 const lexmark_cap_t * caps /* I - Printer model */
2208 )
2209 {
2210 int pos1 = 0;
2211 int pos2 = 0;
2212 int abspos, disp;
2213 int hend = 0;
2214 int header_size = 0;
2215
2216
2217 /* stp_eprintf(v, "#### width %d, length %d, pass_length %d\n", width, length, pass_length);*/
2218 /* first, we write the line header */
2219 switch(caps->model) {
2220 case m_z52:
2221 case m_z42:
2222 if (caps->model == m_z52)
2223 {
2224 header_size = LXM_Z52_HEADERSIZE;
2225 memcpy(prnBuf, outbufHeader_z52, header_size);
2226 }
2227 if (caps->model == m_z42)
2228 {
2229 header_size = LXM_Z42_HEADERSIZE;
2230 memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
2231 }
2232
2233 /* K could only be present if black is printed only. */
2234 if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
2235 stp_dprintf(STP_DBG_LEXMARK, v, "set photo/black cartridge \n");
2236 prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
2237
2238 if (direction) {
2239 } else {
2240 offset += ink_parameter->h_direction_offset;
2241 }
2242 } else {
2243 stp_dprintf(STP_DBG_LEXMARK, v, "set color cartridge \n");
2244 prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
2245
2246 if (direction) {
2247 offset += ink_parameter->h_catridge_offset;
2248 } else {
2249 offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
2250 }
2251 }
2252
2253 switch (mode & PRINT_MODE_MASK) {
2254 case PRINT_MODE_300:
2255 prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
2256 break;
2257 case PRINT_MODE_600:
2258 prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
2259 break;
2260 case PRINT_MODE_1200:
2261 prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
2262 break;
2263 case PRINT_MODE_2400:
2264 prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
2265 break;
2266 }
2267
2268
2269 if (direction) {
2270 prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
2271 } else {
2272 prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
2273 }
2274
2275 /* set package count */
2276 prnBuf[13] = (unsigned char)((width) >> 8);
2277 prnBuf[14] = (unsigned char)((width) & 0xFF);
2278 /* set horizontal offset */
2279 prnBuf[15] =(unsigned char)(offset >> 8);
2280 prnBuf[16] =(unsigned char)(offset & 0xFF);
2281
2282 if (caps->model == m_z42) {
2283 switch(mode & PRINT_MODE_MASK) {
2284 case PRINT_MODE_300:
2285 hend = (width-1)*(2400/300);
2286 break;
2287 case PRINT_MODE_600:
2288 hend = (width-1)*(2400/600);
2289 break;
2290 case PRINT_MODE_1200:
2291 hend = (width-1)*(2400/1200);
2292 break;
2293 case PRINT_MODE_2400:
2294 hend = (width-1)*(2400/2400);
2295 break;
2296 }
2297 hend += offset;
2298 prnBuf[17] = (unsigned char)(hend >> 8);
2299 prnBuf[18] = (unsigned char)(hend & 0xFF);
2300
2301 prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
2302 }
2303
2304 return prnBuf + header_size; /* return the position where the pixels have to be written */
2305 break;
2306 case m_3200:
2307 memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
2308
2309 offset = (offset - 60) * 4;
2310
2311 /* K could only be present if black is printed only. */
2312 if((mode & COLOR_MODE_K) ||
2313 (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
2314 {
2315 disp = LXM3200_LEFTOFFS;
2316 prnBuf[2] = 0x00;
2317 }
2318 else
2319 {
2320 disp = LXM3200_RIGHTOFFS;
2321 prnBuf[2] = 0x80;
2322 }
2323
2324 if(pass_length == 208)
2325 {
2326 prnBuf[2] |= 0x10;
2327 }
2328
2329 switch(mode & PRINT_MODE_MASK) {
2330 case PRINT_MODE_300:
2331 prnBuf[2] |= 0x20;
2332 pos1 = offset + disp;
2333 pos2 = offset + (width * 4) + disp;
2334 break;
2335
2336 case PRINT_MODE_600:
2337 prnBuf[2] |= 0x00;
2338 pos1 = offset + disp;
2339 pos2 = offset + (width * 2) + disp;
2340 break;
2341
2342 case PRINT_MODE_1200:
2343 prnBuf[2] |= 0x40;
2344 pos1 = offset + disp;
2345 pos2 = (offset + width) + disp;
2346 break;
2347 }
2348
2349 if(direction)
2350 prnBuf[2] |= 0x01;
2351 else
2352 prnBuf[2] |= 0x00;
2353
2354 /* set package count */
2355 prnBuf[3] = (unsigned char)((width) >> 8);
2356 prnBuf[4] = (unsigned char)((width) & 0xff);
2357
2358 /* set horizontal offset */
2359 prnBuf[21] = (unsigned char)(pos1 >> 8);
2360 prnBuf[22] = (unsigned char)(pos1 & 0xFF);
2361
2362 abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
2363 prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
2364 prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
2365
2366 lxm3200_headpos = abspos;
2367
2368 if(LXM3200_RIGHTOFFS > 4816)
2369 abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
2370 else
2371 abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
2372
2373 prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
2374 prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
2375
2376 lxm3200_headpos = abspos;
2377
2378 prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
2379 prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
2380 prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
2381
2382 /* return the position where the pixels have to be written */
2383 return prnBuf + LXM_3200_HEADERSIZE;
2384 break;
2385
2386 case m_lex7500:
2387 stp_eprintf(v, "Lexmark 7500 not supported !\n");
2388 return NULL;
2389 break;
2390 }
2391 return NULL;
2392 }
2393
2394
2395 typedef struct Lexmark_head_colors {
2396 int v_start;
2397 unsigned char *line;
2398 int head_nozzle_start;
2399 int head_nozzle_end;
2400 int used_jets;
2401 } Lexmark_head_colors;
2402
2403 /* lexmark_write
2404 This method is has NO printer type dependent code.
2405 This method writes a single line of the print. The line consists of "pass_length"
2406 pixel lines (pixels, which could be printed with one pass by the printer.
2407 */
2408
2409
2410 static int
lexmark_write(const stp_vars_t * v,unsigned char * prnBuf,int * paperShift,int direction,int pass_length,const lexmark_cap_t * caps,const lexmark_inkparam_t * ink_parameter,int xdpi,int yCount,Lexmark_head_colors * head_colors,int length,int mode,int ydpi,int width,int offset,int dmt)2411 lexmark_write(const stp_vars_t *v, /* I - Print file or command */
2412 unsigned char *prnBuf, /* mem block to buffer output */
2413 int *paperShift,
2414 int direction,
2415 int pass_length, /* num of inks to print */
2416 const lexmark_cap_t * caps, /* I - Printer model */
2417 const lexmark_inkparam_t *ink_parameter,
2418 int xdpi,
2419 int yCount,
2420 Lexmark_head_colors *head_colors,
2421 int length, /* I - Length of bitmap data in bytes */
2422 int mode, /* I - Which color */
2423 int ydpi, /* I - Vertical resolution */
2424 int width, /* I - Printed width in pixels */
2425 int offset, /* I - Offset from left side in lexmark_cap_t.x_raster_res DPI */
2426 int dmt)
2427 {
2428 unsigned char *tbits=NULL, *p=NULL;
2429 int clen;
2430 int x; /* actual vertical position */
2431 int y; /* actual horizontal position */
2432 int dy; /* horiz. inkjet position */
2433 int x1;
2434 unsigned short pixelline; /* byte to be written */
2435 unsigned int valid_bytes; /* bit list which tells the present bytes */
2436 int xStart=0; /* count start for horizontal line */
2437 int xEnd=0;
2438 int xIter=0; /* count direction for horizontal line */
2439 int anyCol=0;
2440 int colIndex;
2441 int rwidth; /* real with used at printing (includes shift between even & odd nozzles) */
2442 /* stp_dprintf(STP_DBG_LEXMARK, v, "<%c>",("CMYKcmy"[coloridx])); */
2443 stp_dprintf(STP_DBG_LEXMARK, v, "pass length %d\n", pass_length);
2444
2445
2446 /* first, we check the length of the line an cut it if necessary. */
2447 if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
2448 /* line too long !! Cut the line */
2449 stp_dprintf(STP_DBG_LEXMARK, v, "!! Line too long !! reduce it from %d", width);
2450 width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
2451 stp_dprintf(STP_DBG_LEXMARK, v, " down to %d\n", width);
2452 }
2453
2454
2455 /* we have to write the initial sequence for a line */
2456
2457 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: printer line initialized.\n");
2458
2459 if (direction) {
2460 /* left to right */
2461 xStart = -get_lr_shift(mode);
2462 xEnd = width-1;
2463 xIter = 1;
2464 rwidth = xEnd - xStart;
2465 } else {
2466 /* right to left ! */
2467 xStart = width-1;
2468 xEnd = -get_lr_shift(mode);
2469 rwidth = xStart - xEnd;
2470 xIter = -1;
2471 }
2472
2473 p = lexmark_init_line(v, mode, prnBuf, pass_length, offset, rwidth,
2474 direction, /* direction */
2475 ink_parameter, caps);
2476
2477
2478 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
2479
2480 /* now we can start to write the pixels */
2481 yCount = 2;
2482
2483
2484 for (x=xStart; x != xEnd; x+=xIter) {
2485 int anyDots=0; /* tells us if there was any dot to print */
2486
2487 switch(caps->model) {
2488 case m_z52:
2489 tbits = p;
2490 *(p++) = 0x3F;
2491 tbits[1] = 0; /* here will be nice bitmap */
2492 p++;
2493 break;
2494
2495 case m_3200:
2496 case m_z42:
2497 tbits = p;
2498 p += 4;
2499 break;
2500
2501 case m_lex7500:
2502 break;
2503 }
2504
2505
2506 pixelline =0; /* here we store 16 pixels */
2507 valid_bytes = 0; /* for every valid word (16 bits) a corresponding bit will be set to 1. */
2508
2509 anyDots =0;
2510 x1 = x+get_lr_shift(mode);
2511
2512 for (colIndex=0; colIndex < 3; colIndex++) {
2513 for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
2514 (dy < head_colors[colIndex].head_nozzle_end);
2515 y+=yCount, dy++) { /* we start counting with 1 !!!! */
2516 if (head_colors[colIndex].line != NULL) {
2517 pixelline = pixelline << 1;
2518 if ((x >= 0) &&
2519 ((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
2520 pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
2521 pixelline = pixelline << 1;
2522 if ((x1 < width) &&
2523 (((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
2524 pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
2525
2526 } else {
2527 pixelline = pixelline << 2;
2528 }
2529 switch(caps->model) {
2530 case m_z52:
2531 if ((dy%8) == 7) {
2532 /* we have two bytes, write them */
2533 anyDots |= pixelline;
2534 if (pixelline) {
2535 /* we have some dots */
2536 valid_bytes = valid_bytes >> 1;
2537 *((p++)) = (unsigned char)(pixelline >> 8);
2538 *((p++)) = (unsigned char)(pixelline & 0xff);
2539 } else {
2540 /* there are no dots ! */
2541 valid_bytes = valid_bytes >> 1;
2542 valid_bytes |= 0x1000;
2543 }
2544 pixelline =0;
2545 }
2546 break;
2547
2548 case m_3200:
2549 case m_z42:
2550 if((dy % 4) == 3)
2551 {
2552 anyDots |= pixelline;
2553 valid_bytes <<= 1;
2554
2555 if(pixelline)
2556 *(p++) = (unsigned char)(pixelline & 0xff);
2557 else
2558 valid_bytes |= 0x01;
2559
2560 pixelline = 0;
2561 }
2562 break;
2563
2564 case m_lex7500:
2565 break;
2566 }
2567 }
2568 }
2569
2570 switch(caps->model) {
2571 case m_z52:
2572 if (pass_length != 208) {
2573 valid_bytes = valid_bytes >> 1;
2574 valid_bytes |= 0x1000;
2575 }
2576 tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
2577 tbits[1] = (unsigned char)(valid_bytes & 0xff);
2578 break;
2579
2580 case m_z42:
2581 if ((p-tbits) & 1) *(p++)=0; /* z42 packets always have even length */
2582 /* fall through */
2583 case m_3200:
2584 tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
2585 tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
2586 tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
2587 tbits[3] = (unsigned char)(valid_bytes & 0xff);
2588 break;
2589
2590 case m_lex7500:
2591 break;
2592 }
2593
2594
2595 if (anyDots) {
2596 anyCol = 1;
2597 } else {
2598 /* there are no dots, make empty package */
2599 /* stp_dprintf(STP_DBG_LEXMARK, v, "-- empty col %i\n", x); */
2600 }
2601 }
2602
2603 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: 4\n");
2604
2605 clen=((unsigned char *)p)-prnBuf;
2606
2607 switch(caps->model) {
2608 case m_z52:
2609 case m_z42:
2610 prnBuf[IDX_SEQLEN] =(unsigned char)(clen >> 24);
2611 prnBuf[IDX_SEQLEN+1] =(unsigned char)(clen >> 16);
2612 prnBuf[IDX_SEQLEN+2] =(unsigned char)(clen >> 8);
2613 prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
2614 break;
2615
2616 case m_3200:
2617 prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
2618 prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
2619 prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
2620 prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
2621 break;
2622
2623 default:
2624 break;
2625 }
2626
2627 if (anyCol) {
2628 /* fist, move the paper */
2629 paper_shift(v, (*paperShift), caps);
2630 *paperShift=0;
2631
2632 /* now we write the image line */
2633 stp_zfwrite((const char *)prnBuf,1,clen,v);
2634 #ifdef DEBUG
2635 lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
2636 #endif
2637 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark: line written.\n");
2638 return 1;
2639 } else {
2640 stp_dprintf(STP_DBG_LEXMARK, v, "-- empty line\n");
2641 return 0;
2642 }
2643
2644 /* Send a line of raster graphics... */
2645 }
2646
2647
2648
2649 #ifdef DEBUG
lex_open_tmp_file()2650 const stp_vars_t *lex_open_tmp_file() {
2651 int i;
2652 const stp_vars_t *ofile;
2653 char tmpstr[256];
2654
2655 stp_eprintf(v, " create file !\n");
2656 for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
2657 ofile != NULL;
2658 i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
2659 if (ofile != NULL)
2660 {
2661 fclose(ofile);
2662 }
2663 }
2664 stp_eprintf(v, "Create file %s !\n", tmpstr);
2665 ofile = fopen(tmpstr, "wb");
2666 STPI_ASSERT(ofile);
2667 return ofile;
2668 }
2669
lex_tmp_file_deinit(const stp_vars_t * file)2670 void lex_tmp_file_deinit(const stp_vars_t *file) {
2671 stp_eprintf(v, "Close file %lx\n", file);
2672 fclose(file);
2673 }
2674
lex_write_tmp_file(const stp_vars_t * ofile,void * data,int length)2675 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length) {
2676 fwrite(data, 1, length, ofile);
2677 }
2678
2679
2680 #endif
2681
2682
2683 static void
flush_pass(stp_vars_t * v,int passno,int vertical_subpass)2684 flush_pass(stp_vars_t *v, int passno, int vertical_subpass)
2685 {
2686 stp_lineoff_t *lineoffs = stp_get_lineoffsets_by_pass(v, passno);
2687 stp_lineactive_t *lineactive = stp_get_lineactive_by_pass(v, passno);
2688 const stp_linebufs_t *bufs = stp_get_linebases_by_pass(v, passno);
2689 stp_pass_t *pass = stp_get_pass_by_pass(v, passno);
2690 stp_linecount_t *linecount = stp_get_linecount_by_pass(v, passno);
2691 lexm_privdata_weave *pd =
2692 (lexm_privdata_weave *) stp_get_component_data(v, "Driver");
2693 int width = pd->width;
2694 int hoffset = pd->hoffset;
2695 int model = pd->model;
2696 int xdpi = pd->xdpi;
2697 int ydpi = pd->ydpi;
2698 int physical_xdpi = pd->physical_xdpi;
2699 int lwidth = (width + (pd->horizontal_weave - 1)) / pd->horizontal_weave;
2700 int microoffset = vertical_subpass & (pd->horizontal_weave - 1);
2701
2702 int prn_mode;
2703 int j; /* color counter */
2704 const lexmark_cap_t * caps= lexmark_get_model_capabilities(v, model);
2705 int paperShift;
2706 Lexmark_head_colors head_colors[3]={{0, NULL, 0, 64/2, 64},
2707 {0, NULL, 64/2, 128/2, 64},
2708 {0, NULL, 128/2, 192/2, 64}};
2709
2710
2711 stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: flush_pass, here we are !\n");
2712 stp_dprintf(STP_DBG_LEXMARK, v, " passno %d, pd->ncolors %d, width %d, lwidth %d, bitwidth %d\n",
2713 passno, pd->ncolors, width, lwidth, pd->bitwidth);
2714 stp_dprintf(STP_DBG_LEXMARK, v, "microoffset %d, vertical_subpass %d, pd->horizontal_weave %d\n", microoffset,vertical_subpass, pd->horizontal_weave);
2715
2716 stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: last_pass_offset %d, logicalpassstart %d\n", pd->last_pass_offset, pass->logicalpassstart);
2717 stp_dprintf(STP_DBG_LEXMARK, v, "Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d, \n", caps->y_raster_res, ydpi);
2718
2719 switch (physical_xdpi) {
2720 case 300:
2721 prn_mode = PRINT_MODE_300;
2722 break;
2723 case 600:
2724 prn_mode = PRINT_MODE_600;
2725 break;
2726 case 1200:
2727 prn_mode = PRINT_MODE_1200;
2728 break;
2729 default:
2730 stp_dprintf(STP_DBG_LEXMARK, v, "Error: Unsupported phys resolution (%d)\n", physical_xdpi);
2731 return;
2732 break;
2733 }
2734 /* calculate paper shift and adapt actual resolution to physical positioning resolution */
2735 paperShift = (pass->logicalpassstart - pd->last_pass_offset) * (caps->y_raster_res/ydpi);
2736 for (j = 0; j < pd->ncolors; j++)
2737 stp_dprintf(STP_DBG_LEXMARK, v, "Color %d: active %d line %p jets %d offset %ld\n",
2738 j, lineactive[0].v[j], (void *)bufs[0].v[j], linecount[0].v[j],
2739 lineoffs[0].v[j]);
2740
2741 /*** do we have to print something with the color cartridge ? ***/
2742 if ((STP_ECOLOR_C < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_C] > 0))
2743 {
2744 head_colors[0].line = bufs[0].v[STP_ECOLOR_C];
2745 head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_C];
2746 }
2747 else
2748 {
2749 head_colors[0].line = NULL;
2750 head_colors[0].used_jets = 0;
2751 }
2752
2753 if ((STP_ECOLOR_M < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_M] > 0))
2754 {
2755 head_colors[1].line = bufs[0].v[STP_ECOLOR_M];
2756 head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_M];
2757 }
2758 else
2759 {
2760 head_colors[1].line = 0;
2761 head_colors[1].used_jets = 0;
2762 }
2763
2764 if ((STP_ECOLOR_Y < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_Y] > 0))
2765 {
2766 head_colors[2].line = bufs[0].v[STP_ECOLOR_Y];
2767 head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_Y];
2768 }
2769 else
2770 {
2771 head_colors[2].line = 0;
2772 head_colors[2].used_jets = 0;
2773 }
2774
2775 if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
2776
2777
2778
2779 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_write: lwidth %d\n", lwidth);
2780 lexmark_write(v, /* I - Print file or command */
2781 pd->outbuf,/*unsigned char *prnBuf, mem block to buffer output */
2782 &paperShift, /* int *paperShift, */
2783 pd->direction, /* int direction, */
2784 pd->jets, /* num of inks to print */
2785 caps, /* const lexmark_cap_t * caps, I - Printer model */
2786 pd->ink_parameter,
2787 xdpi, /* int xresolution, */
2788 2, /* yCount,*/
2789 head_colors, /* Lexmark_head_colors *head_colors, */
2790 (lwidth+7)/8, /* length, I - Length of bitmap data of one line in bytes */
2791 prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M, /* mode, I - Which color */
2792 ydpi, /* ydpi, I - Vertical resolution */
2793 lwidth, /* width, I - Printed width in pixels*/
2794 hoffset+microoffset, /* offset I - Offset from left side in x_raster_res DPI */
2795 0 /* dmt */);
2796 if (pd->bidirectional)
2797 pd->direction = (pd->direction +1) & 1;
2798 }
2799
2800
2801 /*** do we have to print something with black or photo cartridge ? ***/
2802 /* we print with the photo or black cartridge */
2803
2804 if (pd->jets != 208)
2805 {
2806 /* we have photo or black cartridge */
2807 if ((STP_ECOLOR_LC < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LC] > 0))
2808 {
2809 head_colors[0].line = bufs[0].v[STP_ECOLOR_LC];
2810 head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_LC];
2811 }
2812 else
2813 {
2814 head_colors[0].line = 0;
2815 head_colors[0].used_jets = 0;
2816 }
2817
2818 if ((STP_ECOLOR_LM < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LM] > 0))
2819 {
2820 head_colors[1].line = bufs[0].v[STP_ECOLOR_LM];
2821 head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_LM];
2822 }
2823 else
2824 {
2825 head_colors[1].line = 0;
2826 head_colors[1].used_jets = 0;
2827 }
2828
2829 if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
2830 {
2831 head_colors[2].line = bufs[0].v[STP_ECOLOR_K];
2832 head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_K];
2833 }
2834 else
2835 {
2836 head_colors[2].line = 0;
2837 head_colors[2].used_jets = 0;
2838 }
2839 }
2840 else
2841 {
2842 if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
2843 {
2844 /* we have black cartridge; we have to print with all 208 jets at once */
2845 head_colors[0].line = bufs[0].v[STP_ECOLOR_K];
2846 head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_K];
2847 head_colors[0].head_nozzle_start = 0;
2848 head_colors[0].head_nozzle_end = pd->jets/2;
2849 head_colors[2].line = NULL;
2850 head_colors[2].used_jets = 0;
2851 head_colors[2].head_nozzle_start = 0;
2852 head_colors[2].head_nozzle_end = 0;
2853 head_colors[1].line = NULL;
2854 head_colors[1].used_jets = 0;
2855 head_colors[1].head_nozzle_start = 0;
2856 head_colors[1].head_nozzle_end = 0;
2857 }
2858 else
2859 {
2860 head_colors[2].line = NULL;
2861 head_colors[2].used_jets = 0;
2862 head_colors[2].head_nozzle_start = 0;
2863 head_colors[2].head_nozzle_end = 0;
2864 head_colors[1].line = NULL;
2865 head_colors[1].used_jets = 0;
2866 head_colors[1].head_nozzle_start = 0;
2867 head_colors[1].head_nozzle_end = 0;
2868 head_colors[0].line = NULL;
2869 head_colors[0].used_jets = 0;
2870 head_colors[0].head_nozzle_start = 0;
2871 head_colors[0].head_nozzle_end = 0;
2872 }
2873 }
2874
2875 if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
2876
2877 lexmark_write(v, /* I - Print file or command */
2878 pd->outbuf,/*unsigned char *prnBuf, mem block to buffer output */
2879 &paperShift, /* int *paperShift, */
2880 pd->direction, /* int direction, */
2881 pd->jets, /* num of inks to print */
2882 caps, /* const lexmark_cap_t * caps, I - Printer model */
2883 pd->ink_parameter,
2884 xdpi, /* int xresolution, */
2885 2, /* yCount,*/
2886 head_colors, /* Lexmark_head_colors *head_colors, */
2887 (lwidth+7)/8, /* length, I - Length of bitmap data of one line in bytes */
2888 prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K, /* mode, I - Which color */
2889 ydpi, /* ydpi, I - Vertical resolution */
2890 lwidth, /* width, I - Printed width in pixels*/
2891 hoffset+microoffset, /* offset I - Offset from left side in x_raster_res DPI */
2892 0 /* dmt */);
2893 if (pd->bidirectional)
2894 {
2895 pd->direction = (pd->direction +1) & 1;
2896 }
2897 }
2898 /* store paper position in respect if there was a paper shift */
2899 pd->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
2900
2901 for (j = 0; j < pd->ncolors; j++)
2902 {
2903 lineoffs[0].v[j] = 0;
2904 linecount[0].v[j] = 0;
2905 }
2906
2907 stp_dprintf(STP_DBG_LEXMARK, v, "lexmark_write finished\n");
2908
2909 }
2910
2911
2912
2913
2914
2915 #ifdef DEBUG
2916
testprint(testdata * td)2917 static void testprint(testdata *td)
2918 {
2919 int icol, i;
2920 char dummy1[256], dummy2[256];
2921 lexmark_linebufs_t linebufs;
2922
2923 /* init */
2924 for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
2925 linebufs.v[i] = NULL;
2926 }
2927
2928 /*let's go */
2929 td->ifile = fopen("/t1.ppm", "rb");
2930 if (td->ifile != NULL) {
2931 /* find "{" */
2932 fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
2933 td->cols -= 1; /* we reduce it by one because fist color will be ignored */
2934 td->input_line = (char *)stp_malloc(td->x+10);
2935 stp_eprintf(v, "<%s> <%s>\n", dummy1, dummy2);
2936 stp_eprintf(v, "%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
2937 if (td->cols > 16) {
2938 stp_eprintf(v, "too many colors !!\n");
2939 return;
2940 }
2941
2942 /* read the colors */
2943 fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, dummy2, dummy2); /* jump over first color */
2944 for (icol=0; icol < td->cols; icol++) { /* we ignore the first color. It is "no dot". */
2945 fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
2946 stp_eprintf(v, "colchar %d <%c>\n", i, td->colchar[icol]);
2947 }
2948
2949
2950 if (td->cols > 5) {
2951 td->cols = 7;
2952 for (icol=0; icol < td->cols; icol++) { /* we ignore the first color. It is "no dot". */
2953 linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2954 }
2955 } else if (td->cols > 4) {
2956 td->cols = 5;
2957 for (icol=0; icol < td->cols; icol++) { /* we ignore the first color. It is "no dot". */
2958 linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2959 }
2960 } else {
2961 td->cols = 1;
2962 linebufs.v[0] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
2963 }
2964 } else {
2965 stp_eprintf(v, "can't open file !\n");
2966 }
2967 }
2968
2969
readtestprintline(testdata * td,lexmark_linebufs_t * linebufs)2970 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
2971 {
2972 char dummy1[256];
2973 int icol, ix;
2974
2975 stp_eprintf(v, "start readtestprintline\n");
2976 for (icol=0; icol < 7; icol++) {
2977 if (linebufs->v[icol] != NULL) {
2978 memset(linebufs->v[icol], 0, (td->x+7)/8); /* clean line */
2979 }
2980 }
2981 stp_eprintf(v, "1 readtestprintline cols %d\n", td->cols);
2982
2983
2984 fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
2985 for (icol=0; icol < td->cols; icol++) {
2986 for (ix=0; ix < td->x; ix++) {
2987 if (td->input_line[ix] == td->colchar[icol]) {
2988 /* set the dot */
2989 if (icol != 0) {
2990 linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
2991 } else {
2992 /* this is specific, we set ymc */
2993 linebufs->p.y[ix/8] |= 1 << (ix%8);
2994 linebufs->p.m[ix/8] |= 1 << (ix%8);
2995 linebufs->p.c[ix/8] |= 1 << (ix%8);
2996 }
2997 }
2998 }
2999 }
3000 /* stp_eprintf(v, "pixchar <%s><%s>\n",dummy1, td->input_line);*/
3001 }
3002
3003 #endif
3004
3005
3006 static stp_family_t print_lexmark_module_data =
3007 {
3008 &print_lexmark_printfuncs,
3009 NULL
3010 };
3011
3012 static int
print_lexmark_module_init(void)3013 print_lexmark_module_init(void)
3014 {
3015 return stpi_family_register(print_lexmark_module_data.printer_list);
3016 }
3017
3018
3019 static int
print_lexmark_module_exit(void)3020 print_lexmark_module_exit(void)
3021 {
3022 return stpi_family_unregister(print_lexmark_module_data.printer_list);
3023 }
3024
3025
3026 /* Module header */
3027 #define stp_module_version print_lexmark_LTX_stp_module_version
3028 #define stp_module_data print_lexmark_LTX_stp_module_data
3029
3030 stp_module_version_t stp_module_version = {0, 0};
3031
3032 stp_module_t stp_module_data =
3033 {
3034 "lexmark",
3035 VERSION,
3036 "Lexmark family driver",
3037 STP_MODULE_CLASS_FAMILY,
3038 NULL,
3039 print_lexmark_module_init,
3040 print_lexmark_module_exit,
3041 (void *) &print_lexmark_module_data
3042 };
3043