Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/main/print-lexmark.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-lexmark.c,v 1.146 2004/05/30 01:26:17 rlk Exp $"
00003  *
00004  *   Print plug-in Lexmark driver for the GIMP.
00005  *
00006  *   Copyright 2000 Richard Wisenoecker (richard.wisenoecker@gmx.at) and
00007  *      Alwin Stolk (p.a.stolk@tmx.nl)
00008  *
00009  *   The plug-in is based on the code of the CANON BJL plugin for the GIMP
00010  *   of Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu).
00011  *
00012  *
00013  *   This program is free software; you can redistribute it and/or modify it
00014  *   under the terms of the GNU General Public License as published by the Free
00015  *   Software Foundation; either version 2 of the License, or (at your option)
00016  *   any later version.
00017  *
00018  *   This program is distributed in the hope that it will be useful, but
00019  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00021  *   for more details.
00022  *
00023  *   You should have received a copy of the GNU General Public License
00024  *   along with this program; if not, write to the Free Software
00025  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /*
00029  * This file must include only standard C header files.  The core code must
00030  * compile on generic platforms that don't support glib, gimp, gtk, etc.
00031  */
00032 
00033 /*
00034  * !!! IMPORTANT !!!  Some short information: Border and page offsets
00035  * are defined in 1/72 DPI. This mean, that the parameter defined at
00036  * lexmark_cap_t which defines positions are in 1/72 DPI. At
00037  * lexmark_print the unit will be changed dependent on the printer,
00038  * according to the value defined at lexmark_cap_t.x_raster_res and
00039  * lexmark_cap_t.y_raster_res. These two parameters are specifing the
00040  * resolution used for positioning the printer head (it is not the
00041  * resolution used for printing!).
00042  */
00043 
00044 /* TODO-LIST
00045  *
00046  *   * implement the left border
00047  *
00048  */
00049 
00050 /*#define DEBUG 1*/
00051 #define USEEPSEWAVE 1
00052 
00053 #ifdef __GNUC__
00054 #define inline __inline__
00055 #endif
00056 
00057 #ifdef HAVE_CONFIG_H
00058 #include <config.h>
00059 #endif
00060 #include <gimp-print/gimp-print.h>
00061 #include <gimp-print/gimp-print-intl-internal.h>
00062 #include "gimp-print-internal.h"
00063 #include <string.h>
00064 #ifdef DEBUG
00065 #include <stdio.h>
00066 #endif
00067 
00068 #define STP_ECOLOR_LC 4
00069 #define STP_ECOLOR_LM 5
00070 #define STP_ECOLOR_LY 6
00071 
00072 #define false 0
00073 #define true  1
00074 
00075 #define max(a, b) ((a > b) ? (a) : (b))
00076 #define INCH(x)         (72 * x)
00077 
00078 static const stp_dotsize_t single_dotsize[] =
00079 {
00080   { 0x1, 1.0 }
00081 };
00082 
00083 static const stp_shade_t photo_dither_shades[] =
00084 {
00085   { 1.0000, 1, single_dotsize },
00086   { 0.3333, 1, single_dotsize },
00087 };
00088 
00089 
00090 typedef enum Lex_model { m_lex7500,   m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
00091 
00092 #define NCHANNELS (7)
00093 
00094 typedef union {                 /* Offsets from the start of each line */
00095   unsigned long v[NCHANNELS];           /* (really pass) */
00096   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
00097     unsigned long k;
00098     unsigned long c;
00099     unsigned long m;
00100     unsigned long y;
00101     unsigned long C;
00102     unsigned long M;
00103     unsigned long Y;
00104   } p;
00105 } lexmark_lineoff_t;
00106 
00107 typedef union {                 /* Base pointers for each pass */
00108   unsigned char *v[NCHANNELS];
00109   struct {     /* IMPORTANT: order corresponds to STP_ECOLOR_* */
00110     unsigned char *k;
00111     unsigned char *c;
00112     unsigned char *m;
00113     unsigned char *y;
00114     unsigned char *C;
00115     unsigned char *M;
00116     unsigned char *Y;
00117   } p;
00118 } lexmark_linebufs_t;
00119 
00120 
00121 
00122 #ifdef DEBUG
00123 typedef struct testdata {
00124   FILE *ifile;
00125   int x, y, cols, deep;
00126   char colchar[16];
00127   char *input_line;
00128 } testdata;
00129 
00130 const stp_vars_t **dbgfileprn;
00131 int  lex_show_lcount, lex_show_length;
00132 
00133 const stp_vars_t *lex_open_tmp_file();
00134 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length);
00135 static void testprint(testdata *td);
00136 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
00137 #endif
00138 
00139 static void
00140 flush_pass(stp_vars_t *v, int passno, int vertical_subpass);
00141 
00142 /*** resolution specific parameters */
00143 #define DPI300   0
00144 #define DPI600   1
00145 #define DPI1200  2
00146 #define DPI2400  3
00147 #define DPItest  4
00148 
00149 #define V_NOZZLE_MASK 0x3
00150 #define H_NOZZLE_MASK 0xc
00151 #define NOZZLE_MASK   0xf
00152 
00153 #define PRINT_MODE_300   0x100
00154 #define PRINT_MODE_600   0x200
00155 #define PRINT_MODE_1200  0x300
00156 #define PRINT_MODE_2400  0x400
00157 
00158 #define COLOR_MODE_K      0x1000
00159 #define COLOR_MODE_C      0x2000
00160 #define COLOR_MODE_Y      0x4000
00161 #define COLOR_MODE_M      0x8000
00162 #define COLOR_MODE_LC    0x10000
00163 #define COLOR_MODE_LY    0x20000
00164 #define COLOR_MODE_LM    0x40000
00165 #define COLOR_MODE_CMYK   (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
00166 #define COLOR_MODE_CMY    (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
00167 #define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
00168 #define COLOR_MODE_CcMcY  (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
00169 
00170 #define COLOR_MODE_MASK  0x7f000
00171 #define PRINT_MODE_MASK    0xf00
00172 #define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
00173 
00174 #define BWR      0
00175 #define BWL      1
00176 #define CR       2
00177 #define CL       3
00178 
00179 
00180 static const char standard_sat_adjustment[] =
00181 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00182 "<gimp-print>\n"
00183 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
00184 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
00185 /* C */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* B */
00186 /* B */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* M */
00187 /* M */  "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 "  /* R */
00188 /* R */  "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 "  /* Y */
00189 /* Y */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* G */
00190 /* G */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* C */
00191 "</sequence>\n"
00192 "</curve>\n"
00193 "</gimp-print>\n";
00194 
00195 static const char standard_lum_adjustment[] =
00196 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00197 "<gimp-print>\n"
00198 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
00199 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
00200 /* C */  "0.50 0.52 0.56 0.60 0.66 0.71 0.74 0.77 "  /* B */
00201 /* B */  "0.81 0.79 0.74 0.68 0.70 0.74 0.77 0.82 "  /* M */
00202 /* M */  "0.88 0.93 0.95 0.97 0.97 0.96 0.95 0.95 "  /* R */
00203 /* R */  "0.95 0.96 0.97 0.98 0.99 1.00 1.00 1.00 "  /* Y */
00204 /* Y */  "1.00 0.97 0.94 0.92 0.90 0.88 0.85 0.79 "  /* G */
00205 /* G */  "0.69 0.64 0.58 0.54 0.54 0.54 0.53 0.51 "  /* C */
00206 "</sequence>\n"
00207 "</curve>\n"
00208 "</gimp-print>\n";
00209 
00210 static const char standard_hue_adjustment[] =
00211 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
00212 "<gimp-print>\n"
00213 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
00214 "<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
00215 /* C */  "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 "  /* B */
00216 /* B */  "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 "  /* M */
00217 /* M */  "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 "  /* R */
00218 /* R */  "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 "  /* Y */
00219 /* Y */  "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 "  /* G */
00220 /* G */  "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 "  /* C */
00221 "</sequence>\n"
00222 "</curve>\n"
00223 "</gimp-print>\n";
00224 
00225 
00226 /* Codes for possible ink-tank combinations.
00227  * Each combo is represented by the colors that can be used with
00228  * the installed ink-tank(s)
00229  * Combinations of the codes represent the combinations allowed for a model
00230  */
00231 #define LEXMARK_INK_K           1
00232 #define LEXMARK_INK_CMY         2
00233 #define LEXMARK_INK_CMYK        4
00234 #define LEXMARK_INK_CcMmYK      8
00235 #define LEXMARK_INK_CcMmYy     16
00236 #define LEXMARK_INK_CcMmYyK    32
00237 
00238 #define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
00239                               LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
00240 
00241 #define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
00242                               LEXMARK_INK_CcMmYyK)
00243 
00244 /* document feeding */
00245 #define LEXMARK_SLOT_ASF1    1
00246 #define LEXMARK_SLOT_ASF2    2
00247 #define LEXMARK_SLOT_MAN1    4
00248 #define LEXMARK_SLOT_MAN2    8
00249 
00250 /* model peculiarities */
00251 #define LEXMARK_CAP_DMT       1<<0    /* Drop Modulation Technology */
00252 #define LEXMARK_CAP_MSB_FIRST 1<<1    /* how to send data           */
00253 #define LEXMARK_CAP_CMD61     1<<2    /* uses command #0x61         */
00254 #define LEXMARK_CAP_CMD6d     1<<3    /* uses command #0x6d         */
00255 #define LEXMARK_CAP_CMD70     1<<4    /* uses command #0x70         */
00256 #define LEXMARK_CAP_CMD72     1<<5    /* uses command #0x72         */
00257 
00258 
00259 static const int lr_shift_color[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
00260 static const int lr_shift_black[10] = { 9, 18, 2*18 }; /* vertical distance between ever 2nd  inkjet (related to resolution) */
00261 
00262 static const stp_parameter_t the_parameters[] =
00263 {
00264   {
00265     "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
00266     N_("Size of the paper being printed to"),
00267     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00268     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00269   },
00270   {
00271     "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
00272     N_("Type of media (plain paper, photo paper, etc.)"),
00273     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00274     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00275   },
00276   {
00277     "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
00278     N_("Source (input slot) of the media"),
00279     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00280     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00281   },
00282   {
00283     "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
00284     N_("Resolution and quality of the print"),
00285     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00286     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00287   },
00288   {
00289     "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
00290     N_("Type of ink in the printer"),
00291     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
00292     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00293   },
00294   {
00295     "InkChannels", N_("Ink Channels"), N_("Advanced Printer Functionality"),
00296     N_("Ink Channels"),
00297     STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
00298     STP_PARAMETER_LEVEL_INTERNAL, 0, 0, -1, 0, 0
00299   },
00300   {
00301     "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
00302     N_("Printing Output Mode"),
00303     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
00304     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
00305   },
00306 };
00307 
00308 static const int the_parameter_count =
00309 sizeof(the_parameters) / sizeof(const stp_parameter_t);
00310 
00311 typedef struct
00312 {
00313   const stp_parameter_t param;
00314   double min;
00315   double max;
00316   double defval;
00317   int color_only;
00318 } float_param_t;
00319 
00320 static const float_param_t float_parameters[] =
00321 {
00322   {
00323     {
00324       "CyanDensity", N_("Cyan Balance"), N_("Output Level Adjustment"),
00325       N_("Adjust the cyan balance"),
00326       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00327       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
00328     }, 0.0, 2.0, 1.0, 1
00329   },
00330   {
00331     {
00332       "MagentaDensity", N_("Magenta Balance"), N_("Output Level Adjustment"),
00333       N_("Adjust the magenta balance"),
00334       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00335       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
00336     }, 0.0, 2.0, 1.0, 1
00337   },
00338   {
00339     {
00340       "YellowDensity", N_("Yellow Balance"), N_("Output Level Adjustment"),
00341       N_("Adjust the yellow balance"),
00342       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00343       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
00344     }, 0.0, 2.0, 1.0, 1
00345   },
00346   {
00347     {
00348       "BlackDensity", N_("Black Balance"), N_("Output Level Adjustment"),
00349       N_("Adjust the black balance"),
00350       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00351       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
00352     }, 0.0, 2.0, 1.0, 1
00353   },
00354   {
00355     {
00356       "LightCyanTransition", N_("Light Cyan Transition"), N_("Advanced Ink Adjustment"),
00357       N_("Light Cyan Transition"),
00358       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00359       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
00360     }, 0.0, 5.0, 1.0, 1
00361   },
00362   {
00363     {
00364       "LightMagentaTransition", N_("Light Magenta Transition"), N_("Advanced Ink Adjustment"),
00365       N_("Light Magenta Transition"),
00366       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00367       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
00368     }, 0.0, 5.0, 1.0, 1
00369   },
00370 };    
00371 
00372 static const int float_parameter_count =
00373 sizeof(float_parameters) / sizeof(const float_param_t);
00374 
00375 /* returns the offset of the first jet when printing in the other direction */
00376 static int get_lr_shift(int mode)
00377 {
00378 
00379   const int *ptr_lr_shift;
00380 
00381       /* K could only be present if black is printed only. */
00382   if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
00383     ptr_lr_shift = lr_shift_black;
00384   } else {
00385     ptr_lr_shift = lr_shift_color;
00386   }
00387 
00388       switch(mode & PRINT_MODE_MASK)    {
00389         case PRINT_MODE_300:
00390           return ptr_lr_shift[0];
00391           break;
00392         case PRINT_MODE_600:
00393           return ptr_lr_shift[1];
00394           break;
00395         case PRINT_MODE_1200:
00396           return ptr_lr_shift[2];
00397           break;
00398         case PRINT_MODE_2400:
00399           return ptr_lr_shift[2];
00400           break;
00401       }
00402       return 0;
00403 }
00404 
00405 
00406 /*
00407  * head offsets for z52:
00408  *
00409  *      black       black          color         photo
00410  *    cartridge   cartridge      cartridge     cartridge
00411  *      mode I     mode II
00412  *
00413  *              v                 +-----+ --    +-----+ ---
00414  * --- +-----+ ---             v  |     | ^     |     |  ^
00415  *  ^  |     | --- +-----+ --- -- |  C  | 64    | LC  |  |
00416  *  |  |     |  ^  |     |  ^  40 |     | v  v  |     |  |
00417  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
00418  *  |  |     |     |     |  |  ^             28          |
00419  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
00420  *     |     |     |     |  |     |     | ^  ^  |     |  |
00421  * 208 |  K  |     |  K  | 192    |  M  | 64    | LM  | 240
00422  *     |     |     |     |  |     |     | v  v  |     |  |
00423  *  |  |     |     |     |  |     +-----+ -- -- +-----+  |
00424  *  |  |     |     |     |  |  v             28          |
00425  *  |  |     |     |     |  |  -- +-----+ -- -- +-----+  |
00426  *  |  |     |     |     |  v  40 |     | ^  ^  |     |  |
00427  *  v  |     |     +-----+ --- -- |  Y  | 64    |  K  |  |
00428  * --- +-----+                 ^  |     | v     |     |  v
00429  *                                +-----+ --    +-----+ ---
00430  *
00431  */
00432 
00433 static const int head_offset_cmyk[] =
00434 {70, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
00435 /* 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 */
00436 static const int head_offset_cmy[] =
00437 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
00438 static const int head_offset_cCmMyk[] =
00439 {0, 368, 184, 0, 368, 184, 0};  /* k, m, c, y, M, C, Y */
00440 
00441 
00442 
00443 
00444 /**************************************************************************/
00445 /**** Data structures which are describing printer specific parameters ****/
00446 
00447 /* resolution specific parameters (substructure of lexmark_cap_t) */
00448 typedef struct {
00449   const char *name;
00450   const char *text;
00451   int hres;
00452   int vres;
00453   int softweave;
00454   int vertical_passes;
00455   int vertical_oversample;
00456   int unidirectional;      /* print bi/unidirectional */
00457   int resid;               /* resolution id */
00458 } lexmark_res_t;
00459 
00460 #define LEXM_RES_COUNT 30
00461 typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
00462 
00463 
00464 /* ink type parameters (substructure of lexmark_cap_t) */
00465 typedef struct {
00466   int ncolors;
00467   unsigned int used_colors; /* specifies the head colors to be used (e.g. COLOR_MODE_K */
00468   unsigned int pass_length; /* avaliable jets for one color */
00469   int v_top_head_offset;    /* offset from top, wehere the first jet will be found */
00470   int h_catridge_offset;    /* horizontal offset of cartridges */
00471   int h_direction_offset;   /* Offset when printing in the other direction */
00472   const int *head_offset;   /* specifies the offset of head colors */
00473 } lexmark_inkparam_t;
00474 
00475 typedef struct
00476 {
00477   const char *name;
00478   const char *text;
00479   lexmark_inkparam_t ink_parameter[2];
00480 } lexmark_inkname_t;
00481 
00482 
00483 /* main structure which describes all printer specific parameters */
00484 typedef struct {
00485   Lex_model model;    /* printer model */
00486   int max_paper_width;  /* maximum printable paper size in 1/72 inch */
00487   int max_paper_height;
00488   int min_paper_width;  /* Maximum paper width, in points */
00489   int min_paper_height; /* Maximum paper height, in points */
00490   int max_xdpi;
00491   int max_ydpi;
00492   int max_quality;
00493   int border_left;    /* unit is 72 DPI */
00494   int border_right;
00495   int border_top;
00496   int border_bottom;
00497   int inks;           /* installable cartridges (LEXMARK_INK_*) */
00498   int slots;          /* available paperslots */
00499   int features;       /* special bjl settings */
00500   /*** printer internal parameters ***/
00501   /* the unit of the following parameters is identical with max phys unit of the printer */
00502   int offset_left_border;      /* Offset to the left paper border (== border_left=0) */
00503   int offset_top_border;       /* Offset to the top paper border (== border_top=0) */
00504   int x_raster_res;            /* horizontal resolution for positioning of the printer head in DPI */
00505   int y_raster_res;            /* vertical   resolution for positioning of the printer head in DPI */
00506   const lexmark_res_t_array *res_parameters; /* resolution specific parameters; last entry has resid = -1 */
00507   const lexmark_inkname_t *ink_types;  /* type of supported inks */
00508   const char *lum_adjustment;
00509   const char *hue_adjustment;
00510   const char *sat_adjustment;
00511 } lexmark_cap_t;
00512 
00513 
00514 /*****************************************************************/
00515 /**** initialize printer specific data structures ****/
00516 
00517 /*
00518  * z52 specific parameters
00519  */
00520 #define LX_Z52_300_DPI  1
00521 #define LX_Z52_600_DPI  3
00522 #define LX_Z52_1200_DPI 4
00523 #define LX_Z52_2400_DPI 5
00524 
00525 #define LX_Z52_COLOR_PRINT 0
00526 #define LX_Z52_BLACK_PRINT 1
00527 
00528 #define LX_PSHIFT                   0x13
00529 #define LX_Z52_COLOR_MODE_POS       0x9
00530 #define LX_Z52_RESOLUTION_POS       0x7
00531 #define LX_Z52_PRINT_DIRECTION_POS  0x8
00532 
00533 /*static const int IDX_Z52ID =2;*/
00534 static const int IDX_SEQLEN=3;
00535 
00536 /*
00537    head:
00538      1 .. black,
00539      0 .. color
00540 
00541    resolution:
00542      1 .. 300 dpi (for black ?)
00543      2 .. like 1
00544      3 .. 600 dpi (color&black)
00545      4 .. 1200 dpi
00546      5 .. ? like 1
00547 */
00548 
00549 #define LXM_Z52_HEADERSIZE 34
00550 static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
00551 {
00552   0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF,         /* number of packets ----     vvvvvvvvv */
00553   0x01,0x01,0x01,0x1a,0x03,0x01,              /* 0x7-0xc: resolution, direction, head */
00554   0x03,0x60,                                  /* 0xd-0xe HE */
00555   0x04,0xe0,                                  /* 0xf-0x10  HS vertical pos */
00556   0x19,0x5c,                                  /* 0x11-0x12 */
00557   0x0,0x0,                                    /* 0x13-0x14  VO between packges*/
00558   0x0,0x80,                                   /* 0x15-0x16 */
00559   0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0 /* 0x17-0x21 */
00560 };
00561 
00562 #define LXM_Z42_HEADERSIZE 34
00563 static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
00564 {
00565   0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
00566   0x01,0x01,0x01,0x18,0x00,0x01,0x00,
00567   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00568   0x00,0x00,0x00,0x00,0x00,0x00,0x00,
00569   0x00,0x00,0x00,0x00,0x00,0x00
00570 };
00571 
00572 
00573 static const lexmark_res_t_array lexmark_reslist_z52 =  /* LEXM_RES_COUNT entries are allowed !! */
00574 {
00575   /*     name                                                    hres vres softw v_pass overs unidir resid */
00576   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),                  300,  600,  0,    1,    1,    0,    DPI300 },
00577   { "600dpi",         N_ ("600 DPI"),                            600,  600,  0,    1,    1,    0,    DPI600 },
00578   { "600hq",          N_ ("600 DPI high quality"),               600,  600,  1,    4,    1,    0,    DPI600 },
00579   { "600uni",         N_ ("600 DPI Unidirectional"),             600,  600,  0,    1,    1,    1,    DPI600 },
00580   { "1200dpi",        N_ ("1200 DPI"),                          1200, 1200,  1,    1,    1,    0,    DPI1200},
00581   { "1200hq",         N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
00582   { "1200hq2",        N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
00583   { "1200uni",        N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
00584   { "2400x1200dpi",   N_ ("2400 DPI x 1200 DPI"),               2400, 1200,  1,    1,    1,    0,    DPI1200},
00585   { "2400x1200hq",    N_ ("2400 DPI x 1200 DPI high quality"),  2400, 1200,  1,    1,    1,    0,    DPI600 },
00586   { "2400x1200hq2",   N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200,  1,    1,    1,    0,    DPI300},
00587 #ifdef DEBUG
00588   { "testprint",      N_ ("test print"),                        1200, 1200,  1,    1,    1,    0,    DPItest},
00589 #endif
00590   { "",                 "", 0, 0, 0, 0, 0, -1 }
00591 };
00592 
00593 
00594 static const lexmark_inkname_t ink_types_z52[] =
00595 {
00596   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
00597    *                                                        h_catridge_offset
00598    *                                                           h_direction_offset
00599    *                                                               head_offset */
00600   { "CMYK",     N_("Four Color Standard"),
00601     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
00602      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 10, head_offset_cmyk }}},
00603   { "RGB",      N_("Three Color Composite"),
00604     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },  /* we ignor CMY, use black */
00605      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 10, head_offset_cmy }}},
00606   { "PhotoCMYK", N_("Six Color Photo"),
00607     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 10, head_offset_cCmMyk },
00608      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 10, head_offset_cCmMyk }}},
00609   { "PhotoCMY", N_("Five Color Photo Composite"),
00610     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cCmMyk },
00611      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 10, head_offset_cCmMyk }}}, /* we ignor CMY, use black */
00612   { "Gray",     N_("Black"),
00613     {{ 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk },
00614      { 1, COLOR_MODE_K,        208, 324, 0, 10, head_offset_cmyk }}},
00615   { NULL, NULL }
00616 };
00617 
00618 
00619 
00620 /*
00621  * 3200 sepecific stuff
00622  */
00623 #define LXM3200_LEFTOFFS 6254
00624 #define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
00625 
00626 static int lxm3200_headpos = 0;
00627 static int lxm3200_linetoeject = 0;
00628 
00629 #define LXM_3200_HEADERSIZE 24
00630 static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
00631 {
00632   0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00633   0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00634   0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00635 };
00636 
00637 static inline int
00638 lexmark_calc_3200_checksum(unsigned char *data)
00639 {
00640   int ck, i;
00641 
00642   ck = 0;
00643   for(i=1; i<7; i++)ck += data[i];
00644 
00645   return(ck & 255);
00646 }
00647 
00648 
00649 static const lexmark_res_t_array lexmark_reslist_3200 =   /* LEXM_RES_COUNT entries are allowed !! */
00650 {
00651   /*     name                                                    hres vres softw v_pass overs unidir resid */
00652   { "300x600dpi",     N_ ("300 DPI x 600 DPI"),                  300,  600,  0,    1,    1,    0,    DPI300 },
00653   { "600dpi",         N_ ("600 DPI"),                            600,  600,  0,    1,    1,    0,    DPI600 },
00654   { "600hq",          N_ ("600 DPI high quality"),               600,  600,  1,    4,    1,    0,    DPI600 },
00655   { "600uni",         N_ ("600 DPI Unidirectional"),             600,  600,  0,    1,    1,    1,    DPI600 },
00656   { "1200dpi",        N_ ("1200 DPI"),                          1200, 1200,  1,    1,    1,    0,    DPI1200},
00657   { "1200hq",         N_ ("1200 DPI high quality"),             1200, 1200,  1,    1,    1,    0,    DPI300 },
00658   { "1200hq2",        N_ ("1200 DPI highest quality"),          1200, 1200,  1,    1,    1,    0,    DPI600 },
00659   { "1200uni",        N_ ("1200 DPI  Unidirectional"),          1200, 1200,  0,    1,    1,    1,    DPI1200},
00660   { "",                 "", 0, 0, 0, 0, 0, -1 }
00661 };
00662 
00663 
00664 static const lexmark_inkname_t ink_types_3200[] =
00665 {
00666   /*   output_type   ncolors used_colors   pass_length  v_top_head_offset
00667    *                                                        h_catridge_offset
00668    *                                                           h_direction_offset
00669    *                                                               head_offset */
00670   { "CMYK",     N_("Four Color Standard"),
00671     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },
00672      { 4, COLOR_MODE_CMYK,   192/3,   0, 0, 12, head_offset_cmyk }}},
00673   { "RGB",      N_("Three Color Composite"),
00674     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cmyk },  /* we ignor CMY, use black */
00675      { 4, COLOR_MODE_CMY,    192/3,   0, 0, 12, head_offset_cmy }}},
00676   { "PhotoCMYK", N_("Six Color Photo"),
00677     {{ 1, COLOR_MODE_K,      192/3,   0, 0, 12, head_offset_cCmMyk },
00678      { 6, COLOR_MODE_CcMcYK, 192/3,   0, 0, 12, head_offset_cCmMyk }}},
00679   { "PhotoCMY", N_("Five Color Photo Composite"),
00680     {{ 1, COLOR_MODE_K,        208,  20, 0, 12, head_offset_cCmMyk }, /* we ignor CMY, use black */
00681      { 5, COLOR_MODE_CcMcY,  192/3,   0, 0, 12, head_offset_cCmMyk }}},
00682   { NULL, NULL }
00683 };
00684 
00685 
00686 
00687 
00688 
00689 /* main structure */
00690 static const lexmark_cap_t lexmark_model_capabilities[] =
00691 {
00692   /* default settings for unkown models */
00693 
00694   {   (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
00695 
00696   /* tested models */
00697 
00698   { /* Lexmark z52 */
00699     m_z52,
00700     618, 936,         /* max paper size *//* 8.58" x 13 " */
00701     INCH(2), INCH(4), /* min paper size */
00702     2400, 1200, 2, /* max resolution */
00703     0, 0, 5, 15, /* 15 36 border l,r,t,b    unit is 1/72 DPI */
00704     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
00705     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
00706     LEXMARK_CAP_DMT,
00707     /*** printer internal parameters ***/
00708     20,        /* real left paper border */
00709     123,       /* real top paper border */
00710     2400,      /* horizontal resolution of 2400 dpi for positioning */
00711     1200,      /* use a vertical resolution of 1200 dpi for positioning */
00712     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
00713     ink_types_z52,  /* supported inks */
00714     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
00715   },
00716   { /* Lexmark z42 */
00717     m_z42,
00718     618, 936,         /* max paper size *//* 8.58" x 13 " */
00719     INCH(2), INCH(4), /* min paper size */
00720     2400, 1200, 2, /* max resolution */
00721     0, 0, 5, 41, /* border l,r,t,b    unit is 1/72 DPI */
00722     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
00723     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
00724     LEXMARK_CAP_DMT,
00725     /*** printer internal parameters ***/
00726     20,        /* real left paper border */
00727     123,       /* real top paper border */
00728     2400,      /* horizontal resolution of 2400 dpi for positioning */
00729     1200,      /* use a vertical resolution of 1200 dpi for positioning */
00730     &lexmark_reslist_z52,  /* resolution specific parameters of z52 */
00731     ink_types_z52,  /* supported inks */
00732     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
00733   },
00734   { /* Lexmark 3200 */
00735     m_3200,
00736     618, 936,      /* 8.58" x 13 " */
00737     INCH(2), INCH(4), /* min paper size */
00738     1200, 1200, 2,
00739     11, 9, 10, 18,
00740     LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
00741     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
00742     LEXMARK_CAP_DMT,
00743     /*** printer internal parameters ***/
00744     0,         /* real left paper border */
00745     300,       /* real top paper border */
00746     1200,      /* horizontal resolution of ?? dpi for positioning */
00747     1200,      /* use a vertical resolution of 1200 dpi for positioning */
00748     &lexmark_reslist_3200,  /* resolution specific parameters of 3200 */
00749     ink_types_3200,  /* supported inks */
00750     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
00751   },
00752   { /*  */
00753     m_lex7500,
00754     618, 936,      /* 8.58" x 13 " */
00755     INCH(2), INCH(4), /* min paper size */
00756     2400, 1200, 2,
00757     11, 9, 10, 18,
00758     LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
00759     LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
00760     LEXMARK_CAP_DMT,
00761     /*** printer internal parameters ***/
00762     0,         /* real left paper border */
00763     300,       /* real top paper border */
00764     1200,      /* horizontal resolutio of ??? dpi for positioning */
00765     1200,      /* use a vertical resolution of 1200 dpi for positioning */
00766     &lexmark_reslist_3200,  /* resolution specific parameters of ?? */
00767     ink_types_3200,  /* supported inks */
00768     standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
00769   },
00770 };
00771 
00772 
00773 
00774 
00775 
00776 typedef struct lexm_privdata_weave {
00777   const lexmark_inkparam_t *ink_parameter;
00778   int           bidirectional; /* tells us if we are allowed to print bidirectional */
00779   int           direction;     /* stores the last direction or print head */
00780   int           hoffset;
00781   int model;
00782   int width;
00783   int ydpi;
00784   int xdpi;
00785   int physical_xdpi;
00786   int last_pass_offset;
00787   int jets;
00788   int bitwidth;
00789   int ncolors;
00790   int horizontal_weave;
00791   unsigned char *outbuf;
00792 } lexm_privdata_weave;
00793 
00794 
00795 /*
00796  * internal functions
00797  */
00798 static int model_to_index(int model)
00799 {
00800   int i;
00801   int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
00802   for (i=0; i<models; i++) {
00803     if (lexmark_model_capabilities[i].model == model) {
00804       return i;
00805     }
00806   }
00807   return -1;
00808 }
00809 
00810 
00811 static const lexmark_cap_t *
00812 lexmark_get_model_capabilities(int model)
00813 {
00814   int i = model_to_index(model);
00815 
00816   if (i != -1) {
00817     return &(lexmark_model_capabilities[i]);
00818   }
00819 #ifdef DEBUG
00820   stp_erprintf("lexmark: model %d not found in capabilities list.\n",model);
00821 #endif
00822   return &(lexmark_model_capabilities[0]);
00823 }
00824 
00825 
00826 
00827 typedef struct
00828 {
00829   const char *name;
00830   const char *text;
00831   int paper_feed_sequence;
00832   int platen_gap;
00833   double base_density;
00834   double k_lower_scale;
00835   double k_upper;
00836   double cyan;
00837   double magenta;
00838   double yellow;
00839   double p_cyan;
00840   double p_magenta;
00841   double p_yellow;
00842   double saturation;
00843   double gamma;
00844   int feed_adjustment;
00845   int vacuum_intensity;
00846   int paper_thickness;
00847   const char *hue_adjustment;
00848   const char *lum_adjustment;
00849   const char *sat_adjustment;
00850 } paper_t;
00851 
00852 
00853 
00854 static const paper_t lexmark_paper_list[] =
00855 {
00856   { "Plain", N_("Plain Paper"),
00857     1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
00858     1, 1.0, 0x6b, 0x1a, 0x01,
00859     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00860   { "GlossyFilm", N_("Glossy Film"),
00861     3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00862     1, 1.0, 0x6d, 0x00, 0x01,
00863     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00864   { "Transparency", N_("Transparencies"),
00865     3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00866     1.0, 1.0, 0x6d, 0x00, 0x02,
00867     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00868   { "Envelope", N_("Envelopes"),
00869     4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00870     1, 1.0, 0x6b, 0x1a, 0x01,
00871     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00872   { "Matte", N_("Matte Paper"),
00873     7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
00874     1, 1.0, 0x00, 0x00, 0x02,
00875     standard_hue_adjustment, standard_sat_adjustment, standard_sat_adjustment},
00876   { "Inkjet", N_("Inkjet Paper"),
00877     7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00878     1, 1.0, 0x6b, 0x1a, 0x01,
00879     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00880   { "Coated", N_("Photo Quality Inkjet Paper"),
00881     7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00882     1, 1.0, 0x6b, 0x1a, 0x01,
00883     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00884   { "Photo", N_("Photo Paper"),
00885     8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00886     1, 1.0, 0x67, 0x00, 0x02,
00887     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00888   { "GlossyPhoto", N_("Premium Glossy Photo Paper"),
00889     8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
00890     1, 1.0, 0x80, 0x00, 0x02,
00891     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00892   { "Luster", N_("Premium Luster Photo Paper"),
00893     8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00894     1.0, 1.0, 0x80, 0x00, 0x02,
00895     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00896   { "GlossyPaper", N_("Photo Quality Glossy Paper"),
00897     6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00898     1.0, 1.0, 0x6b, 0x1a, 0x01,
00899     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00900   { "Ilford", N_("Ilford Heavy Paper"),
00901     8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00902     1, 1.0, 0x80, 0x00, 0x02,
00903     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00904   { "Other", N_("Other"),
00905     0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
00906     1, 1.0, 0x6b, 0x1a, 0x01,
00907     standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
00908 };
00909 
00910 static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
00911 
00912 static const lexmark_inkname_t *
00913 lexmark_get_ink_type(const char *name, int printing_color, const lexmark_cap_t * caps)
00914 {
00915   int i = 0;
00916   const lexmark_inkname_t *ink_type = caps->ink_types;
00917 
00918   if (name)
00919     for (i=0; ((ink_type[i].name != NULL) &&
00920                (strcmp(name, ink_type[i].name)  != 0)); i++) ;
00921   return &(ink_type[i]);
00922 
00923 }
00924 
00925 static const lexmark_inkparam_t *
00926 lexmark_get_ink_parameter(const char *name, int printing_color, const lexmark_cap_t * caps, const stp_vars_t *nv)
00927 {
00928   const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, printing_color, caps);
00929 
00930   if (ink_type->name == NULL) {
00931     return (NULL); /* not found ! */
00932   }
00933 
00934   return &(ink_type->ink_parameter[printing_color]);
00935 }
00936 
00937 
00938 static const paper_t *
00939 get_media_type(const char *name, const lexmark_cap_t * caps)
00940 {
00941   int i;
00942   if (name)
00943     {
00944       for (i = 0; i < paper_type_count; i++)
00945         {
00946           if (!strcmp(name, lexmark_paper_list[i].name))
00947             return &(lexmark_paper_list[i]);
00948         }
00949     }
00950   return NULL;
00951 }
00952 
00953 static int
00954 lexmark_source_type(const char *name, const lexmark_cap_t * caps)
00955 {
00956   if (name)
00957     {
00958       if (!strcmp(name,"Auto"))    return 4;
00959       if (!strcmp(name,"Manual"))    return 0;
00960       if (!strcmp(name,"ManualNP")) return 1;
00961     }
00962 
00963 #ifdef DEBUG
00964   stp_erprintf("lexmark: Unknown source type '%s' - reverting to auto\n",name);
00965 #endif
00966   return 4;
00967 }
00968 
00969 
00970 
00971 /*******************************
00972 lexmark_head_offset
00973 *******************************/
00974 static const lexmark_lineoff_t *
00975 lexmark_head_offset(int ydpi,                       /* i */
00976                     const char *ink_type,           /* i */
00977                     const lexmark_cap_t * caps,     /* i */
00978                     const lexmark_inkparam_t *ink_parameter, /* i */
00979                     lexmark_lineoff_t *lineoff_buffer)  /* o */
00980 {
00981   int i;
00982 
00983 #ifdef DEBUG
00984   stp_erprintf("  sizie %d,  size_v %d, size_v[0] %d\n", sizeof(*lineoff_buffer), sizeof(lineoff_buffer->v), sizeof(lineoff_buffer->v[0]));
00985 #endif
00986   memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
00987 
00988   for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
00989     lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
00990   }
00991   return (lineoff_buffer);
00992 }
00993 
00994 
00995 #if 0
00996 /*******************************
00997 lexmark_size_type
00998 *******************************/
00999 /* This method is actually not used.
01000    Is there a possibility to set such value ???????????? */
01001 static unsigned char
01002 lexmark_size_type(const stp_vars_t *v, const lexmark_cap_t * caps)
01003 {
01004   const stp_papersize_t *pp = stp_get_papersize_by_size(stp_get_page_height(v),
01005                                                         stp_get_page_width(v));
01006   if (pp)
01007     {
01008       const char *name = pp->name;
01009       /* built ins: */
01010       if (!strcmp(name,"A5"))           return 0x01;
01011       if (!strcmp(name,"A4"))           return 0x03;
01012       if (!strcmp(name,"B5"))           return 0x08;
01013       if (!strcmp(name,"Letter"))       return 0x0d;
01014       if (!strcmp(name,"Legal"))        return 0x0f;
01015       if (!strcmp(name,"COM10"))        return 0x16;
01016       if (!strcmp(name,"DL"))           return 0x17;
01017       if (!strcmp(name,"LetterExtra"))  return 0x2a;
01018       if (!strcmp(name,"A4Extra"))      return 0x2b;
01019       if (!strcmp(name,"w288h144"))     return 0x2d;
01020       /* custom */
01021 
01022 #ifdef DEBUG
01023       stp_erprintf("lexmark: Unknown paper size '%s' - using custom\n",name);
01024     } else {
01025       stp_erprintf("lexmark: Couldn't look up paper size %dx%d - "
01026               "using custom\n",stp_get_page_height(v), stp_get_page_width(v));
01027 #endif
01028     }
01029   return 0;
01030 }
01031 #endif
01032 
01033 
01034 static int lexmark_get_phys_resolution_vertical(int model)
01035 {
01036   return 600;
01037 }
01038 
01039 #if 0
01040 static int lexmark_get_phys_resolution_horizontal(int model)
01041 {
01042   return 1200;
01043 }
01044 #endif
01045 
01046 static const lexmark_res_t
01047 *lexmark_get_resolution_para(int model, const char *resolution)
01048 {
01049   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
01050 
01051   const lexmark_res_t *res = *(caps->res_parameters); /* get the resolution specific parameters of printer */
01052 
01053   if (resolution)
01054     {
01055       while (res->hres)
01056         {
01057           if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
01058               (res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
01059               (!strcmp(resolution, res->name)))
01060             {
01061               return res;
01062             }
01063           res++;
01064         }
01065     }
01066   stp_erprintf("lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
01067   return NULL;
01068 }
01069 
01070 
01071 static int
01072 lexmark_print_bidirectional(int model, const char *resolution)
01073 {
01074   const lexmark_res_t *res_para = lexmark_get_resolution_para(model, resolution);
01075   return !res_para->unidirectional;
01076 }
01077 
01078 static const char *
01079 lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
01080 {
01081   return (caps->lum_adjustment);
01082 }
01083 
01084 static const char *
01085 lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
01086 {
01087   return (caps->hue_adjustment);
01088 }
01089 
01090 static const char *
01091 lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
01092 {
01093   return (caps->sat_adjustment);
01094 }
01095 
01096 
01097 static void
01098 lexmark_describe_resolution(const stp_vars_t *v, int *x, int *y)
01099 {
01100   const char *resolution = stp_get_string_parameter(v, "Resolution");
01101   const lexmark_res_t *res =
01102     lexmark_get_resolution_para(stp_get_model_id(v), resolution);
01103 
01104   if (res)
01105     {
01106       *x = res->hres;
01107       *y = res->vres;
01108       return;
01109     }
01110   *x = -1;
01111   *y = -1;
01112 }
01113 
01114 
01115 static stp_param_string_t media_sources[] =
01116 {
01117   { "Auto",             N_("Auto Sheet Feeder") },
01118   { "Manual",           N_("Manual with Pause") },
01119   { "ManualNP",         N_("Manual without Pause") }
01120 };
01121 
01122 
01123 /*
01124  * 'lexmark_parameters()' - Return the parameter values for the given parameter.
01125  */
01126 
01127 static stp_parameter_list_t
01128 lexmark_list_parameters(const stp_vars_t *v)
01129 {
01130   stp_parameter_list_t *ret = stp_parameter_list_create();
01131   int i;
01132   for (i = 0; i < the_parameter_count; i++)
01133     stp_parameter_list_add_param(ret, &(the_parameters[i]));
01134   for (i = 0; i < float_parameter_count; i++)
01135     stp_parameter_list_add_param(ret, &(float_parameters[i].param));
01136   return ret;
01137 }
01138 
01139 static const char *
01140 lexmark_describe_output(const stp_vars_t *v)
01141 {
01142   int printing_color = 0;
01143   int model = stp_get_model_id(v);
01144   const lexmark_cap_t *caps = lexmark_get_model_capabilities(model);
01145   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
01146   const char *ink_type = stp_get_string_parameter(v, "InkType");
01147   const lexmark_inkparam_t *ink_parameter;
01148 
01149   if (!print_mode || strcmp(print_mode, "Color") == 0)
01150     printing_color = 1;
01151 
01152   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
01153 
01154   if (ink_parameter->used_colors == COLOR_MODE_K ||
01155       caps->inks == LEXMARK_INK_K || !printing_color)
01156     return "Grayscale";
01157   else if (!(ink_parameter->used_colors & COLOR_MODE_K))
01158     return "CMY";
01159   else
01160     return "CMYK";
01161 }
01162 
01163 static void
01164 lexmark_parameters(const stp_vars_t *v, const char *name,
01165                    stp_parameter_t *description)
01166 {
01167   int           i;
01168 
01169   const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
01170   description->p_type = STP_PARAMETER_TYPE_INVALID;
01171 
01172   if (name == NULL)
01173     return;
01174 
01175   for (i = 0; i < float_parameter_count; i++)
01176     if (strcmp(name, float_parameters[i].param.name) == 0)
01177       {
01178         stp_fill_parameter_settings(description,
01179                                     &(float_parameters[i].param));
01180         description->deflt.dbl = float_parameters[i].defval;
01181         description->bounds.dbl.upper = float_parameters[i].max;
01182         description->bounds.dbl.lower = float_parameters[i].min;
01183         return;
01184       }
01185 
01186   for (i = 0; i < the_parameter_count; i++)
01187     if (strcmp(name, the_parameters[i].name) == 0)
01188       {
01189         stp_fill_parameter_settings(description, &(the_parameters[i]));
01190         break;
01191       }
01192 
01193   if (strcmp(name, "PageSize") == 0)
01194   {
01195     unsigned int height_limit, width_limit;
01196     unsigned int min_height_limit, min_width_limit;
01197     int papersizes = stp_known_papersizes();
01198     description->bounds.str = stp_string_list_create();
01199 
01200     width_limit  = caps->max_paper_width;
01201     height_limit = caps->max_paper_height;
01202     min_width_limit  = caps->min_paper_width;
01203     min_height_limit = caps->min_paper_height;
01204 
01205     for (i = 0; i < papersizes; i++) {
01206       const stp_papersize_t *pt = stp_get_papersize_by_index(i);
01207       if (strlen(pt->name) > 0 &&
01208           pt->width <= width_limit && pt->height <= height_limit &&
01209           (pt->height >= min_height_limit || pt->height == 0) &&
01210           (pt->width >= min_width_limit || pt->width == 0))
01211         {
01212           if (stp_string_list_count(description->bounds.str) == 0)
01213             description->deflt.str = pt->name;
01214           stp_string_list_add_string(description->bounds.str,
01215                                      pt->name, pt->text);
01216         }
01217     }
01218   }
01219   else if (strcmp(name, "Resolution") == 0)
01220   {
01221     const lexmark_res_t *res;
01222     description->bounds.str = stp_string_list_create();
01223 
01224     res =  *(caps->res_parameters); /* get resolution specific parameters of printer */
01225 
01226     /* check for allowed resolutions */
01227     while (res->hres)
01228       {
01229         if (stp_string_list_count(description->bounds.str) == 0)
01230           description->deflt.str = res->name;
01231         stp_string_list_add_string(description->bounds.str,
01232                                   res->name, _(res->text));
01233         res++;
01234       }
01235   }
01236   else if (strcmp(name, "InkType") == 0)
01237   {
01238     description->bounds.str = stp_string_list_create();
01239     description->deflt.str = caps->ink_types[0].name;
01240     for (i = 0; caps->ink_types[i].name != NULL; i++)
01241       stp_string_list_add_string(description->bounds.str,
01242                                caps->ink_types[i].name,
01243                                _(caps->ink_types[i].text));
01244   }
01245   else if (strcmp(name, "MediaType") == 0)
01246   {
01247     description->bounds.str = stp_string_list_create();
01248     description->deflt.str = lexmark_paper_list[0].name;
01249     for (i = 0; i < paper_type_count; i++)
01250       stp_string_list_add_string(description->bounds.str,
01251                                lexmark_paper_list[i].name,
01252                                _(lexmark_paper_list[i].text));
01253   }
01254   else if (strcmp(name, "InputSlot") == 0)
01255   {
01256     description->bounds.str = stp_string_list_create();
01257     description->deflt.str = media_sources[0].name;
01258     for (i = 0; i < sizeof(media_sources) / sizeof(stp_param_string_t); i++)
01259       stp_string_list_add_string(description->bounds.str,
01260                                media_sources[i].name,
01261                                _(media_sources[i].name));
01262   }
01263   else if (strcmp(name, "InkChannels") == 0)
01264     {
01265       if (caps->inks & LEXMARK_INK_CcMmYyK)
01266         description->deflt.integer = 7;
01267       else if (caps->inks & LEXMARK_INK_CcMmYK)
01268         description->deflt.integer = 6;
01269       else if (caps->inks & LEXMARK_INK_CMYK)
01270         description->deflt.integer = 4;
01271       else if (caps->inks & LEXMARK_INK_CMY)
01272         description->deflt.integer = 3;
01273       else
01274         description->deflt.integer = 1;
01275       description->bounds.integer.lower = -1;
01276       description->bounds.integer.upper = -1;
01277     }
01278   else if (strcmp(name, "PrintingMode") == 0)
01279     {
01280       description->bounds.str = stp_string_list_create();
01281       stp_string_list_add_string
01282         (description->bounds.str, "Color", _("Color"));
01283       stp_string_list_add_string
01284         (description->bounds.str, "BW", _("Black and White"));
01285       description->deflt.str =
01286         stp_string_list_param(description->bounds.str, 0)->name;
01287     }
01288 }
01289 
01290 /*
01291  * 'lexmark_imageable_area()' - Return the imageable area of the page.
01292  */
01293 
01294 static void
01295 internal_imageable_area(const stp_vars_t *v,   /* I */
01296                         int  use_paper_margins,
01297                         int  *left,     /* O - Left position in points */
01298                         int  *right,    /* O - Right position in points */
01299                         int  *bottom,   /* O - Bottom position in points */
01300                         int  *top)      /* O - Top position in points */
01301 {
01302   int   width, length;                  /* Size of page */
01303   int left_margin = 0;
01304   int right_margin = 0;
01305   int bottom_margin = 0;
01306   int top_margin = 0;
01307   const char *media_size = stp_get_string_parameter(v, "PageSize");
01308   const stp_papersize_t *pt = NULL;
01309   const lexmark_cap_t *caps =
01310     lexmark_get_model_capabilities(stp_get_model_id(v));
01311 
01312 
01313   if (media_size && use_paper_margins)
01314     pt = stp_get_papersize_by_name(media_size);
01315 
01316   stp_default_media_size(v, &width, &length);
01317   if (pt)
01318     {
01319       left_margin = pt->left;
01320       right_margin = pt->right;
01321       bottom_margin = pt->bottom;
01322       top_margin = pt->top;
01323     }
01324   left_margin = max(left_margin, caps->border_left);
01325   right_margin = max(right_margin, caps->border_right);
01326   top_margin = max(top_margin, caps->border_top);
01327   bottom_margin = max(bottom_margin, caps->border_bottom);
01328 
01329   *left =       left_margin;
01330   *right =      width - right_margin;
01331   *top =        top_margin;
01332   *bottom =     length - bottom_margin;
01333 }
01334 
01335 static void
01336 lexmark_imageable_area(const stp_vars_t *v,   /* I */
01337                        int  *left,      /* O - Left position in points */
01338                        int  *right,     /* O - Right position in points */
01339                        int  *bottom,    /* O - Bottom position in points */
01340                        int  *top)       /* O - Top position in points */
01341 {
01342   internal_imageable_area(v, 1, left, right, bottom, top);
01343 }
01344 
01345 static void
01346 lexmark_limit(const stp_vars_t *v,              /* I */
01347               int *width,
01348               int *height,
01349               int *min_width,
01350               int *min_height)
01351 {
01352   const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
01353   *width =      caps->max_paper_width;
01354   *height =     caps->max_paper_height;
01355   *min_width =  caps->min_paper_width;
01356   *min_height = caps->min_paper_height;
01357 }
01358 
01359 
01360 
01361 static int
01362 lexmark_init_printer(const stp_vars_t *v, const lexmark_cap_t * caps,
01363                      int printing_color,
01364                      const char *source_str,
01365                      int xdpi, int ydpi,
01366                      int page_width, int page_height,
01367                      int top, int left,
01368                      int use_dmt)
01369 {
01370 
01371   /* because the details of the header sequence are not known, we simply write it as one image. */
01372 
01373 #define LXM_Z52_STARTSIZE 0x35
01374   /* 300 dpi */
01375   unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
01376                                            0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
01377                                            0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
01378                                            0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
01379                                            0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
01380                                            0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
01381                                            0xf0,0x1b,0x2a,0x07,0x63};
01382 
01383 #define LXM_Z42_STARTSIZE 0x30
01384   /* 600 dpi */
01385   unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
01386                                            0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
01387                                            0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
01388                                            0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
01389                                            0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
01390                                            0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
01391 
01392   #define ESC2a "\033\052"
01393 
01394 
01395 
01396 #define LXM_3200_STARTSIZE 32
01397 
01398   unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
01399   {
01400     0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
01401     0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
01402     0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
01403     0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
01404   };
01405 
01406   /* write init sequence */
01407   switch(caps->model)
01408         {
01409                 case m_z52:
01410                         stp_zfwrite((const char *) startHeader_z52,
01411                                     LXM_Z52_STARTSIZE,1,v);
01412 #ifdef DEBUG
01413                         lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
01414 #endif
01415                 case m_z42:
01416                         stp_zfwrite((const char *) startHeader_z42,
01417                                     LXM_Z42_STARTSIZE,1,v);
01418 #ifdef DEBUG
01419                         lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
01420 #endif
01421                         break;
01422 
01423                 case m_3200:
01424                         stp_zfwrite((const char *) startHeader_3200,
01425                                     LXM_3200_STARTSIZE, 1, v);
01426                         break;
01427 
01428                 default:
01429                         stp_erprintf("Unknown printer !! %i\n", caps->model);
01430                         return 0;
01431   }
01432 
01433 
01434 
01435   /*
01436 #ifdef DEBUG
01437   stp_erprintf("lexmark: printable size = %dx%d (%dx%d) %02x%02x %02x%02x\n",
01438           page_width,page_height,printable_width,printable_length,
01439           arg_70_1,arg_70_2,arg_70_3,arg_70_4);
01440 #endif
01441   */
01442   return 1;
01443 }
01444 
01445 static void lexmark_deinit_printer(const stp_vars_t *v, const lexmark_cap_t * caps)
01446 {
01447 
01448         switch(caps->model)     {
01449                 case m_z52:
01450                 {
01451                         char buffer[40];
01452 
01453                         memcpy(buffer, ESC2a, 2);
01454                         buffer[2] = 0x7;
01455                         buffer[3] = 0x65;
01456 
01457 #ifdef DEBUG
01458                         stp_erprintf("lexmark: <<eject page.>> %x %x %x %x   %lx\n", buffer[0],  buffer[1], buffer[2], buffer[3], dbgfileprn);
01459                         lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
01460 #endif
01461                         /* eject page */
01462                         stp_zfwrite(buffer, 1, 4, v);
01463                 }
01464                 break;
01465 
01466                 case m_z42:
01467                 {
01468                         unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
01469 #ifdef DEBUG
01470                         stp_erprintf("lexmark: <<eject page.>>\n");
01471                         lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
01472 #endif
01473                         /* eject page */
01474                         stp_zfwrite((char *)buffer, 1, 12, v);
01475                 }
01476                 break;
01477 
01478                 case m_3200:
01479                 {
01480                   unsigned char buffer[24] =
01481                   {
01482                     0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
01483                     0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
01484                     0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
01485                   };
01486 
01487 #ifdef DEBUG
01488                         stp_erprintf("Headpos: %d\n", lxm3200_headpos);
01489 #endif
01490 
01491                         lxm3200_linetoeject += 2400;
01492                         buffer[3] = lxm3200_linetoeject >> 8;
01493                         buffer[4] = lxm3200_linetoeject & 0xff;
01494                         buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
01495                         buffer[11] = lxm3200_headpos >> 8;
01496                         buffer[12] = lxm3200_headpos & 0xff;
01497                         buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
01498 
01499                         stp_zfwrite((const char *)buffer, 24, 1, v);
01500                 }
01501                 break;
01502 
01503                 case m_lex7500:
01504                         break;
01505         }
01506 
01507 }
01508 
01509 
01510 /* paper_shift() -- shift paper in printer -- units are unknown :-)
01511  */
01512 static void paper_shift(const stp_vars_t *v, int offset, const lexmark_cap_t * caps)
01513 {
01514         switch(caps->model)     {
01515                 case m_z52:
01516                 case m_z42:
01517                 {
01518                         unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
01519                         if(offset == 0)return;
01520                         buf[3] = (unsigned char)(offset >> 8);
01521                         buf[4] = (unsigned char)(offset & 0xFF);
01522                         stp_zfwrite((const char *)buf, 1, 5, v);
01523 #ifdef DEBUG
01524                         lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
01525 #endif
01526                 }
01527                 break;
01528 
01529                 case m_3200:
01530                 {
01531                         unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
01532                         if(offset == 0)return;
01533                         lxm3200_linetoeject -= offset;
01534                         buf[3] = (unsigned char)(offset >> 8);
01535                         buf[4] = (unsigned char)(offset & 0xff);
01536                         buf[7] = lexmark_calc_3200_checksum(buf);
01537                         stp_zfwrite((const char *)buf, 1, 8, v);
01538                 }
01539                 break;
01540 
01541                 case m_lex7500:
01542                         break;
01543         }
01544 
01545 #ifdef DEBUG
01546         stp_erprintf("Lines to eject: %d\n", lxm3200_linetoeject);
01547 #endif
01548 }
01549 
01550 /*
01551  * 'advance_buffer()' - Move (num) lines of length (len) down one line
01552  *                      and sets first line to 0s
01553  *                      accepts NULL pointers as buf
01554  *                  !!! buf must contain more than (num) lines !!!
01555  *                      also sets first line to 0s if num<1
01556  */
01557 #if 0
01558 static void
01559 lexmark_advance_buffer(unsigned char *buf, int len, int num)
01560 {
01561   if (!buf || !len) return;
01562   if (num>0) memmove(buf+len,buf,len*num);
01563   memset(buf,0,len);
01564 }
01565 #endif
01566 
01567 static double
01568 get_double_param(stp_vars_t *v, const char *param)
01569 {
01570   if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
01571     return stp_get_float_parameter(v, param);
01572   else
01573     return 1.0;
01574 }
01575 
01576 /**********************************************************
01577  * lexmark_print() - Print an image to a LEXMARK printer.
01578  **********************************************************/
01579 /* This method should not be printer dependent (mybe it is because of nozzle count and other things) */
01580 /* The method will set the printing method depending on the selected printer.
01581    It will define the colors to be used and the resolution.
01582    Additionally the pass_length will be defined.
01583    The method lexmark_write() is responsible to handle the received lines
01584    in a correct way.
01585 */
01586 static int
01587 lexmark_do_print(stp_vars_t *v, stp_image_t *image)
01588 {
01589   int           status = 1;
01590   int           y;              /* Looping vars */
01591   int           xdpi, ydpi;     /* Resolution */
01592   int           n;              /* Output number */
01593   int page_width,       /* Width of page */
01594     page_height,        /* Length of page */
01595     page_left,
01596     page_top,
01597     page_right,
01598     page_bottom,
01599     page_true_height,   /* True length of page */
01600     out_width,  /* Width of image on page in pixles */
01601     out_height, /* Length of image on page */
01602     out_channels,       /* Output bytes per pixel */
01603     length,             /* Length of raster data in bytes*/
01604     buf_length,     /* Length of raster data buffer (dmt) */
01605     errdiv,             /* Error dividend */
01606     errmod,             /* Error modulus */
01607     errval,             /* Current error value */
01608     errline,    /* Current raster line */
01609     errlast;    /* Last raster line loaded */
01610   unsigned      zero_mask;
01611   int           image_height,
01612                 image_width;
01613   int           use_dmt = 0;
01614   int pass_length=0;              /* count of inkjets for one pass */
01615   int add_top_offset=0;              /* additional top offset */
01616   int printMode = 0;
01617     int source;
01618   /* Lexmark do not have differnet pixel sizes. We have to correct the density according the print resolution. */
01619   double  densityDivisor;            /* This parameter is will adapt the density according the resolution */
01620   double k_lower, k_upper;
01621   int  physical_xdpi = 0;
01622   int  physical_ydpi = 0;
01623   int i;
01624 
01625   stp_curve_t *lum_adjustment = NULL;
01626   stp_curve_t *hue_adjustment = NULL;
01627   stp_curve_t *sat_adjustment = NULL;
01628 
01629   /* weave parameters */
01630   lexmark_linebufs_t cols;
01631   int  nozzle_separation;
01632   int  horizontal_passes;
01633   int  ncolors;
01634   lexm_privdata_weave privdata;
01635 
01636   lexmark_lineoff_t lineoff_buffer;  /* holds the line offsets of each color */
01637 #ifdef DEBUG
01638   testdata td;
01639 #endif
01640 
01641 
01642   int           model         = stp_get_model_id(v);
01643   const char    *resolution   = stp_get_string_parameter(v, "Resolution");
01644   const char    *media_type   = stp_get_string_parameter(v, "MediaType");
01645   const char    *media_source = stp_get_string_parameter(v, "InputSlot");
01646   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
01647   int printing_color = 0;
01648   const char    *ink_type     = stp_get_string_parameter(v, "InkType");
01649   int           top = stp_get_top(v);
01650   int           left = stp_get_left(v);
01651 
01652   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
01653   const lexmark_res_t *res_para_ptr =
01654     lexmark_get_resolution_para(model, resolution);
01655   const paper_t *media = get_media_type(media_type,caps);
01656   const lexmark_inkparam_t *ink_parameter;
01657 
01658   stp_prune_inactive_options(v);
01659 
01660 #ifdef DEBUG
01661   dbgfileprn = lex_open_tmp_file(); /* open file with xx */
01662 #endif
01663 
01664   if (!stp_verify(v))
01665     {
01666       stp_eprintf(v, "Print options not verified; cannot print.\n");
01667       return 0;
01668     }
01669   if (strcmp(print_mode, "Color") == 0)
01670     printing_color = 1;
01671 
01672   ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
01673 
01674   if (ink_parameter == NULL)
01675     {
01676       stp_eprintf(v, "Illegal Ink Type specified; cannot print.\n");
01677       return 0;
01678     }
01679 
01680   stp_image_init(image);
01681 
01682   source= lexmark_source_type(media_source,caps);
01683 
01684   /* force grayscale if image is grayscale
01685    *                 or single black cartridge installed
01686    */
01687 
01688   if ((ink_parameter->used_colors == COLOR_MODE_K) ||
01689       (caps->inks == LEXMARK_INK_K))
01690     {
01691       printing_color = 0;
01692       stp_set_string_parameter(v, "PrintingMode", "BW");
01693     }
01694 
01695   /*
01696    * Choose the correct color conversion function...
01697    */
01698 
01699 
01700   ncolors = ink_parameter->ncolors;
01701   printMode = ink_parameter->used_colors;
01702   pass_length = ink_parameter->pass_length;
01703   add_top_offset = ink_parameter->v_top_head_offset;
01704 
01705 
01706   /*
01707    * Figure out the output resolution...
01708    */
01709 
01710   stp_describe_resolution(v, &xdpi, &ydpi);
01711 #ifdef DEBUG
01712   stp_erprintf("lexmark: resolution=%dx%d\n",xdpi,ydpi);
01713 #endif
01714 
01715   switch (res_para_ptr->resid) {
01716   case DPI300:
01717     physical_xdpi = 300;
01718     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
01719     break;
01720   case DPI600:
01721     physical_xdpi = 600;
01722     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
01723     break;
01724   case DPI1200:
01725   case DPItest:
01726     physical_xdpi = 1200;
01727     physical_ydpi = lexmark_get_phys_resolution_vertical(model);
01728     break;
01729   default:
01730     return 0;
01731     break;
01732   }
01733   /* adapt the density */
01734   densityDivisor = ((xdpi / 300)*(ydpi/ 600));
01735 
01736 #ifdef DEBUG
01737   if (res_para_ptr->resid == DPItest) {
01738     stp_erprintf("Start test print1\n");
01739     doTestPrint = 1;
01740   }
01741 #endif
01742 
01743   if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
01744     /* in case of photo mode we have to go a bit ligther */
01745 densityDivisor /= 1.2;
01746   }
01747 
01748   nozzle_separation = ydpi / physical_ydpi;
01749 
01750   horizontal_passes = xdpi / physical_xdpi;
01751 #ifdef DEBUG
01752   stp_erprintf("lexmark: horizontal_passes %i, xdpi %i, physical_xdpi %i\n",
01753                horizontal_passes, xdpi, physical_xdpi);
01754 #endif
01755 
01756 
01757 
01758 
01759   if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
01760       (caps->features & LEXMARK_CAP_DMT)) {
01761     use_dmt= 1;
01762 #ifdef DEBUG
01763     stpi_erprintf("lexmark: using drop modulation technology\n");
01764 #endif
01765   }
01766 
01767   /*
01768   * Compute the output size...
01769   */
01770 
01771   out_width = stp_get_width(v);
01772   out_height = stp_get_height(v);
01773 
01774   internal_imageable_area(v, 0, &page_left, &page_right,
01775                           &page_bottom, &page_top);
01776   left -= page_left;
01777   top -= page_top;
01778   page_width = page_right - page_left;
01779   page_height = page_bottom - page_top;
01780 
01781 #ifdef DEBUG
01782   stp_erprintf("page_right %d, page_left %d, page_top %d, page_bottom %d, left %d, top %d\n",page_right, page_left, page_top, page_bottom,left, top);
01783 #endif
01784 
01785   image_height = stp_image_height(image);
01786   image_width = stp_image_width(image);
01787 
01788   stp_default_media_size(v, &n, &page_true_height);
01789   lxm3200_linetoeject = (page_true_height * 1200) / 72;
01790 
01791 
01792   if (!lexmark_init_printer(v, caps, printing_color,
01793                             media_source,
01794                             xdpi, ydpi, page_width, page_height,
01795                             top,left,use_dmt))
01796     return 0;
01797 
01798   /*
01799   * Convert image size to printer resolution...
01800   */
01801 
01802   out_width  = xdpi * out_width / 72;
01803   out_height = ydpi * out_height / 72;
01804 
01805 #ifdef DEBUG
01806 
01807   stp_erprintf("border: left %ld, x_raster_res %d, offser_left %ld\n", left, caps->x_raster_res, caps->offset_left_border);
01808 #endif
01809 
01810   left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
01811 
01812 #ifdef DEBUG
01813   stp_erprintf("border: left %d\n", left);
01814 #endif
01815 
01816 
01817 
01818 #ifdef DEBUG
01819   if (doTestPrint == 1) {
01820     stp_erprintf("Start test print\n");
01821     testprint(&td);
01822     out_width = td.x;
01823     out_height = td.y;
01824     if (td.cols != 7) {
01825     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
01826     } else {
01827     printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
01828     }
01829   }
01830 #endif
01831 
01832  /*
01833   * Allocate memory for the raster data...
01834   */
01835 
01836   length = (out_width + 7) / 8;
01837 
01838 
01839 
01840   if (use_dmt) {
01841     /*    buf_length= length*2; */
01842     buf_length= length;
01843   } else {
01844     buf_length= length;
01845   }
01846 
01847 #ifdef DEBUG
01848   stp_erprintf("lexmark: buflength is %d!\n",buf_length);
01849 #endif
01850 
01851 
01852   /* Now we know the color which are used, let's get the memory for every color image */
01853   cols.p.k = NULL;
01854   cols.p.c = NULL;
01855   cols.p.y = NULL;
01856   cols.p.m = NULL;
01857   cols.p.C = NULL;
01858   cols.p.M = NULL;
01859   cols.p.Y = NULL;
01860 
01861 
01862   if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
01863     cols.p.c = stp_zalloc(buf_length+10);
01864   }
01865   if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
01866     cols.p.y = stp_zalloc(buf_length+10);
01867   }
01868   if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
01869     cols.p.m = stp_zalloc(buf_length+10);
01870   }
01871   if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
01872     cols.p.k = stp_zalloc(buf_length+10);
01873   }
01874   if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
01875     cols.p.C = stp_zalloc(buf_length+10);
01876   }
01877   if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
01878     cols.p.Y = stp_zalloc(buf_length+10);
01879   }
01880   if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
01881     cols.p.M = stp_zalloc(buf_length+10);
01882   }
01883 
01884   if (cols.p.k)
01885     {
01886       if (cols.p.c)
01887         stp_set_string_parameter(v, "STPIOutputType", "KCMY");
01888       else
01889         stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
01890     }
01891   else
01892     stp_set_string_parameter(v, "STPIOutputType", "CMY");
01893 
01894 #ifdef DEBUG
01895   stp_erprintf("lexmark: driver will use colors ");
01896   if (cols.p.c)     stp_erputc('c');
01897   if (cols.p.C)     stp_erputc('C');
01898   if (cols.p.m)     stp_erputc('m');
01899   if (cols.p.M)     stp_erputc('M');
01900   if (cols.p.y)     stp_erputc('y');
01901   if (cols.p.Y)     stp_erputc('Y');
01902   if (cols.p.k)     stp_erputc('k');
01903   stp_erprintf("\n");
01904 #endif
01905 
01906   /* initialize soft weaveing */
01907   privdata.ink_parameter = ink_parameter;
01908   privdata.bidirectional = lexmark_print_bidirectional(model, resolution);
01909   privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
01910   privdata.direction = 0;
01911   stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
01912   /*  lxm_nozzles_used = 1;*/
01913 
01914   stp_initialize_weave(v,
01915                        pass_length, /* jets */
01916                        nozzle_separation, /* separation */
01917                        horizontal_passes, /* h overample */
01918                        res_para_ptr->vertical_passes, /* v passes */
01919                        res_para_ptr->vertical_oversample, /* v oversample */
01920                        ncolors, /* colors */
01921                        1, /* bits/pixel */
01922                        out_width, /* line width */
01923                        out_height,
01924                        ((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
01925                                             /caps->y_raster_res),
01926                        (page_height * ydpi) / 72,
01927                        (const int *) lexmark_head_offset(ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
01928                        STP_WEAVE_ZIGZAG, /* weave_strategy */
01929                        flush_pass,
01930                        stp_fill_uncompressed,  /* fill_start */
01931                        stp_pack_uncompressed,  /* pack */
01932                        stp_compute_uncompressed_linewidth);  /* compute_linewidth */
01933   privdata.last_pass_offset = 0;
01934   privdata.jets = pass_length;
01935   privdata.ncolors = ncolors;
01936   privdata.horizontal_weave = horizontal_passes;
01937 
01938 
01939   if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
01940     {
01941       stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
01942       stp_set_float_parameter(v, "Density", 1.0);
01943     }
01944 
01945 #ifdef DEBUG
01946   stp_erprintf("density is %f\n",stp_get_parameter(v, "Density"));
01947 #endif
01948 
01949 #ifdef DEBUG
01950   stp_erprintf("density is %f and will be changed to %f  (%f)\n",
01951                 stp_get_float_parameter(v, "Density"),
01952                 stp_get_float_parameter(v, "Density") / densityDivisor,
01953                 densityDivisor);
01954 #endif
01955 
01956   /* Lexmark do not have differnet pixel sizes. We have to correct the density according the print resolution. */
01957   stp_scale_float_parameter(v, "Density", 1.0 / densityDivisor);
01958 
01959 
01960   /*
01961    * Compute the LUT.  For now, it's 8 bit, but that may eventually
01962    * sometimes change.
01963    */
01964   if (ncolors > 4)
01965     k_lower = .5;
01966   else
01967     k_lower = .25;
01968 
01969   if (media)
01970     {
01971       stp_scale_float_parameter(v, "Density", media->base_density);
01972       stp_scale_float_parameter(v, "Cyan", media->p_cyan);
01973       stp_scale_float_parameter(v, "Magenta", media->p_magenta);
01974       stp_scale_float_parameter(v, "Yellow", media->p_yellow);
01975       k_lower *= media->k_lower_scale;
01976       k_upper  = media->k_upper;
01977     }
01978   else
01979     {
01980       stp_scale_float_parameter(v, "Density", .8);
01981       k_lower *= .1;
01982       k_upper = .5;
01983     }
01984   if (stp_get_float_parameter(v, "Density") > 1.0)
01985     stp_set_float_parameter(v, "Density", 1.0);
01986 
01987 #ifdef DEBUG
01988   stp_erprintf("density is %f\n",stp_get_float_parameter(v, "Density"));
01989 #endif
01990 
01991 
01992   if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
01993     stp_set_default_float_parameter(v, "GCRLower", k_lower);
01994   if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
01995     stp_set_default_float_parameter(v, "GCRUpper", k_upper);
01996   stp_dither_init(v, image, out_width, xdpi, ydpi);
01997 
01998         /*
01999           stpi_dither_set_black_lower(dither, .8 / ((1 << (use_dmt+1)) - 1));*/
02000   /*stpi_dither_set_black_levels(dither, 0.5, 0.5, 0.5);
02001     stpi_dither_set_black_lower(dither, 0.4);*/
02002   /*
02003     if (use_glossy_film)
02004   */
02005 
02006   if (!use_dmt) {
02007     if (cols.p.C)
02008       {
02009         stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
02010                                   0.31 / .5);
02011       }
02012     if (cols.p.M)
02013       {
02014         stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
02015                                   0.61 / .97);
02016       }
02017     if (cols.p.Y)
02018       {
02019         stp_dither_set_inks_full(v, STP_ECOLOR_Y, 2, photo_dither_shades, 1.0,
02020                                   0.08);
02021       }
02022   }
02023 
02024   stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
02025                                      get_double_param(v, "BlackDensity") *
02026                                      get_double_param(v, "Density"));
02027   stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
02028                                      get_double_param(v, "CyanDensity") *
02029                                      get_double_param(v, "Density"));
02030   stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
02031                                      get_double_param(v, "MagentaDensity") *
02032                                      get_double_param(v, "Density"));
02033   stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
02034                                      get_double_param(v, "YellowDensity") *
02035                                      get_double_param(v, "Density"));
02036   if (!use_dmt) {
02037     if (cols.p.C)
02038       {
02039         stp_channel_set_density_adjustment
02040           (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
02041                             get_double_param(v, "LightCyanTransition") *
02042                             get_double_param(v, "Density")));
02043       }
02044     if (cols.p.M)
02045       {
02046         stp_channel_set_density_adjustment
02047           (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
02048                             get_double_param(v, "LightMagentaTransition") *
02049                             get_double_param(v, "Density")));
02050       }
02051     if (cols.p.Y)
02052       {
02053         stp_channel_set_density_adjustment
02054           (v, STP_ECOLOR_Y, 1, (get_double_param(v, "YellowDensity") *
02055                             get_double_param(v, "LightYellowTransition") *
02056                             get_double_param(v, "Density")));
02057       }
02058   }
02059 
02060   /*
02061    * Output the page...
02062   */
02063 
02064   if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE) &&
02065       media->hue_adjustment)
02066     {
02067       hue_adjustment = stp_read_and_compose_curves
02068         (lexmark_hue_adjustment(caps, v),
02069          media ? media->hue_adjustment : NULL, STP_CURVE_COMPOSE_ADD, 384);
02070       stp_set_curve_parameter(v, "HueMap", hue_adjustment);
02071       stp_curve_destroy(hue_adjustment);
02072     }
02073   if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE) &&
02074       media->lum_adjustment)
02075     {
02076       lum_adjustment = stp_read_and_compose_curves
02077         (lexmark_lum_adjustment(caps, v),
02078          media ? media->lum_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
02079       stp_set_curve_parameter(v, "LumMap", lum_adjustment);
02080       stp_curve_destroy(lum_adjustment);
02081     }
02082   if (!stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_ACTIVE) &&
02083       media->sat_adjustment)
02084     {
02085       sat_adjustment = stp_read_and_compose_curves
02086         (lexmark_sat_adjustment(caps, v),
02087          media ? media->sat_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
02088       stp_set_curve_parameter(v, "SatMap", sat_adjustment);
02089       stp_curve_destroy(sat_adjustment);
02090     }
02091 
02092   out_channels = stp_color_init(v, image, 65536);
02093 
02094   /* calculate the memory we need for one line of the printer image (hopefully we are right) */
02095 #ifdef DEBUG
02096   stp_erprintf("---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
02097 #endif
02098 
02099   errdiv  = image_height / out_height;
02100   errmod  = image_height % out_height;
02101   errval  = 0;
02102   errlast = -1;
02103   errline  = 0;
02104 
02105   if (cols.p.k)
02106     stp_dither_add_channel(v, cols.p.k, STP_ECOLOR_K, 0);
02107   if (cols.p.c)
02108     stp_dither_add_channel(v, cols.p.c, STP_ECOLOR_C, 0);
02109   if (cols.p.C)
02110     stp_dither_add_channel(v, cols.p.C, STP_ECOLOR_C, 1);
02111   if (cols.p.m)
02112     stp_dither_add_channel(v, cols.p.m, STP_ECOLOR_M, 0);
02113   if (cols.p.M)
02114     stp_dither_add_channel(v, cols.p.M, STP_ECOLOR_M, 1);
02115   if (cols.p.y)
02116     stp_dither_add_channel(v, cols.p.y, STP_ECOLOR_Y, 0);
02117   if (cols.p.Y)
02118     stp_dither_add_channel(v, cols.p.Y, STP_ECOLOR_Y, 1);
02119   privdata.hoffset = left;
02120   privdata.ydpi = ydpi;
02121   privdata.model = model;
02122   privdata.width = out_width;
02123   privdata.xdpi = xdpi;
02124   privdata.physical_xdpi = physical_xdpi;
02125 
02126   for (y = 0; y < out_height; y ++)
02127     {
02128       int duplicate_line = 1;
02129 
02130       if (errline != errlast)
02131         {
02132           errlast = errline;
02133           duplicate_line = 0;
02134           if (stp_color_get_row(v, image, errline, &zero_mask))
02135             {
02136               status = 2;
02137               break;
02138             }
02139         }
02140       stp_dither(v, y, duplicate_line, zero_mask, NULL);
02141       stp_write_weave(v, (unsigned char **)cols.v);
02142 
02143       errval += errmod;
02144       errline += errdiv;
02145       if (errval >= out_height)
02146         {
02147           errval -= out_height;
02148           errline ++;
02149         }
02150     }
02151   stp_image_conclude(image);
02152 
02153   stp_flush_all(v);
02154 
02155   lexmark_deinit_printer(v, caps);
02156 
02157   /*
02158   * Cleanup...
02159   */
02160   if (privdata.outbuf != NULL) {
02161     stp_free(privdata.outbuf);/* !!!!!!!!!!!!!! */
02162   }
02163 
02164   for (i = 0; i < NCHANNELS; i++)
02165     if (cols.v[i])
02166       stp_free(cols.v[i]);
02167 
02168 #ifdef DEBUG
02169   lex_tmp_file_deinit(dbgfileprn);
02170 #endif
02171 
02172   return status;
02173 }
02174 
02175 static int
02176 lexmark_print(const stp_vars_t *v, stp_image_t *image)
02177 {
02178   int status;
02179   stp_vars_t *nv = stp_vars_create_copy(v);
02180   stp_prune_inactive_options(nv);
02181   status = lexmark_do_print(nv, image);
02182   stp_vars_destroy(nv);
02183   return status;
02184 }
02185 
02186 static const stp_printfuncs_t print_lexmark_printfuncs =
02187 {
02188   lexmark_list_parameters,
02189   lexmark_parameters,
02190   stp_default_media_size,
02191   lexmark_imageable_area,
02192   lexmark_limit,
02193   lexmark_print,
02194   lexmark_describe_resolution,
02195   lexmark_describe_output,
02196   stp_verify_printer_params,
02197   NULL,
02198   NULL
02199 };
02200 
02201 
02202 
02203 /* lexmark_init_line
02204    This method is printer type dependent code.
02205 
02206    This method initializes the line to be printed. It will set
02207    the printer specific initialization which has to be done bofor
02208    the pixels of the image could be printed.
02209 */
02210 static unsigned char *
02211 lexmark_init_line(int mode, unsigned char *prnBuf,
02212                   int pass_length,
02213                   int offset,    /* offset from left in 1/"x_raster_res" DIP (printer resolution)*/
02214                   int width, int direction,
02215                   const lexmark_inkparam_t *ink_parameter,
02216                   const lexmark_cap_t *   caps          /* I - Printer model */
02217                   )
02218 {
02219   int pos1 = 0;
02220   int pos2 = 0;
02221   int abspos, disp;
02222   int hend = 0;
02223   int header_size = 0;
02224 
02225 
02226   /*  stp_erprintf("#### width %d, length %d, pass_length %d\n", width, length, pass_length);*/
02227   /* first, we wirte the line header */
02228   switch(caps->model)  {
02229   case m_z52:
02230   case m_z42:
02231     if (caps->model == m_z52)
02232       {
02233         header_size = LXM_Z52_HEADERSIZE;
02234         memcpy(prnBuf, outbufHeader_z52, header_size);
02235       }
02236     if (caps->model == m_z42)
02237       {
02238         header_size = LXM_Z42_HEADERSIZE;
02239         memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
02240       }
02241 
02242     /* K could only be present if black is printed only. */
02243     if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
02244 #ifdef DEBUG
02245       stp_erprintf("set  photo/black catridge \n");
02246 #endif
02247       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
02248 
02249       if (direction) {
02250       } else {
02251         offset += ink_parameter->h_direction_offset;
02252       }
02253     } else {
02254 #ifdef DEBUG
02255       stp_erprintf("set color cartridge \n");
02256 #endif
02257       prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
02258 
02259       if (direction) {
02260         offset += ink_parameter->h_catridge_offset;
02261       } else {
02262         offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
02263       }
02264     }
02265 
02266     switch (mode & PRINT_MODE_MASK) {
02267     case PRINT_MODE_300:
02268       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
02269       break;
02270     case PRINT_MODE_600:
02271       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
02272       break;
02273     case PRINT_MODE_1200:
02274       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
02275       break;
02276     case PRINT_MODE_2400:
02277       prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
02278       break;
02279     }
02280 
02281 
02282     if (direction) {
02283       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
02284     } else {
02285       prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
02286     }
02287 
02288     /* set package count */
02289     prnBuf[13] = (unsigned char)((width) >> 8);
02290     prnBuf[14] = (unsigned char)((width) & 0xFF);
02291     /* set horizontal offset */
02292     prnBuf[15] =(unsigned char)(offset >> 8);
02293     prnBuf[16] =(unsigned char)(offset & 0xFF);
02294 
02295     if (caps->model == m_z42) {
02296         switch(mode & PRINT_MODE_MASK) {
02297         case PRINT_MODE_300:
02298                 hend = (width-1)*(2400/300);
02299                 break;
02300         case PRINT_MODE_600:
02301                 hend = (width-1)*(2400/600);
02302                 break;
02303         case PRINT_MODE_1200:
02304                 hend = (width-1)*(2400/1200);
02305                 break;
02306         case PRINT_MODE_2400:
02307                 hend = (width-1)*(2400/2400);
02308                 break;
02309         }
02310         hend += offset;
02311         prnBuf[17] = (unsigned char)(hend >> 8);
02312         prnBuf[18] = (unsigned char)(hend & 0xFF);
02313 
02314         prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
02315     }
02316 
02317     return prnBuf + header_size;  /* return the position where the pixels have to be written */
02318     break;
02319     case m_3200:
02320       memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
02321 
02322       offset = (offset - 60) * 4;
02323 
02324       /* K could only be present if black is printed only. */
02325       if((mode & COLOR_MODE_K) ||
02326          (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
02327         {
02328           disp = LXM3200_LEFTOFFS;
02329           prnBuf[2] = 0x00;
02330         }
02331       else
02332         {
02333           disp = LXM3200_RIGHTOFFS;
02334           prnBuf[2] = 0x80;
02335         }
02336 
02337       if(pass_length == 208)
02338         {
02339           prnBuf[2] |= 0x10;
02340         }
02341 
02342       switch(mode & PRINT_MODE_MASK)    {
02343         case PRINT_MODE_300:
02344           prnBuf[2] |= 0x20;
02345           pos1 = offset + disp;
02346           pos2 = offset + (width * 4) + disp;
02347           break;
02348 
02349         case PRINT_MODE_600:
02350           prnBuf[2] |= 0x00;
02351           pos1 = offset + disp;
02352           pos2 = offset + (width * 2) + disp;
02353           break;
02354 
02355         case PRINT_MODE_1200:
02356           prnBuf[2] |= 0x40;
02357           pos1 = offset + disp;
02358           pos2 = (offset + width) + disp;
02359           break;
02360         }
02361 
02362       if(direction)
02363         prnBuf[2] |= 0x01;
02364       else
02365         prnBuf[2] |= 0x00;
02366 
02367       /* set package count */
02368       prnBuf[3] = (unsigned char)((width) >> 8);
02369       prnBuf[4] = (unsigned char)((width) & 0xff);
02370 
02371       /* set horizontal offset */
02372       prnBuf[21] = (unsigned char)(pos1 >> 8);
02373       prnBuf[22] = (unsigned char)(pos1 & 0xFF);
02374 
02375       abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
02376       prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
02377       prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
02378 
02379       lxm3200_headpos = abspos;
02380 
02381       if(LXM3200_RIGHTOFFS > 4816)
02382         abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
02383       else
02384         abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
02385 
02386       prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
02387       prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
02388 
02389       lxm3200_headpos = abspos;
02390 
02391       prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
02392       prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
02393       prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
02394 
02395       /* return the position where the pixels have to be written */
02396       return prnBuf + LXM_3200_HEADERSIZE;
02397       break;
02398 
02399   case m_lex7500:
02400     stp_erprintf("Lexmark 7500 not supported !\n");
02401     return NULL;
02402     break;
02403   }
02404   return NULL;
02405 }
02406 
02407 
02408 typedef struct Lexmark_head_colors {
02409   int v_start;
02410   unsigned char *line;
02411   int head_nozzle_start;
02412   int head_nozzle_end;
02413   int used_jets;
02414 } Lexmark_head_colors;
02415 
02416 /* lexmark_write
02417    This method is has NO printer type dependent code.
02418    This method writes a single line of the print. The line consits of "pass_length"
02419    pixel lines (pixels, which could be printed with one pass by the printer.
02420 */
02421 
02422 
02423 static int
02424 lexmark_write(const stp_vars_t *v,              /* I - Print file or command */
02425               unsigned char *prnBuf,      /* mem block to buffer output */
02426               int *paperShift,
02427               int direction,
02428               int pass_length,       /* num of inks to print */
02429               const lexmark_cap_t *   caps,             /* I - Printer model */
02430               const lexmark_inkparam_t *ink_parameter,
02431               int xdpi,
02432               int yCount,
02433               Lexmark_head_colors *head_colors,
02434               int           length,     /* I - Length of bitmap data in bytes */
02435               int           mode,       /* I - Which color */
02436               int           ydpi,               /* I - Vertical resolution */
02437               int           width,      /* I - Printed width in pixles */
02438               int           offset,     /* I - Offset from left side in lexmark_cap_t.x_raster_res DPI */
02439               int           dmt)
02440 {
02441   unsigned char *tbits=NULL, *p=NULL;
02442   int clen;
02443   int x;  /* actual vertical position */
02444   int y;  /* actual horizontal position */
02445   int dy; /* horiz. inkjet posintion */
02446   int x1;
02447   unsigned short pixelline;  /* byte to be written */
02448   unsigned int valid_bytes; /* bit list which tells the present bytes */
02449   int xStart=0; /* count start for horizontal line */
02450   int xEnd=0;
02451   int xIter=0;  /* count direction for horizontal line */
02452   int anyCol=0;
02453   int colIndex;
02454   int rwidth; /* real with used at printing (includes shift between even & odd nozzles) */
02455 #ifdef DEBUG
02456   /* stp_erprintf("<%c>",("CMYKcmy"[coloridx])); */
02457   stp_erprintf("pass length %d\n", pass_length);
02458 #endif
02459 
02460 
02461   /* first, we check the length of the line an cut it if necessary. */
02462   if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
02463     /* line too long !! Cut the line */
02464 #ifdef DEBUG
02465    stp_erprintf("!! Line too long !! reduce it from %d", width);
02466 #endif
02467     width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
02468 #ifdef DEBUG
02469    stp_erprintf(" down to %d\n", width);
02470 #endif
02471   }
02472 
02473 
02474   /* we have to write the initial sequence for a line */
02475 
02476 #ifdef DEBUG
02477   stp_erprintf("lexmark: printer line initialized.\n");
02478 #endif
02479 
02480   if (direction) {
02481     /* left to right */
02482     xStart = -get_lr_shift(mode);
02483     xEnd = width-1;
02484     xIter = 1;
02485     rwidth = xEnd - xStart;
02486   } else {
02487     /* right to left ! */
02488     xStart = width-1;
02489     xEnd = -get_lr_shift(mode);
02490     rwidth = xStart - xEnd;
02491     xIter = -1;
02492   }
02493 
02494   p = lexmark_init_line(mode, prnBuf, pass_length, offset, rwidth,
02495                         direction,  /* direction */
02496                         ink_parameter, caps);
02497 
02498 
02499 #ifdef DEBUG
02500   stp_erprintf("lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
02501 #endif
02502 
02503   /* now we can start to write the pixels */
02504   yCount = 2;
02505 
02506 
02507   for (x=xStart; x != xEnd; x+=xIter) {
02508     int  anyDots=0; /* tells us if there was any dot to print */
02509 
02510        switch(caps->model)      {
02511         case m_z52:
02512           tbits = p;
02513           *(p++) = 0x3F;
02514           tbits[1] = 0; /* here will be nice bitmap */
02515           p++;
02516           break;
02517 
02518         case m_3200:
02519         case m_z42:
02520           tbits = p;
02521           p += 4;
02522           break;
02523 
02524         case m_lex7500:
02525           break;
02526         }
02527 
02528 
02529     pixelline =0;     /* here we store 16 pixels */
02530     valid_bytes = 0;  /* for every valid word (16 bits) a corresponding bit will be set to 1. */
02531 
02532     anyDots =0;
02533     x1 = x+get_lr_shift(mode);
02534 
02535     for (colIndex=0; colIndex < 3; colIndex++) {
02536       for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
02537            (dy < head_colors[colIndex].head_nozzle_end);
02538            y+=yCount, dy++) { /* we start counting with 1 !!!! */
02539         if (head_colors[colIndex].line != NULL) {
02540           pixelline = pixelline << 1;
02541           if ((x >= 0) &&
02542               ((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
02543             pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
02544           pixelline = pixelline << 1;
02545           if ((x1 < width) &&
02546               (((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
02547             pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
02548 
02549         } else {
02550           pixelline = pixelline << 2;
02551         }
02552         switch(caps->model)             {
02553         case m_z52:
02554           if ((dy%8) == 7) {
02555             /* we have two bytes, write them */
02556             anyDots |= pixelline;
02557             if (pixelline) {
02558               /* we have some dots */
02559               valid_bytes = valid_bytes >> 1;
02560               *((p++)) = (unsigned char)(pixelline >> 8);
02561               *((p++)) = (unsigned char)(pixelline & 0xff);
02562             } else {
02563               /* there are no dots ! */
02564               valid_bytes = valid_bytes >> 1;
02565               valid_bytes |= 0x1000;
02566             }
02567             pixelline =0;
02568           }
02569           break;
02570 
02571         case m_3200:
02572         case m_z42:
02573           if((dy % 4) == 3)
02574             {
02575               anyDots |= pixelline;
02576               valid_bytes <<= 1;
02577 
02578               if(pixelline)
02579                 *(p++) = (unsigned char)(pixelline & 0xff);
02580               else
02581                 valid_bytes |= 0x01;
02582 
02583               pixelline = 0;
02584             }
02585           break;
02586 
02587         case m_lex7500:
02588           break;
02589         }
02590       }
02591     }
02592 
02593     switch(caps->model) {
02594     case m_z52:
02595       if (pass_length != 208) {
02596         valid_bytes = valid_bytes >> 1;
02597         valid_bytes |= 0x1000;
02598       }
02599       tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
02600       tbits[1] = (unsigned char)(valid_bytes & 0xff);
02601       break;
02602 
02603     case m_z42:
02604       if ((p-tbits) & 1) *(p++)=0; /* z42 packets always have even length */
02605       /* fall through */
02606     case m_3200:
02607       tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
02608       tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
02609       tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
02610       tbits[3] = (unsigned char)(valid_bytes & 0xff);
02611       break;
02612 
02613     case m_lex7500:
02614       break;
02615     }
02616 
02617 
02618     if (anyDots) {
02619       anyCol = 1;
02620     } else {
02621       /* there are no dots, make empy package */
02622 #ifdef DEBUG
02623       /*     stp_erprintf("-- empty col %i\n", x); */
02624 #endif
02625     }
02626   }
02627 
02628 #ifdef DEBUG
02629   stp_erprintf("lexmark: 4\n");
02630 #endif
02631 
02632   clen=((unsigned char *)p)-prnBuf;
02633 
02634   switch(caps->model)    {
02635     case m_z52:
02636     case m_z42:
02637   prnBuf[IDX_SEQLEN]  =(unsigned char)(clen >> 24);
02638   prnBuf[IDX_SEQLEN+1]  =(unsigned char)(clen >> 16);
02639   prnBuf[IDX_SEQLEN+2]  =(unsigned char)(clen >> 8);
02640   prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
02641   break;
02642 
02643   case m_3200:
02644     prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
02645     prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
02646     prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
02647     prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
02648     break;
02649 
02650   default:
02651     break;
02652   }
02653 
02654   if (anyCol) {
02655     /* fist, move the paper */
02656     paper_shift(v, (*paperShift), caps);
02657     *paperShift=0;
02658 
02659     /* now we write the image line */
02660     stp_zfwrite((const char *)prnBuf,1,clen,v);
02661 #ifdef DEBUG
02662     lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
02663     stp_erprintf("lexmark: line written.\n");
02664 #endif
02665     return 1;
02666   } else {
02667 #ifdef DEBUG
02668     stp_erprintf("-- empty line\n");
02669 #endif
02670     return 0;
02671   }
02672 
02673   /* Send a line of raster graphics... */
02674 
02675   return 0;
02676 }
02677 
02678 
02679 
02680 #ifdef DEBUG
02681 const stp_vars_t *lex_open_tmp_file() {
02682   int i;
02683   const stp_vars_t *ofile;
02684   char tmpstr[256];
02685 
02686       stp_erprintf(" create file !\n");
02687   for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
02688        ofile != NULL;
02689        i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
02690     if (ofile != NULL)
02691       {
02692         fclose(ofile);
02693       }
02694   }
02695       stp_erprintf("Create file %s !\n", tmpstr);
02696   ofile = fopen(tmpstr, "wb");
02697   if (ofile == NULL)
02698     {
02699       stp_erprintf("Can't create file !\n");
02700       stp_abort();
02701     }
02702   return ofile;
02703 }
02704 
02705 void lex_tmp_file_deinit(const stp_vars_t *file) {
02706   stp_erprintf("Close file %lx\n", file);
02707   fclose(file);
02708 }
02709 
02710 const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length) {
02711   fwrite(data, 1, length, ofile);
02712 }
02713 
02714 
02715 #endif
02716 
02717 
02718 static void
02719 flush_pass(stp_vars_t *v, int passno, int vertical_subpass)
02720 {
02721   stp_lineoff_t        *lineoffs   = stp_get_lineoffsets_by_pass(v, passno);
02722   stp_lineactive_t     *lineactive = stp_get_lineactive_by_pass(v, passno);
02723   const stp_linebufs_t *bufs       = stp_get_linebases_by_pass(v, passno);
02724   stp_pass_t           *pass       = stp_get_pass_by_pass(v, passno);
02725   stp_linecount_t      *linecount  = stp_get_linecount_by_pass(v, passno);
02726   lexm_privdata_weave *pd =
02727     (lexm_privdata_weave *) stp_get_component_data(v, "Driver");
02728   int width = pd->width;
02729   int hoffset = pd->hoffset;
02730   int model = pd->model;
02731   int xdpi = pd->xdpi;
02732   int ydpi = pd->ydpi;
02733   int physical_xdpi = pd->physical_xdpi;
02734   int lwidth = (width + (pd->horizontal_weave - 1)) / pd->horizontal_weave;
02735   int microoffset = vertical_subpass & (pd->horizontal_weave - 1);
02736 
02737   int prn_mode;
02738   int j; /* color counter */
02739   const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
02740   int paperShift;
02741   Lexmark_head_colors head_colors[3]={{0, NULL,     0,  64/2, 64},
02742                                       {0, NULL,  64/2, 128/2, 64},
02743                                       {0, NULL, 128/2, 192/2, 64}};
02744 
02745 
02746 #ifdef DEBUG
02747   stp_erprintf("Lexmark: flush_pass, here we are !\n");
02748   stp_erprintf("  passno %i, pd->ncolors %i, width %d, lwidth %d, linecount k % d, linecount m % d, bitwidth %d\n",
02749                passno, pd->ncolors, width, lwidth, /*linecount[0].p.k, linecount[0].p.m,*/ pd->bitwidth);
02750   stp_erprintf("microoffset %d, vertical_subpass %d, pd->horizontal_weave %d\n", microoffset,vertical_subpass, pd->horizontal_weave);
02751 
02752   stp_erprintf("Lexmark: last_pass_offset %d, logicalpassstart %d\n", pd->last_pass_offset, pass->logicalpassstart);
02753   stp_erprintf("Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d,  \n", caps->y_raster_res, ydpi);
02754 
02755 #endif
02756 
02757   if (1) { /* wisi */
02758 
02759 #ifdef DEBUG
02760   stp_erprintf("1\n");
02761   stp_erprintf("\n");
02762   stp_erprintf("lineoffs[0].v[j]  %d\n", lineoffs[0].v[0]);
02763   stp_erprintf("lineoffs[0].v[j]  %d\n", lineoffs[0].v[1]);
02764 
02765 #endif
02766 
02767   switch (physical_xdpi) {
02768   case 300:
02769     prn_mode = PRINT_MODE_300;
02770     break;
02771   case 600:
02772     prn_mode = PRINT_MODE_600;
02773     break;
02774   case 1200:
02775     prn_mode = PRINT_MODE_1200;
02776     break;
02777   default:
02778 #ifdef DEBUG
02779     stp_erprintf("Eror: Unsupported phys resolution (%d)\n", physical_xdpi);
02780 #endif
02781     return;
02782     break;
02783   }
02784   /* calculate paper shift and adapt actual resoution to physical positioning resolution */
02785   paperShift = (pass->logicalpassstart - pd->last_pass_offset) * (caps->y_raster_res/ydpi);
02786 
02787 
02788       /*** do we have to print something with the color cartridge ? ***/
02789       if ((STP_ECOLOR_C < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_C] > 0))
02790         {
02791           head_colors[0].line = bufs[0].v[STP_ECOLOR_C];
02792           head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_C];
02793         }
02794       else
02795         {
02796           head_colors[0].line = NULL;
02797           head_colors[0].used_jets = 0;
02798         }
02799 
02800       if ((STP_ECOLOR_M < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_M] > 0))
02801         {
02802           head_colors[1].line = bufs[0].v[STP_ECOLOR_M];
02803           head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_M];
02804         }
02805       else
02806         {
02807           head_colors[1].line = 0;
02808           head_colors[1].used_jets = 0;
02809         }
02810 
02811       if ((STP_ECOLOR_Y < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_Y] > 0))
02812         {
02813           head_colors[2].line = bufs[0].v[STP_ECOLOR_Y];
02814           head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_Y];
02815         }
02816       else
02817         {
02818           head_colors[2].line = 0;
02819           head_colors[2].used_jets = 0;
02820         }
02821 
02822       if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
02823 
02824 
02825 
02826 #ifdef DEBUG
02827         stp_erprintf("lexmark_write: lwidth %d\n", lwidth);
02828 #endif
02829         lexmark_write(v,                /* I - Print file or command */
02830                       pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
02831                       &paperShift,           /* int *paperShift, */
02832                       pd->direction,                     /* int direction, */
02833                       pd->jets,       /* num of inks to print */
02834                       caps,                  /* const lexmark_cap_t *   caps,       I - Printer model */
02835                       pd->ink_parameter,
02836                       xdpi,                  /* int xresolution, */
02837                       2,                     /* yCount,*/
02838                       head_colors,           /* Lexmark_head_colors *head_colors, */
02839                       (lwidth+7)/8, /* length,   I - Length of bitmap data of one line in bytes */
02840                       prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M,       /* mode,      I - Which color */
02841                       ydpi,                  /* ydpi,    I - Vertical resolution */
02842                       lwidth,      /* width,     I - Printed width in pixles*/
02843                       hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
02844                       0                      /* dmt */);
02845         if (pd->bidirectional)
02846           pd->direction = (pd->direction +1) & 1;
02847       }
02848 
02849 
02850       /*** do we have to print somthing with black or photo cartridge ? ***/
02851       /* we print with the photo or black cartidge */
02852 
02853     if (pd->jets != 208)
02854       {
02855         /* we have photo or black cartridge */
02856         if ((STP_ECOLOR_LC < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LC] > 0))
02857           {
02858             head_colors[0].line = bufs[0].v[STP_ECOLOR_LC];
02859             head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_LC];
02860           }
02861         else
02862           {
02863             head_colors[0].line = 0;
02864             head_colors[0].used_jets = 0;
02865           }
02866 
02867             if ((STP_ECOLOR_LM < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LM] > 0))
02868           {
02869             head_colors[1].line = bufs[0].v[STP_ECOLOR_LM];
02870             head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_LM];
02871           }
02872         else
02873           {
02874             head_colors[1].line = 0;
02875             head_colors[1].used_jets = 0;
02876           }
02877 
02878             if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
02879           {
02880             head_colors[2].line = bufs[0].v[STP_ECOLOR_K];
02881             head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_K];
02882           }
02883         else
02884           {
02885             head_colors[2].line = 0;
02886             head_colors[2].used_jets = 0;
02887           }
02888       }
02889     else
02890       {
02891         if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
02892           {
02893             /* we have black cartridge; we have to print with all 208 jets at once */
02894             head_colors[0].line = bufs[0].v[STP_ECOLOR_K];
02895             head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_K];
02896             head_colors[0].head_nozzle_start = 0;
02897             head_colors[0].head_nozzle_end = pd->jets/2;
02898             head_colors[2].line = NULL;
02899             head_colors[2].used_jets = 0;
02900             head_colors[2].head_nozzle_start = 0;
02901             head_colors[2].head_nozzle_end = 0;
02902             head_colors[1].line = NULL;
02903             head_colors[1].used_jets = 0;
02904             head_colors[1].head_nozzle_start = 0;
02905             head_colors[1].head_nozzle_end = 0;
02906           }
02907         else
02908           {
02909             head_colors[2].line = NULL;
02910             head_colors[2].used_jets = 0;
02911             head_colors[2].head_nozzle_start = 0;
02912             head_colors[2].head_nozzle_end = 0;
02913             head_colors[1].line = NULL;
02914             head_colors[1].used_jets = 0;
02915             head_colors[1].head_nozzle_start = 0;
02916             head_colors[1].head_nozzle_end = 0;
02917             head_colors[0].line = NULL;
02918             head_colors[0].used_jets = 0;
02919             head_colors[0].head_nozzle_start = 0;
02920             head_colors[0].head_nozzle_end = 0;
02921           }
02922       }
02923 
02924      if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
02925 
02926     lexmark_write(v,            /* I - Print file or command */
02927                   pd->outbuf,/*unsigned char *prnBuf,   mem block to buffer output */
02928                   &paperShift,           /* int *paperShift, */
02929                   pd->direction,             /* int direction, */
02930                   pd->jets,              /* num of inks to print */
02931                   caps,                  /* const lexmark_cap_t *   caps,     I - Printer model */
02932                   pd->ink_parameter,
02933                   xdpi,                  /* int xresolution, */
02934                   2,                     /* yCount,*/
02935                   head_colors,           /* Lexmark_head_colors *head_colors, */
02936                   (lwidth+7)/8, /* length,       I - Length of bitmap data of one line in bytes */
02937                   prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K,       /* mode,        I - Which color */
02938                   ydpi,                  /* ydpi,        I - Vertical resolution */
02939                   lwidth,      /* width,         I - Printed width in pixles*/
02940                   hoffset+microoffset,   /* offset  I - Offset from left side in x_raster_res DPI */
02941                   0                      /* dmt */);
02942     if (pd->bidirectional)
02943       {
02944         pd->direction = (pd->direction +1) & 1;
02945       }
02946     }
02947   /* store paper position in respect if there was a paper shift */
02948   pd->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
02949   }
02950 
02951   for (j = 0; j < pd->ncolors; j++)
02952     {
02953       lineoffs[0].v[j]  = 0;
02954       linecount[0].v[j] = 0;
02955     }
02956 
02957 #ifdef DEBUG
02958   stp_erprintf("lexmark_write finished\n");
02959 #endif
02960 
02961 }
02962 
02963 
02964 
02965 
02966 
02967 #ifdef DEBUG
02968 
02969 static void testprint(testdata *td)
02970 {
02971   int icol, i;
02972   char dummy1[256], dummy2[256];
02973   lexmark_linebufs_t linebufs;
02974 
02975   /* init */
02976   for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
02977     linebufs.v[i] = NULL;
02978   }
02979 
02980   /*let's go */
02981   td->ifile = fopen("/t1.ppm", "rb");
02982   if (td->ifile != NULL) {
02983     /* find "{" */
02984     fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
02985     td->cols -= 1; /* we reduce it by one because fist color will be ignored */
02986     td->input_line = (char *)stp_malloc(td->x+10);
02987     stp_erprintf("<%s> <%s>\n", dummy1, dummy2);
02988     stp_erprintf("%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
02989     if (td->cols > 16) {
02990       stp_erprintf("too many colors !!\n");
02991       return;
02992     }
02993 
02994     /* read the colors */
02995     fscanf(td->ifile, "%[^\"]\"%c       c %[^\"]\",", dummy1, dummy2, dummy2); /* jump over first color */
02996     for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
02997       fscanf(td->ifile, "%[^\"]\"%c     c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
02998       stp_erprintf("colchar %d <%c>\n", i, td->colchar[icol]);
02999     }
03000 
03001 
03002     if (td->cols > 5) {
03003       td->cols = 7;
03004       for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
03005         linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
03006       }
03007     } else if (td->cols > 4) {
03008       td->cols = 5;
03009       for (icol=0; icol < td->cols; icol++) {  /* we ignor the first color. It is "no dot". */
03010         linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
03011       }
03012     } else {
03013       td->cols = 1;
03014       linebufs.v[0] = (char *)stp_malloc((td->x+7)/8); /* allocate the color */
03015     }
03016   } else {
03017     stp_erprintf("can't open file !\n");
03018   }
03019 }
03020 
03021 
03022 static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
03023 {
03024   char dummy1[256];
03025   int icol, ix;
03026 
03027   stp_erprintf("start readtestprintline\n");
03028   for (icol=0; icol < 7; icol++) {
03029     if (linebufs->v[icol] != NULL) {
03030       memset(linebufs->v[icol], 0, (td->x+7)/8);  /* clean line */
03031     }
03032   }
03033   stp_erprintf("1 readtestprintline cols %d\n", td->cols);
03034 
03035 
03036   fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
03037   for (icol=0; icol < td->cols; icol++) {
03038    for (ix=0; ix < td->x; ix++) {
03039       if (td->input_line[ix] == td->colchar[icol]) {
03040         /* set the dot */
03041         if (icol != 0) {
03042           linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
03043         } else {
03044           /* this is specific, we set ymc */
03045           linebufs->p.y[ix/8] |= 1 << (ix%8);
03046           linebufs->p.m[ix/8] |= 1 << (ix%8);
03047           linebufs->p.c[ix/8] |= 1 << (ix%8);
03048         }
03049       }
03050     }
03051   }
03052   /* stp_erprintf("pixchar  <%s><%s>\n",dummy1, td->input_line);*/
03053 }
03054 
03055 #endif
03056 
03057 
03058 static stp_family_t print_lexmark_module_data =
03059   {
03060     &print_lexmark_printfuncs,
03061     NULL
03062   };
03063 
03064 static int
03065 print_lexmark_module_init(void)
03066 {
03067   return stp_family_register(print_lexmark_module_data.printer_list);
03068 }
03069 
03070 
03071 static int
03072 print_lexmark_module_exit(void)
03073 {
03074   return stp_family_unregister(print_lexmark_module_data.printer_list);
03075 }
03076 
03077 
03078 /* Module header */
03079 #define stp_module_version print_lexmark_LTX_stp_module_version
03080 #define stp_module_data print_lexmark_LTX_stp_module_data
03081 
03082 stp_module_version_t stp_module_version = {0, 0};
03083 
03084 stp_module_t stp_module_data =
03085   {
03086     "lexmark",
03087     VERSION,
03088     "Lexmark family driver",
03089     STP_MODULE_CLASS_FAMILY,
03090     NULL,
03091     print_lexmark_module_init,
03092     print_lexmark_module_exit,
03093     (void *) &print_lexmark_module_data
03094   };
03095 

Generated on Wed Aug 25 07:56:14 2004 for libgimpprint API Reference by doxygen 1.3.6