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

print-lexmark.c

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

Generated on Thu Feb 10 19:29:30 2005 for libgutenprint API Reference by  doxygen 1.4.1