#define USEEPSEWAVE 1
#ifdef __GNUC__
#define inline __inline__
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gimp-print/gimp-print.h>
#include <gimp-print/gimp-print-intl-internal.h>
#include "gimp-print-internal.h"
#include <string.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#define STP_ECOLOR_LC 4
#define STP_ECOLOR_LM 5
#define STP_ECOLOR_LY 6
#define false 0
#define true 1
#define max(a, b) ((a > b) ? (a) : (b))
#define INCH(x) (72 * x)
static const stp_dotsize_t single_dotsize[] =
{
{ 0x1, 1.0 }
};
static const stp_shade_t photo_dither_shades[] =
{
{ 1.0000, 1, single_dotsize },
{ 0.3333, 1, single_dotsize },
};
typedef enum Lex_model { m_lex7500, m_z52=10052, m_z42=10042, m_3200=3200 } Lex_model;
#define NCHANNELS (7)
typedef union {
unsigned long v[NCHANNELS];
struct {
unsigned long k;
unsigned long c;
unsigned long m;
unsigned long y;
unsigned long C;
unsigned long M;
unsigned long Y;
} p;
} lexmark_lineoff_t;
typedef union {
unsigned char *v[NCHANNELS];
struct {
unsigned char *k;
unsigned char *c;
unsigned char *m;
unsigned char *y;
unsigned char *C;
unsigned char *M;
unsigned char *Y;
} p;
} lexmark_linebufs_t;
#ifdef DEBUG
typedef struct testdata {
FILE *ifile;
int x, y, cols, deep;
char colchar[16];
char *input_line;
} testdata;
const stp_vars_t **dbgfileprn;
int lex_show_lcount, lex_show_length;
const stp_vars_t *lex_open_tmp_file();
const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length);
static void testprint(testdata *td);
static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs);
#endif
static void
flush_pass(stp_vars_t *v, int passno, int vertical_subpass);
#define DPI300 0
#define DPI600 1
#define DPI1200 2
#define DPI2400 3
#define DPItest 4
#define V_NOZZLE_MASK 0x3
#define H_NOZZLE_MASK 0xc
#define NOZZLE_MASK 0xf
#define PRINT_MODE_300 0x100
#define PRINT_MODE_600 0x200
#define PRINT_MODE_1200 0x300
#define PRINT_MODE_2400 0x400
#define COLOR_MODE_K 0x1000
#define COLOR_MODE_C 0x2000
#define COLOR_MODE_Y 0x4000
#define COLOR_MODE_M 0x8000
#define COLOR_MODE_LC 0x10000
#define COLOR_MODE_LY 0x20000
#define COLOR_MODE_LM 0x40000
#define COLOR_MODE_CMYK (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y | COLOR_MODE_K)
#define COLOR_MODE_CMY (COLOR_MODE_C | COLOR_MODE_M | COLOR_MODE_Y)
#define COLOR_MODE_CcMcYK (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y | COLOR_MODE_K)
#define COLOR_MODE_CcMcY (COLOR_MODE_C | COLOR_MODE_LC | COLOR_MODE_M | COLOR_MODE_LM | COLOR_MODE_Y)
#define COLOR_MODE_MASK 0x7f000
#define PRINT_MODE_MASK 0xf00
#define COLOR_MODE_PHOTO (COLOR_MODE_LC | COLOR_MODE_LM)
#define BWR 0
#define BWL 1
#define CR 2
#define CL 3
static const char standard_sat_adjustment[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<gimp-print>\n"
"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
"<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
"1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "
"1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "
"1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 "
"0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 "
"1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "
"1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "
"</sequence>\n"
"</curve>\n"
"</gimp-print>\n";
static const char standard_lum_adjustment[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<gimp-print>\n"
"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
"<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
"0.50 0.52 0.56 0.60 0.66 0.71 0.74 0.77 "
"0.81 0.79 0.74 0.68 0.70 0.74 0.77 0.82 "
"0.88 0.93 0.95 0.97 0.97 0.96 0.95 0.95 "
"0.95 0.96 0.97 0.98 0.99 1.00 1.00 1.00 "
"1.00 0.97 0.94 0.92 0.90 0.88 0.85 0.79 "
"0.69 0.64 0.58 0.54 0.54 0.54 0.53 0.51 "
"</sequence>\n"
"</curve>\n"
"</gimp-print>\n";
static const char standard_hue_adjustment[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<gimp-print>\n"
"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
"<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
"0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 "
"-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 "
"-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 "
"-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 "
"0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 "
"-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 "
"</sequence>\n"
"</curve>\n"
"</gimp-print>\n";
#define LEXMARK_INK_K 1
#define LEXMARK_INK_CMY 2
#define LEXMARK_INK_CMYK 4
#define LEXMARK_INK_CcMmYK 8
#define LEXMARK_INK_CcMmYy 16
#define LEXMARK_INK_CcMmYyK 32
#define LEXMARK_INK_BLACK_MASK (LEXMARK_INK_K|LEXMARK_INK_CMYK|\
LEXMARK_INK_CcMmYK|LEXMARK_INK_CcMmYyK)
#define LEXMARK_INK_PHOTO_MASK (LEXMARK_INK_CcMmYy|LEXMARK_INK_CcMmYK|\
LEXMARK_INK_CcMmYyK)
#define LEXMARK_SLOT_ASF1 1
#define LEXMARK_SLOT_ASF2 2
#define LEXMARK_SLOT_MAN1 4
#define LEXMARK_SLOT_MAN2 8
#define LEXMARK_CAP_DMT 1<<0
#define LEXMARK_CAP_MSB_FIRST 1<<1
#define LEXMARK_CAP_CMD61 1<<2
#define LEXMARK_CAP_CMD6d 1<<3
#define LEXMARK_CAP_CMD70 1<<4
#define LEXMARK_CAP_CMD72 1<<5
static const int lr_shift_color[10] = { 9, 18, 2*18 };
static const int lr_shift_black[10] = { 9, 18, 2*18 };
static const stp_parameter_t the_parameters[] =
{
{
"PageSize", N_("Page Size"), N_("Basic Printer Setup"),
N_("Size of the paper being printed to"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
{
"MediaType", N_("Media Type"), N_("Basic Printer Setup"),
N_("Type of media (plain paper, photo paper, etc.)"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
{
"InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
N_("Source (input slot) of the media"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
{
"Resolution", N_("Resolution"), N_("Basic Printer Setup"),
N_("Resolution and quality of the print"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
{
"InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
N_("Type of ink in the printer"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
{
"InkChannels", N_("Ink Channels"), N_("Advanced Printer Functionality"),
N_("Ink Channels"),
STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
STP_PARAMETER_LEVEL_INTERNAL, 0, 0, -1, 0, 0
},
{
"PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
N_("Printing Output Mode"),
STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
},
};
static const int the_parameter_count =
sizeof(the_parameters) / sizeof(const stp_parameter_t);
typedef struct
{
const stp_parameter_t param;
double min;
double max;
double defval;
int color_only;
} float_param_t;
static const float_param_t float_parameters[] =
{
{
{
"CyanDensity", N_("Cyan Balance"), N_("Output Level Adjustment"),
N_("Adjust the cyan balance"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
}, 0.0, 2.0, 1.0, 1
},
{
{
"MagentaDensity", N_("Magenta Balance"), N_("Output Level Adjustment"),
N_("Adjust the magenta balance"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
}, 0.0, 2.0, 1.0, 1
},
{
{
"YellowDensity", N_("Yellow Balance"), N_("Output Level Adjustment"),
N_("Adjust the yellow balance"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
}, 0.0, 2.0, 1.0, 1
},
{
{
"BlackDensity", N_("Black Balance"), N_("Output Level Adjustment"),
N_("Adjust the black balance"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
}, 0.0, 2.0, 1.0, 1
},
{
{
"LightCyanTransition", N_("Light Cyan Transition"), N_("Advanced Ink Adjustment"),
N_("Light Cyan Transition"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
}, 0.0, 5.0, 1.0, 1
},
{
{
"LightMagentaTransition", N_("Light Magenta Transition"), N_("Advanced Ink Adjustment"),
N_("Light Magenta Transition"),
STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
}, 0.0, 5.0, 1.0, 1
},
};
static const int float_parameter_count =
sizeof(float_parameters) / sizeof(const float_param_t);
static int get_lr_shift(int mode)
{
const int *ptr_lr_shift;
if((mode & COLOR_MODE_K) == (mode & COLOR_MODE_MASK)) {
ptr_lr_shift = lr_shift_black;
} else {
ptr_lr_shift = lr_shift_color;
}
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
return ptr_lr_shift[0];
break;
case PRINT_MODE_600:
return ptr_lr_shift[1];
break;
case PRINT_MODE_1200:
return ptr_lr_shift[2];
break;
case PRINT_MODE_2400:
return ptr_lr_shift[2];
break;
}
return 0;
}
static const int head_offset_cmyk[] =
{70, 368, 184, 0, 368, 184, 0};
static const int head_offset_cmy[] =
{0, 368, 184, 0, 368, 184, 0};
static const int head_offset_cCmMyk[] =
{0, 368, 184, 0, 368, 184, 0};
typedef struct {
const char *name;
const char *text;
int hres;
int vres;
int softweave;
int vertical_passes;
int vertical_oversample;
int unidirectional;
int resid;
} lexmark_res_t;
#define LEXM_RES_COUNT 30
typedef lexmark_res_t lexmark_res_t_array[LEXM_RES_COUNT];
typedef struct {
int ncolors;
unsigned int used_colors;
unsigned int pass_length;
int v_top_head_offset;
int h_catridge_offset;
int h_direction_offset;
const int *head_offset;
} lexmark_inkparam_t;
typedef struct
{
const char *name;
const char *text;
lexmark_inkparam_t ink_parameter[2];
} lexmark_inkname_t;
typedef struct {
Lex_model model;
int max_paper_width;
int max_paper_height;
int min_paper_width;
int min_paper_height;
int max_xdpi;
int max_ydpi;
int max_quality;
int border_left;
int border_right;
int border_top;
int border_bottom;
int inks;
int slots;
int features;
int offset_left_border;
int offset_top_border;
int x_raster_res;
int y_raster_res;
const lexmark_res_t_array *res_parameters;
const lexmark_inkname_t *ink_types;
const char *lum_adjustment;
const char *hue_adjustment;
const char *sat_adjustment;
} lexmark_cap_t;
#define LX_Z52_300_DPI 1
#define LX_Z52_600_DPI 3
#define LX_Z52_1200_DPI 4
#define LX_Z52_2400_DPI 5
#define LX_Z52_COLOR_PRINT 0
#define LX_Z52_BLACK_PRINT 1
#define LX_PSHIFT 0x13
#define LX_Z52_COLOR_MODE_POS 0x9
#define LX_Z52_RESOLUTION_POS 0x7
#define LX_Z52_PRINT_DIRECTION_POS 0x8
static const int IDX_SEQLEN=3;
#define LXM_Z52_HEADERSIZE 34
static const unsigned char outbufHeader_z52[LXM_Z52_HEADERSIZE]=
{
0x1B,0x2A,0x24,0x00,0x00,0xFF,0xFF,
0x01,0x01,0x01,0x1a,0x03,0x01,
0x03,0x60,
0x04,0xe0,
0x19,0x5c,
0x0,0x0,
0x0,0x80,
0x0,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0
};
#define LXM_Z42_HEADERSIZE 34
static const unsigned char outbufHeader_z42[LXM_Z42_HEADERSIZE]=
{
0x1B,0x2A,0x24,0x00,0x00,0x00,0x00,
0x01,0x01,0x01,0x18,0x00,0x01,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00
};
static const lexmark_res_t_array lexmark_reslist_z52 =
{
{ "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
{ "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
{ "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
{ "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
{ "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
{ "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
{ "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
{ "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
{ "2400x1200dpi", N_ ("2400 DPI x 1200 DPI"), 2400, 1200, 1, 1, 1, 0, DPI1200},
{ "2400x1200hq", N_ ("2400 DPI x 1200 DPI high quality"), 2400, 1200, 1, 1, 1, 0, DPI600 },
{ "2400x1200hq2", N_ ("2400 DPI x 1200 DPI highest quality"),2400, 1200, 1, 1, 1, 0, DPI300},
#ifdef DEBUG
{ "testprint", N_ ("test print"), 1200, 1200, 1, 1, 1, 0, DPItest},
#endif
{ "", "", 0, 0, 0, 0, 0, -1 }
};
static const lexmark_inkname_t ink_types_z52[] =
{
{ "CMYK", N_("Four Color Standard"),
{{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ 4, COLOR_MODE_CMYK, 192/3, 0, 0, 10, head_offset_cmyk }}},
{ "RGB", N_("Three Color Composite"),
{{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ 4, COLOR_MODE_CMY, 192/3, 0, 0, 10, head_offset_cmy }}},
{ "PhotoCMYK", N_("Six Color Photo"),
{{ 1, COLOR_MODE_K, 192/3, 0, 0, 10, head_offset_cCmMyk },
{ 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 10, head_offset_cCmMyk }}},
{ "PhotoCMY", N_("Five Color Photo Composite"),
{{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cCmMyk },
{ 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 10, head_offset_cCmMyk }}},
{ "Gray", N_("Black"),
{{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk },
{ 1, COLOR_MODE_K, 208, 324, 0, 10, head_offset_cmyk }}},
{ NULL, NULL }
};
#define LXM3200_LEFTOFFS 6254
#define LXM3200_RIGHTOFFS (LXM3200_LEFTOFFS-2120)
static int lxm3200_headpos = 0;
static int lxm3200_linetoeject = 0;
#define LXM_3200_HEADERSIZE 24
static const char outbufHeader_3200[LXM_3200_HEADERSIZE] =
{
0x1b, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static inline int
lexmark_calc_3200_checksum(unsigned char *data)
{
int ck, i;
ck = 0;
for(i=1; i<7; i++)ck += data[i];
return(ck & 255);
}
static const lexmark_res_t_array lexmark_reslist_3200 =
{
{ "300x600dpi", N_ ("300 DPI x 600 DPI"), 300, 600, 0, 1, 1, 0, DPI300 },
{ "600dpi", N_ ("600 DPI"), 600, 600, 0, 1, 1, 0, DPI600 },
{ "600hq", N_ ("600 DPI high quality"), 600, 600, 1, 4, 1, 0, DPI600 },
{ "600uni", N_ ("600 DPI Unidirectional"), 600, 600, 0, 1, 1, 1, DPI600 },
{ "1200dpi", N_ ("1200 DPI"), 1200, 1200, 1, 1, 1, 0, DPI1200},
{ "1200hq", N_ ("1200 DPI high quality"), 1200, 1200, 1, 1, 1, 0, DPI300 },
{ "1200hq2", N_ ("1200 DPI highest quality"), 1200, 1200, 1, 1, 1, 0, DPI600 },
{ "1200uni", N_ ("1200 DPI Unidirectional"), 1200, 1200, 0, 1, 1, 1, DPI1200},
{ "", "", 0, 0, 0, 0, 0, -1 }
};
static const lexmark_inkname_t ink_types_3200[] =
{
{ "CMYK", N_("Four Color Standard"),
{{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ 4, COLOR_MODE_CMYK, 192/3, 0, 0, 12, head_offset_cmyk }}},
{ "RGB", N_("Three Color Composite"),
{{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cmyk },
{ 4, COLOR_MODE_CMY, 192/3, 0, 0, 12, head_offset_cmy }}},
{ "PhotoCMYK", N_("Six Color Photo"),
{{ 1, COLOR_MODE_K, 192/3, 0, 0, 12, head_offset_cCmMyk },
{ 6, COLOR_MODE_CcMcYK, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
{ "PhotoCMY", N_("Five Color Photo Composite"),
{{ 1, COLOR_MODE_K, 208, 20, 0, 12, head_offset_cCmMyk },
{ 5, COLOR_MODE_CcMcY, 192/3, 0, 0, 12, head_offset_cCmMyk }}},
{ NULL, NULL }
};
static const lexmark_cap_t lexmark_model_capabilities[] =
{
{ (Lex_model)-1, 8*72,11*72,180,180,20,20,20,20, LEXMARK_INK_K, LEXMARK_SLOT_ASF1, 0 },
{
m_z52,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
0, 0, 5, 15,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
20,
123,
2400,
1200,
&lexmark_reslist_z52,
ink_types_z52,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_z42,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
0, 0, 5, 41,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
20,
123,
2400,
1200,
&lexmark_reslist_z52,
ink_types_z52,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_3200,
618, 936,
INCH(2), INCH(4),
1200, 1200, 2,
11, 9, 10, 18,
LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
0,
300,
1200,
1200,
&lexmark_reslist_3200,
ink_types_3200,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
{
m_lex7500,
618, 936,
INCH(2), INCH(4),
2400, 1200, 2,
11, 9, 10, 18,
LEXMARK_INK_CMY | LEXMARK_INK_CMYK | LEXMARK_INK_CcMmYK,
LEXMARK_SLOT_ASF1 | LEXMARK_SLOT_MAN1,
LEXMARK_CAP_DMT,
0,
300,
1200,
1200,
&lexmark_reslist_3200,
ink_types_3200,
standard_lum_adjustment, standard_hue_adjustment, standard_sat_adjustment
},
};
typedef struct lexm_privdata_weave {
const lexmark_inkparam_t *ink_parameter;
int bidirectional;
int direction;
int hoffset;
int model;
int width;
int ydpi;
int xdpi;
int physical_xdpi;
int last_pass_offset;
int jets;
int bitwidth;
int ncolors;
int horizontal_weave;
unsigned char *outbuf;
} lexm_privdata_weave;
static int model_to_index(int model)
{
int i;
int models= sizeof(lexmark_model_capabilities) / sizeof(lexmark_cap_t);
for (i=0; i<models; i++) {
if (lexmark_model_capabilities[i].model == model) {
return i;
}
}
return -1;
}
static const lexmark_cap_t *
lexmark_get_model_capabilities(int model)
{
int i = model_to_index(model);
if (i != -1) {
return &(lexmark_model_capabilities[i]);
}
#ifdef DEBUG
stp_erprintf("lexmark: model %d not found in capabilities list.\n",model);
#endif
return &(lexmark_model_capabilities[0]);
}
typedef struct
{
const char *name;
const char *text;
int paper_feed_sequence;
int platen_gap;
double base_density;
double k_lower_scale;
double k_upper;
double cyan;
double magenta;
double yellow;
double p_cyan;
double p_magenta;
double p_yellow;
double saturation;
double gamma;
int feed_adjustment;
int vacuum_intensity;
int paper_thickness;
const char *hue_adjustment;
const char *lum_adjustment;
const char *sat_adjustment;
} paper_t;
static const paper_t lexmark_paper_list[] =
{
{ "Plain", N_("Plain Paper"),
1, 0, 0.80, .1, .5, 1.0, 1.0, 1.0, .9, 1.05, 1.15,
1, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "GlossyFilm", N_("Glossy Film"),
3, 0, 1.00 ,1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6d, 0x00, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Transparency", N_("Transparencies"),
3, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x6d, 0x00, 0x02,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Envelope", N_("Envelopes"),
4, 0, 0.80, .125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Matte", N_("Matte Paper"),
7, 0, 0.85, 1.0, .999, 1.05, .9, 1.05, .9, 1.0, 1.1,
1, 1.0, 0x00, 0x00, 0x02,
standard_hue_adjustment, standard_sat_adjustment, standard_sat_adjustment},
{ "Inkjet", N_("Inkjet Paper"),
7, 0, 0.85, .25, .6, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Coated", N_("Photo Quality Inkjet Paper"),
7, 0, 1.00, 1.0, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Photo", N_("Photo Paper"),
8, 0, 1.00, 1.0, .9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x67, 0x00, 0x02,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "GlossyPhoto", N_("Premium Glossy Photo Paper"),
8, 0, 1.10, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.03, 1.0,
1, 1.0, 0x80, 0x00, 0x02,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Luster", N_("Premium Luster Photo Paper"),
8, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x80, 0x00, 0x02,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "GlossyPaper", N_("Photo Quality Glossy Paper"),
6, 0, 1.00, 1, .999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Ilford", N_("Ilford Heavy Paper"),
8, 0, .85, .5, 1.35, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x80, 0x00, 0x02,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
{ "Other", N_("Other"),
0, 0, 0.80, 0.125, .5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1, 1.0, 0x6b, 0x1a, 0x01,
standard_hue_adjustment, standard_lum_adjustment, standard_sat_adjustment},
};
static const int paper_type_count = sizeof(lexmark_paper_list) / sizeof(paper_t);
static const lexmark_inkname_t *
lexmark_get_ink_type(const char *name, int printing_color, const lexmark_cap_t * caps)
{
int i = 0;
const lexmark_inkname_t *ink_type = caps->ink_types;
if (name)
for (i=0; ((ink_type[i].name != NULL) &&
(strcmp(name, ink_type[i].name) != 0)); i++) ;
return &(ink_type[i]);
}
static const lexmark_inkparam_t *
lexmark_get_ink_parameter(const char *name, int printing_color, const lexmark_cap_t * caps, const stp_vars_t *nv)
{
const lexmark_inkname_t *ink_type = lexmark_get_ink_type(name, printing_color, caps);
if (ink_type->name == NULL) {
return (NULL);
}
return &(ink_type->ink_parameter[printing_color]);
}
static const paper_t *
get_media_type(const char *name, const lexmark_cap_t * caps)
{
int i;
if (name)
{
for (i = 0; i < paper_type_count; i++)
{
if (!strcmp(name, lexmark_paper_list[i].name))
return &(lexmark_paper_list[i]);
}
}
return NULL;
}
static int
lexmark_source_type(const char *name, const lexmark_cap_t * caps)
{
if (name)
{
if (!strcmp(name,"Auto")) return 4;
if (!strcmp(name,"Manual")) return 0;
if (!strcmp(name,"ManualNP")) return 1;
}
#ifdef DEBUG
stp_erprintf("lexmark: Unknown source type '%s' - reverting to auto\n",name);
#endif
return 4;
}
static const lexmark_lineoff_t *
lexmark_head_offset(int ydpi,
const char *ink_type,
const lexmark_cap_t * caps,
const lexmark_inkparam_t *ink_parameter,
lexmark_lineoff_t *lineoff_buffer)
{
int i;
#ifdef DEBUG
stp_erprintf(" sizie %d, size_v %d, size_v[0] %d\n", sizeof(*lineoff_buffer), sizeof(lineoff_buffer->v), sizeof(lineoff_buffer->v[0]));
#endif
memcpy(lineoff_buffer, ink_parameter->head_offset, sizeof(*lineoff_buffer));
for (i=0; i < (sizeof(lineoff_buffer->v) / sizeof(lineoff_buffer->v[0])); i++) {
lineoff_buffer->v[i] /= (caps->y_raster_res / ydpi);
}
return (lineoff_buffer);
}
#if 0
static unsigned char
lexmark_size_type(const stp_vars_t *v, const lexmark_cap_t * caps)
{
const stp_papersize_t *pp = stp_get_papersize_by_size(stp_get_page_height(v),
stp_get_page_width(v));
if (pp)
{
const char *name = pp->name;
if (!strcmp(name,"A5")) return 0x01;
if (!strcmp(name,"A4")) return 0x03;
if (!strcmp(name,"B5")) return 0x08;
if (!strcmp(name,"Letter")) return 0x0d;
if (!strcmp(name,"Legal")) return 0x0f;
if (!strcmp(name,"COM10")) return 0x16;
if (!strcmp(name,"DL")) return 0x17;
if (!strcmp(name,"LetterExtra")) return 0x2a;
if (!strcmp(name,"A4Extra")) return 0x2b;
if (!strcmp(name,"w288h144")) return 0x2d;
#ifdef DEBUG
stp_erprintf("lexmark: Unknown paper size '%s' - using custom\n",name);
} else {
stp_erprintf("lexmark: Couldn't look up paper size %dx%d - "
"using custom\n",stp_get_page_height(v), stp_get_page_width(v));
#endif
}
return 0;
}
#endif
static int lexmark_get_phys_resolution_vertical(int model)
{
return 600;
}
#if 0
static int lexmark_get_phys_resolution_horizontal(int model)
{
return 1200;
}
#endif
static const lexmark_res_t
*lexmark_get_resolution_para(int model, const char *resolution)
{
const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
const lexmark_res_t *res = *(caps->res_parameters);
if (resolution)
{
while (res->hres)
{
if ((res->vres <= caps->max_ydpi) && (caps->max_ydpi != -1) &&
(res->hres <= caps->max_xdpi) && (caps->max_xdpi != -1) &&
(!strcmp(resolution, res->name)))
{
return res;
}
res++;
}
}
stp_erprintf("lexmark_get_resolution_para: resolution not found (%s)\n", resolution);
return NULL;
}
static int
lexmark_print_bidirectional(int model, const char *resolution)
{
const lexmark_res_t *res_para = lexmark_get_resolution_para(model, resolution);
return !res_para->unidirectional;
}
static const char *
lexmark_lum_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
{
return (caps->lum_adjustment);
}
static const char *
lexmark_hue_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
{
return (caps->hue_adjustment);
}
static const char *
lexmark_sat_adjustment(const lexmark_cap_t * caps, const stp_vars_t *v)
{
return (caps->sat_adjustment);
}
static void
lexmark_describe_resolution(const stp_vars_t *v, int *x, int *y)
{
const char *resolution = stp_get_string_parameter(v, "Resolution");
const lexmark_res_t *res =
lexmark_get_resolution_para(stp_get_model_id(v), resolution);
if (res)
{
*x = res->hres;
*y = res->vres;
return;
}
*x = -1;
*y = -1;
}
static stp_param_string_t media_sources[] =
{
{ "Auto", N_("Auto Sheet Feeder") },
{ "Manual", N_("Manual with Pause") },
{ "ManualNP", N_("Manual without Pause") }
};
static stp_parameter_list_t
lexmark_list_parameters(const stp_vars_t *v)
{
stp_parameter_list_t *ret = stp_parameter_list_create();
int i;
for (i = 0; i < the_parameter_count; i++)
stp_parameter_list_add_param(ret, &(the_parameters[i]));
for (i = 0; i < float_parameter_count; i++)
stp_parameter_list_add_param(ret, &(float_parameters[i].param));
return ret;
}
static const char *
lexmark_describe_output(const stp_vars_t *v)
{
int printing_color = 0;
int model = stp_get_model_id(v);
const lexmark_cap_t *caps = lexmark_get_model_capabilities(model);
const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
const char *ink_type = stp_get_string_parameter(v, "InkType");
const lexmark_inkparam_t *ink_parameter;
if (!print_mode || strcmp(print_mode, "Color") == 0)
printing_color = 1;
ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
if (ink_parameter->used_colors == COLOR_MODE_K ||
caps->inks == LEXMARK_INK_K || !printing_color)
return "Grayscale";
else if (!(ink_parameter->used_colors & COLOR_MODE_K))
return "CMY";
else
return "CMYK";
}
static void
lexmark_parameters(const stp_vars_t *v, const char *name,
stp_parameter_t *description)
{
int i;
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
description->p_type = STP_PARAMETER_TYPE_INVALID;
if (name == NULL)
return;
for (i = 0; i < float_parameter_count; i++)
if (strcmp(name, float_parameters[i].param.name) == 0)
{
stp_fill_parameter_settings(description,
&(float_parameters[i].param));
description->deflt.dbl = float_parameters[i].defval;
description->bounds.dbl.upper = float_parameters[i].max;
description->bounds.dbl.lower = float_parameters[i].min;
return;
}
for (i = 0; i < the_parameter_count; i++)
if (strcmp(name, the_parameters[i].name) == 0)
{
stp_fill_parameter_settings(description, &(the_parameters[i]));
break;
}
if (strcmp(name, "PageSize") == 0)
{
unsigned int height_limit, width_limit;
unsigned int min_height_limit, min_width_limit;
int papersizes = stp_known_papersizes();
description->bounds.str = stp_string_list_create();
width_limit = caps->max_paper_width;
height_limit = caps->max_paper_height;
min_width_limit = caps->min_paper_width;
min_height_limit = caps->min_paper_height;
for (i = 0; i < papersizes; i++) {
const stp_papersize_t *pt = stp_get_papersize_by_index(i);
if (strlen(pt->name) > 0 &&
pt->width <= width_limit && pt->height <= height_limit &&
(pt->height >= min_height_limit || pt->height == 0) &&
(pt->width >= min_width_limit || pt->width == 0))
{
if (stp_string_list_count(description->bounds.str) == 0)
description->deflt.str = pt->name;
stp_string_list_add_string(description->bounds.str,
pt->name, pt->text);
}
}
}
else if (strcmp(name, "Resolution") == 0)
{
const lexmark_res_t *res;
description->bounds.str = stp_string_list_create();
res = *(caps->res_parameters);
while (res->hres)
{
if (stp_string_list_count(description->bounds.str) == 0)
description->deflt.str = res->name;
stp_string_list_add_string(description->bounds.str,
res->name, _(res->text));
res++;
}
}
else if (strcmp(name, "InkType") == 0)
{
description->bounds.str = stp_string_list_create();
description->deflt.str = caps->ink_types[0].name;
for (i = 0; caps->ink_types[i].name != NULL; i++)
stp_string_list_add_string(description->bounds.str,
caps->ink_types[i].name,
_(caps->ink_types[i].text));
}
else if (strcmp(name, "MediaType") == 0)
{
description->bounds.str = stp_string_list_create();
description->deflt.str = lexmark_paper_list[0].name;
for (i = 0; i < paper_type_count; i++)
stp_string_list_add_string(description->bounds.str,
lexmark_paper_list[i].name,
_(lexmark_paper_list[i].text));
}
else if (strcmp(name, "InputSlot") == 0)
{
description->bounds.str = stp_string_list_create();
description->deflt.str = media_sources[0].name;
for (i = 0; i < sizeof(media_sources) / sizeof(stp_param_string_t); i++)
stp_string_list_add_string(description->bounds.str,
media_sources[i].name,
_(media_sources[i].name));
}
else if (strcmp(name, "InkChannels") == 0)
{
if (caps->inks & LEXMARK_INK_CcMmYyK)
description->deflt.integer = 7;
else if (caps->inks & LEXMARK_INK_CcMmYK)
description->deflt.integer = 6;
else if (caps->inks & LEXMARK_INK_CMYK)
description->deflt.integer = 4;
else if (caps->inks & LEXMARK_INK_CMY)
description->deflt.integer = 3;
else
description->deflt.integer = 1;
description->bounds.integer.lower = -1;
description->bounds.integer.upper = -1;
}
else if (strcmp(name, "PrintingMode") == 0)
{
description->bounds.str = stp_string_list_create();
stp_string_list_add_string
(description->bounds.str, "Color", _("Color"));
stp_string_list_add_string
(description->bounds.str, "BW", _("Black and White"));
description->deflt.str =
stp_string_list_param(description->bounds.str, 0)->name;
}
}
static void
internal_imageable_area(const stp_vars_t *v,
int use_paper_margins,
int *left,
int *right,
int *bottom,
int *top)
{
int width, length;
int left_margin = 0;
int right_margin = 0;
int bottom_margin = 0;
int top_margin = 0;
const char *media_size = stp_get_string_parameter(v, "PageSize");
const stp_papersize_t *pt = NULL;
const lexmark_cap_t *caps =
lexmark_get_model_capabilities(stp_get_model_id(v));
if (media_size && use_paper_margins)
pt = stp_get_papersize_by_name(media_size);
stp_default_media_size(v, &width, &length);
if (pt)
{
left_margin = pt->left;
right_margin = pt->right;
bottom_margin = pt->bottom;
top_margin = pt->top;
}
left_margin = max(left_margin, caps->border_left);
right_margin = max(right_margin, caps->border_right);
top_margin = max(top_margin, caps->border_top);
bottom_margin = max(bottom_margin, caps->border_bottom);
*left = left_margin;
*right = width - right_margin;
*top = top_margin;
*bottom = length - bottom_margin;
}
static void
lexmark_imageable_area(const stp_vars_t *v,
int *left,
int *right,
int *bottom,
int *top)
{
internal_imageable_area(v, 1, left, right, bottom, top);
}
static void
lexmark_limit(const stp_vars_t *v,
int *width,
int *height,
int *min_width,
int *min_height)
{
const lexmark_cap_t * caps= lexmark_get_model_capabilities(stp_get_model_id(v));
*width = caps->max_paper_width;
*height = caps->max_paper_height;
*min_width = caps->min_paper_width;
*min_height = caps->min_paper_height;
}
static int
lexmark_init_printer(const stp_vars_t *v, const lexmark_cap_t * caps,
int printing_color,
const char *source_str,
int xdpi, int ydpi,
int page_width, int page_height,
int top, int left,
int use_dmt)
{
#define LXM_Z52_STARTSIZE 0x35
unsigned char startHeader_z52[LXM_Z52_STARTSIZE]={0x1b,0x2a,0x81,0x00,0x1c,0x56,0x49,0x00,
0x01,0x00,0x2c,0x01,0x00,0x00,0x60,0x09,
0xe4,0x0c,0x01,0x00,0x34,0x00,0x00,0x00,
0x08,0x00,0x08,0x00,0x1b,0x2a,0x07,0x76,
0x01,0x1b,0x2a,0x07,0x73,0x30,0x1b,0x2a,
0x6d,0x00,0x14,0x01,0xf4,0x02,0x00,0x01,
0xf0,0x1b,0x2a,0x07,0x63};
#define LXM_Z42_STARTSIZE 0x30
unsigned char startHeader_z42[LXM_Z42_STARTSIZE]={0x1B,0x2A,0x81,0x00,0x1C,0x50,0x41,0x00,
0x01,0x00,0x58,0x02,0x04,0x00,0xC0,0x12,
0xC8,0x19,0x02,0x00,0x50,0x00,0x14,0x00,
0x07,0x00,0x08,0x00,0x1B,0x2A,0x07,0x73,
0x30,0x1B,0x2A,0x6D,0x00,0x14,0x01,0xC0,
0x02,0x00,0x01,0xBE,0x1B,0x2A,0x07,0x63};
#define ESC2a "\033\052"
#define LXM_3200_STARTSIZE 32
unsigned char startHeader_3200[LXM_3200_STARTSIZE] =
{
0x1b, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33,
0x1b, 0x30, 0x80, 0x0C, 0x02, 0x00, 0x00, 0xbe,
0x1b, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21
};
switch(caps->model)
{
case m_z52:
stp_zfwrite((const char *) startHeader_z52,
LXM_Z52_STARTSIZE,1,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)startHeader_z52, LXM_Z52_STARTSIZE);
#endif
case m_z42:
stp_zfwrite((const char *) startHeader_z42,
LXM_Z42_STARTSIZE,1,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)startHeader_z42, LXM_Z42_STARTSIZE);
#endif
break;
case m_3200:
stp_zfwrite((const char *) startHeader_3200,
LXM_3200_STARTSIZE, 1, v);
break;
default:
stp_erprintf("Unknown printer !! %i\n", caps->model);
return 0;
}
return 1;
}
static void lexmark_deinit_printer(const stp_vars_t *v, const lexmark_cap_t * caps)
{
switch(caps->model) {
case m_z52:
{
char buffer[40];
memcpy(buffer, ESC2a, 2);
buffer[2] = 0x7;
buffer[3] = 0x65;
#ifdef DEBUG
stp_erprintf("lexmark: <<eject page.>> %x %x %x %x %lx\n", buffer[0], buffer[1], buffer[2], buffer[3], dbgfileprn);
lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 4);
#endif
stp_zfwrite(buffer, 1, 4, v);
}
break;
case m_z42:
{
unsigned char buffer[12] = {0x1B,0x2A,0x07,0x65,0x1B,0x2A,0x82,0x00,0x00,0x00,0x00,0xAC};
#ifdef DEBUG
stp_erprintf("lexmark: <<eject page.>>\n");
lex_write_tmp_file(dbgfileprn, (void *)&(buffer[0]), 12);
#endif
stp_zfwrite((char *)buffer, 1, 12, v);
}
break;
case m_3200:
{
unsigned char buffer[24] =
{
0x1b, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x31, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1b, 0x33, 0x10, 0x00, 0x00, 0x00, 0x00, 0x33
};
#ifdef DEBUG
stp_erprintf("Headpos: %d\n", lxm3200_headpos);
#endif
lxm3200_linetoeject += 2400;
buffer[3] = lxm3200_linetoeject >> 8;
buffer[4] = lxm3200_linetoeject & 0xff;
buffer[7] = lexmark_calc_3200_checksum(&buffer[0]);
buffer[11] = lxm3200_headpos >> 8;
buffer[12] = lxm3200_headpos & 0xff;
buffer[15] = lexmark_calc_3200_checksum(&buffer[8]);
stp_zfwrite((const char *)buffer, 24, 1, v);
}
break;
case m_lex7500:
break;
}
}
static void paper_shift(const stp_vars_t *v, int offset, const lexmark_cap_t * caps)
{
switch(caps->model) {
case m_z52:
case m_z42:
{
unsigned char buf[5] = {0x1b, 0x2a, 0x3, 0x0, 0x0};
if(offset == 0)return;
buf[3] = (unsigned char)(offset >> 8);
buf[4] = (unsigned char)(offset & 0xFF);
stp_zfwrite((const char *)buf, 1, 5, v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)buf, 5);
#endif
}
break;
case m_3200:
{
unsigned char buf[8] = {0x1b, 0x23, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00};
if(offset == 0)return;
lxm3200_linetoeject -= offset;
buf[3] = (unsigned char)(offset >> 8);
buf[4] = (unsigned char)(offset & 0xff);
buf[7] = lexmark_calc_3200_checksum(buf);
stp_zfwrite((const char *)buf, 1, 8, v);
}
break;
case m_lex7500:
break;
}
#ifdef DEBUG
stp_erprintf("Lines to eject: %d\n", lxm3200_linetoeject);
#endif
}
#if 0
static void
lexmark_advance_buffer(unsigned char *buf, int len, int num)
{
if (!buf || !len) return;
if (num>0) memmove(buf+len,buf,len*num);
memset(buf,0,len);
}
#endif
static double
get_double_param(stp_vars_t *v, const char *param)
{
if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
return stp_get_float_parameter(v, param);
else
return 1.0;
}
static int
lexmark_do_print(stp_vars_t *v, stp_image_t *image)
{
int status = 1;
int y;
int xdpi, ydpi;
int n;
int page_width,
page_height,
page_left,
page_top,
page_right,
page_bottom,
page_true_height,
out_width,
out_height,
out_channels,
length,
buf_length,
errdiv,
errmod,
errval,
errline,
errlast;
unsigned zero_mask;
int image_height,
image_width;
int use_dmt = 0;
int pass_length=0;
int add_top_offset=0;
int printMode = 0;
int source;
double densityDivisor;
double k_lower, k_upper;
int physical_xdpi = 0;
int physical_ydpi = 0;
int i;
stp_curve_t *lum_adjustment = NULL;
stp_curve_t *hue_adjustment = NULL;
stp_curve_t *sat_adjustment = NULL;
lexmark_linebufs_t cols;
int nozzle_separation;
int horizontal_passes;
int ncolors;
lexm_privdata_weave privdata;
lexmark_lineoff_t lineoff_buffer;
#ifdef DEBUG
testdata td;
#endif
int model = stp_get_model_id(v);
const char *resolution = stp_get_string_parameter(v, "Resolution");
const char *media_type = stp_get_string_parameter(v, "MediaType");
const char *media_source = stp_get_string_parameter(v, "InputSlot");
const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
int printing_color = 0;
const char *ink_type = stp_get_string_parameter(v, "InkType");
int top = stp_get_top(v);
int left = stp_get_left(v);
const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
const lexmark_res_t *res_para_ptr =
lexmark_get_resolution_para(model, resolution);
const paper_t *media = get_media_type(media_type,caps);
const lexmark_inkparam_t *ink_parameter;
stp_prune_inactive_options(v);
#ifdef DEBUG
dbgfileprn = lex_open_tmp_file();
#endif
if (!stp_verify(v))
{
stp_eprintf(v, "Print options not verified; cannot print.\n");
return 0;
}
if (strcmp(print_mode, "Color") == 0)
printing_color = 1;
ink_parameter = lexmark_get_ink_parameter(ink_type, printing_color, caps, v);
if (ink_parameter == NULL)
{
stp_eprintf(v, "Illegal Ink Type specified; cannot print.\n");
return 0;
}
stp_image_init(image);
source= lexmark_source_type(media_source,caps);
if ((ink_parameter->used_colors == COLOR_MODE_K) ||
(caps->inks == LEXMARK_INK_K))
{
printing_color = 0;
stp_set_string_parameter(v, "PrintingMode", "BW");
}
ncolors = ink_parameter->ncolors;
printMode = ink_parameter->used_colors;
pass_length = ink_parameter->pass_length;
add_top_offset = ink_parameter->v_top_head_offset;
stp_describe_resolution(v, &xdpi, &ydpi);
#ifdef DEBUG
stp_erprintf("lexmark: resolution=%dx%d\n",xdpi,ydpi);
#endif
switch (res_para_ptr->resid) {
case DPI300:
physical_xdpi = 300;
physical_ydpi = lexmark_get_phys_resolution_vertical(model);
break;
case DPI600:
physical_xdpi = 600;
physical_ydpi = lexmark_get_phys_resolution_vertical(model);
break;
case DPI1200:
case DPItest:
physical_xdpi = 1200;
physical_ydpi = lexmark_get_phys_resolution_vertical(model);
break;
default:
return 0;
break;
}
densityDivisor = ((xdpi / 300)*(ydpi/ 600));
#ifdef DEBUG
if (res_para_ptr->resid == DPItest) {
stp_erprintf("Start test print1\n");
doTestPrint = 1;
}
#endif
if ((printMode & COLOR_MODE_PHOTO) == COLOR_MODE_PHOTO) {
densityDivisor /= 1.2;
}
nozzle_separation = ydpi / physical_ydpi;
horizontal_passes = xdpi / physical_xdpi;
#ifdef DEBUG
stp_erprintf("lexmark: horizontal_passes %i, xdpi %i, physical_xdpi %i\n",
horizontal_passes, xdpi, physical_xdpi);
#endif
if (!strcmp(resolution+(strlen(resolution)-3),"DMT") &&
(caps->features & LEXMARK_CAP_DMT)) {
use_dmt= 1;
#ifdef DEBUG
stpi_erprintf("lexmark: using drop modulation technology\n");
#endif
}
out_width = stp_get_width(v);
out_height = stp_get_height(v);
internal_imageable_area(v, 0, &page_left, &page_right,
&page_bottom, &page_top);
left -= page_left;
top -= page_top;
page_width = page_right - page_left;
page_height = page_bottom - page_top;
#ifdef DEBUG
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);
#endif
image_height = stp_image_height(image);
image_width = stp_image_width(image);
stp_default_media_size(v, &n, &page_true_height);
lxm3200_linetoeject = (page_true_height * 1200) / 72;
if (!lexmark_init_printer(v, caps, printing_color,
media_source,
xdpi, ydpi, page_width, page_height,
top,left,use_dmt))
return 0;
out_width = xdpi * out_width / 72;
out_height = ydpi * out_height / 72;
#ifdef DEBUG
stp_erprintf("border: left %ld, x_raster_res %d, offser_left %ld\n", left, caps->x_raster_res, caps->offset_left_border);
#endif
left = ((caps->x_raster_res * left) / 72) + caps->offset_left_border;
#ifdef DEBUG
stp_erprintf("border: left %d\n", left);
#endif
#ifdef DEBUG
if (doTestPrint == 1) {
stp_erprintf("Start test print\n");
testprint(&td);
out_width = td.x;
out_height = td.y;
if (td.cols != 7) {
printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y;
} else {
printMode = COLOR_MODE_K | COLOR_MODE_M | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_LM | COLOR_MODE_LC;
}
}
#endif
length = (out_width + 7) / 8;
if (use_dmt) {
buf_length= length;
} else {
buf_length= length;
}
#ifdef DEBUG
stp_erprintf("lexmark: buflength is %d!\n",buf_length);
#endif
cols.p.k = NULL;
cols.p.c = NULL;
cols.p.y = NULL;
cols.p.m = NULL;
cols.p.C = NULL;
cols.p.M = NULL;
cols.p.Y = NULL;
if ((printMode & COLOR_MODE_C) == COLOR_MODE_C) {
cols.p.c = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_Y) == COLOR_MODE_Y) {
cols.p.y = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_M) == COLOR_MODE_M) {
cols.p.m = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_K) == COLOR_MODE_K) {
cols.p.k = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LC) == COLOR_MODE_LC) {
cols.p.C = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LY) == COLOR_MODE_LY) {
cols.p.Y = stp_zalloc(buf_length+10);
}
if ((printMode & COLOR_MODE_LM) == COLOR_MODE_LM) {
cols.p.M = stp_zalloc(buf_length+10);
}
if (cols.p.k)
{
if (cols.p.c)
stp_set_string_parameter(v, "STPIOutputType", "KCMY");
else
stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
}
else
stp_set_string_parameter(v, "STPIOutputType", "CMY");
#ifdef DEBUG
stp_erprintf("lexmark: driver will use colors ");
if (cols.p.c) stp_erputc('c');
if (cols.p.C) stp_erputc('C');
if (cols.p.m) stp_erputc('m');
if (cols.p.M) stp_erputc('M');
if (cols.p.y) stp_erputc('y');
if (cols.p.Y) stp_erputc('Y');
if (cols.p.k) stp_erputc('k');
stp_erprintf("\n");
#endif
privdata.ink_parameter = ink_parameter;
privdata.bidirectional = lexmark_print_bidirectional(model, resolution);
privdata.outbuf = stp_malloc((((((pass_length/8)*11))+40) * out_width)+2000);
privdata.direction = 0;
stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
stp_initialize_weave(v,
pass_length,
nozzle_separation,
horizontal_passes,
res_para_ptr->vertical_passes,
res_para_ptr->vertical_oversample,
ncolors,
1,
out_width,
out_height,
((top * ydpi) / 72)+(((caps->offset_top_border+add_top_offset)*ydpi)
/caps->y_raster_res),
(page_height * ydpi) / 72,
(const int *) lexmark_head_offset(ydpi, ink_type, caps, ink_parameter, &lineoff_buffer),
STP_WEAVE_ZIGZAG,
flush_pass,
stp_fill_uncompressed,
stp_pack_uncompressed,
stp_compute_uncompressed_linewidth);
privdata.last_pass_offset = 0;
privdata.jets = pass_length;
privdata.ncolors = ncolors;
privdata.horizontal_weave = horizontal_passes;
if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
{
stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
stp_set_float_parameter(v, "Density", 1.0);
}
#ifdef DEBUG
stp_erprintf("density is %f\n",stp_get_parameter(v, "Density"));
#endif
#ifdef DEBUG
stp_erprintf("density is %f and will be changed to %f (%f)\n",
stp_get_float_parameter(v, "Density"),
stp_get_float_parameter(v, "Density") / densityDivisor,
densityDivisor);
#endif
stp_scale_float_parameter(v, "Density", 1.0 / densityDivisor);
if (ncolors > 4)
k_lower = .5;
else
k_lower = .25;
if (media)
{
stp_scale_float_parameter(v, "Density", media->base_density);
stp_scale_float_parameter(v, "Cyan", media->p_cyan);
stp_scale_float_parameter(v, "Magenta", media->p_magenta);
stp_scale_float_parameter(v, "Yellow", media->p_yellow);
k_lower *= media->k_lower_scale;
k_upper = media->k_upper;
}
else
{
stp_scale_float_parameter(v, "Density", .8);
k_lower *= .1;
k_upper = .5;
}
if (stp_get_float_parameter(v, "Density") > 1.0)
stp_set_float_parameter(v, "Density", 1.0);
#ifdef DEBUG
stp_erprintf("density is %f\n",stp_get_float_parameter(v, "Density"));
#endif
if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
stp_set_default_float_parameter(v, "GCRLower", k_lower);
if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
stp_set_default_float_parameter(v, "GCRUpper", k_upper);
stp_dither_init(v, image, out_width, xdpi, ydpi);
if (!use_dmt) {
if (cols.p.C)
{
stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
0.31 / .5);
}
if (cols.p.M)
{
stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
0.61 / .97);
}
if (cols.p.Y)
{
stp_dither_set_inks_full(v, STP_ECOLOR_Y, 2, photo_dither_shades, 1.0,
0.08);
}
}
stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
get_double_param(v, "BlackDensity") *
get_double_param(v, "Density"));
stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
get_double_param(v, "CyanDensity") *
get_double_param(v, "Density"));
stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
get_double_param(v, "MagentaDensity") *
get_double_param(v, "Density"));
stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
get_double_param(v, "YellowDensity") *
get_double_param(v, "Density"));
if (!use_dmt) {
if (cols.p.C)
{
stp_channel_set_density_adjustment
(v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
get_double_param(v, "LightCyanTransition") *
get_double_param(v, "Density")));
}
if (cols.p.M)
{
stp_channel_set_density_adjustment
(v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
get_double_param(v, "LightMagentaTransition") *
get_double_param(v, "Density")));
}
if (cols.p.Y)
{
stp_channel_set_density_adjustment
(v, STP_ECOLOR_Y, 1, (get_double_param(v, "YellowDensity") *
get_double_param(v, "LightYellowTransition") *
get_double_param(v, "Density")));
}
}
if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE) &&
media->hue_adjustment)
{
hue_adjustment = stp_read_and_compose_curves
(lexmark_hue_adjustment(caps, v),
media ? media->hue_adjustment : NULL, STP_CURVE_COMPOSE_ADD, 384);
stp_set_curve_parameter(v, "HueMap", hue_adjustment);
stp_curve_destroy(hue_adjustment);
}
if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE) &&
media->lum_adjustment)
{
lum_adjustment = stp_read_and_compose_curves
(lexmark_lum_adjustment(caps, v),
media ? media->lum_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
stp_set_curve_parameter(v, "LumMap", lum_adjustment);
stp_curve_destroy(lum_adjustment);
}
if (!stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_ACTIVE) &&
media->sat_adjustment)
{
sat_adjustment = stp_read_and_compose_curves
(lexmark_sat_adjustment(caps, v),
media ? media->sat_adjustment : NULL, STP_CURVE_COMPOSE_MULTIPLY, 384);
stp_set_curve_parameter(v, "SatMap", sat_adjustment);
stp_curve_destroy(sat_adjustment);
}
out_channels = stp_color_init(v, image, 65536);
#ifdef DEBUG
stp_erprintf("---------- buffer mem size = %d\n", (((((pass_length/8)*11)/10)+40) * out_width)+200);
#endif
errdiv = image_height / out_height;
errmod = image_height % out_height;
errval = 0;
errlast = -1;
errline = 0;
if (cols.p.k)
stp_dither_add_channel(v, cols.p.k, STP_ECOLOR_K, 0);
if (cols.p.c)
stp_dither_add_channel(v, cols.p.c, STP_ECOLOR_C, 0);
if (cols.p.C)
stp_dither_add_channel(v, cols.p.C, STP_ECOLOR_C, 1);
if (cols.p.m)
stp_dither_add_channel(v, cols.p.m, STP_ECOLOR_M, 0);
if (cols.p.M)
stp_dither_add_channel(v, cols.p.M, STP_ECOLOR_M, 1);
if (cols.p.y)
stp_dither_add_channel(v, cols.p.y, STP_ECOLOR_Y, 0);
if (cols.p.Y)
stp_dither_add_channel(v, cols.p.Y, STP_ECOLOR_Y, 1);
privdata.hoffset = left;
privdata.ydpi = ydpi;
privdata.model = model;
privdata.width = out_width;
privdata.xdpi = xdpi;
privdata.physical_xdpi = physical_xdpi;
for (y = 0; y < out_height; y ++)
{
int duplicate_line = 1;
if (errline != errlast)
{
errlast = errline;
duplicate_line = 0;
if (stp_color_get_row(v, image, errline, &zero_mask))
{
status = 2;
break;
}
}
stp_dither(v, y, duplicate_line, zero_mask, NULL);
stp_write_weave(v, (unsigned char **)cols.v);
errval += errmod;
errline += errdiv;
if (errval >= out_height)
{
errval -= out_height;
errline ++;
}
}
stp_image_conclude(image);
stp_flush_all(v);
lexmark_deinit_printer(v, caps);
if (privdata.outbuf != NULL) {
stp_free(privdata.outbuf);
}
for (i = 0; i < NCHANNELS; i++)
if (cols.v[i])
stp_free(cols.v[i]);
#ifdef DEBUG
lex_tmp_file_deinit(dbgfileprn);
#endif
return status;
}
static int
lexmark_print(const stp_vars_t *v, stp_image_t *image)
{
int status;
stp_vars_t *nv = stp_vars_create_copy(v);
stp_prune_inactive_options(nv);
status = lexmark_do_print(nv, image);
stp_vars_destroy(nv);
return status;
}
static const stp_printfuncs_t print_lexmark_printfuncs =
{
lexmark_list_parameters,
lexmark_parameters,
stp_default_media_size,
lexmark_imageable_area,
lexmark_limit,
lexmark_print,
lexmark_describe_resolution,
lexmark_describe_output,
stp_verify_printer_params,
NULL,
NULL
};
static unsigned char *
lexmark_init_line(int mode, unsigned char *prnBuf,
int pass_length,
int offset,
int width, int direction,
const lexmark_inkparam_t *ink_parameter,
const lexmark_cap_t * caps
)
{
int pos1 = 0;
int pos2 = 0;
int abspos, disp;
int hend = 0;
int header_size = 0;
switch(caps->model) {
case m_z52:
case m_z42:
if (caps->model == m_z52)
{
header_size = LXM_Z52_HEADERSIZE;
memcpy(prnBuf, outbufHeader_z52, header_size);
}
if (caps->model == m_z42)
{
header_size = LXM_Z42_HEADERSIZE;
memcpy(prnBuf, outbufHeader_z42, LXM_Z42_HEADERSIZE);
}
if ((mode & COLOR_MODE_K) || (mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM))) {
#ifdef DEBUG
stp_erprintf("set photo/black catridge \n");
#endif
prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_BLACK_PRINT;
if (direction) {
} else {
offset += ink_parameter->h_direction_offset;
}
} else {
#ifdef DEBUG
stp_erprintf("set color cartridge \n");
#endif
prnBuf[LX_Z52_COLOR_MODE_POS] = LX_Z52_COLOR_PRINT;
if (direction) {
offset += ink_parameter->h_catridge_offset;
} else {
offset += ink_parameter->h_catridge_offset + ink_parameter->h_direction_offset;
}
}
switch (mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_300_DPI;
break;
case PRINT_MODE_600:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_600_DPI;
break;
case PRINT_MODE_1200:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_1200_DPI;
break;
case PRINT_MODE_2400:
prnBuf[LX_Z52_RESOLUTION_POS] = LX_Z52_2400_DPI;
break;
}
if (direction) {
prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 1;
} else {
prnBuf[LX_Z52_PRINT_DIRECTION_POS] = 2;
}
prnBuf[13] = (unsigned char)((width) >> 8);
prnBuf[14] = (unsigned char)((width) & 0xFF);
prnBuf[15] =(unsigned char)(offset >> 8);
prnBuf[16] =(unsigned char)(offset & 0xFF);
if (caps->model == m_z42) {
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
hend = (width-1)*(2400/300);
break;
case PRINT_MODE_600:
hend = (width-1)*(2400/600);
break;
case PRINT_MODE_1200:
hend = (width-1)*(2400/1200);
break;
case PRINT_MODE_2400:
hend = (width-1)*(2400/2400);
break;
}
hend += offset;
prnBuf[17] = (unsigned char)(hend >> 8);
prnBuf[18] = (unsigned char)(hend & 0xFF);
prnBuf[10] = (pass_length==208 ? 0x1A : 0x18);
}
return prnBuf + header_size;
break;
case m_3200:
memcpy(prnBuf, outbufHeader_3200, LXM_3200_HEADERSIZE);
offset = (offset - 60) * 4;
if((mode & COLOR_MODE_K) ||
(mode & (COLOR_MODE_K | COLOR_MODE_LC | COLOR_MODE_LM)))
{
disp = LXM3200_LEFTOFFS;
prnBuf[2] = 0x00;
}
else
{
disp = LXM3200_RIGHTOFFS;
prnBuf[2] = 0x80;
}
if(pass_length == 208)
{
prnBuf[2] |= 0x10;
}
switch(mode & PRINT_MODE_MASK) {
case PRINT_MODE_300:
prnBuf[2] |= 0x20;
pos1 = offset + disp;
pos2 = offset + (width * 4) + disp;
break;
case PRINT_MODE_600:
prnBuf[2] |= 0x00;
pos1 = offset + disp;
pos2 = offset + (width * 2) + disp;
break;
case PRINT_MODE_1200:
prnBuf[2] |= 0x40;
pos1 = offset + disp;
pos2 = (offset + width) + disp;
break;
}
if(direction)
prnBuf[2] |= 0x01;
else
prnBuf[2] |= 0x00;
prnBuf[3] = (unsigned char)((width) >> 8);
prnBuf[4] = (unsigned char)((width) & 0xff);
prnBuf[21] = (unsigned char)(pos1 >> 8);
prnBuf[22] = (unsigned char)(pos1 & 0xFF);
abspos = ((((pos2 - 3600) >> 3) & 0xfff0) + 9);
prnBuf[5] = (abspos-lxm3200_headpos) >> 8;
prnBuf[6] = (abspos-lxm3200_headpos) & 0xff;
lxm3200_headpos = abspos;
if(LXM3200_RIGHTOFFS > 4816)
abspos = (((LXM3200_RIGHTOFFS - 4800) >> 3) & 0xfff0);
else
abspos = (((LXM3200_RIGHTOFFS - 3600) >> 3) & 0xfff0);
prnBuf[11] = (lxm3200_headpos-abspos) >> 8;
prnBuf[12] = (lxm3200_headpos-abspos) & 0xff;
lxm3200_headpos = abspos;
prnBuf[7] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[0]);
prnBuf[15] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[8]);
prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
return prnBuf + LXM_3200_HEADERSIZE;
break;
case m_lex7500:
stp_erprintf("Lexmark 7500 not supported !\n");
return NULL;
break;
}
return NULL;
}
typedef struct Lexmark_head_colors {
int v_start;
unsigned char *line;
int head_nozzle_start;
int head_nozzle_end;
int used_jets;
} Lexmark_head_colors;
static int
lexmark_write(const stp_vars_t *v,
unsigned char *prnBuf,
int *paperShift,
int direction,
int pass_length,
const lexmark_cap_t * caps,
const lexmark_inkparam_t *ink_parameter,
int xdpi,
int yCount,
Lexmark_head_colors *head_colors,
int length,
int mode,
int ydpi,
int width,
int offset,
int dmt)
{
unsigned char *tbits=NULL, *p=NULL;
int clen;
int x;
int y;
int dy;
int x1;
unsigned short pixelline;
unsigned int valid_bytes;
int xStart=0;
int xEnd=0;
int xIter=0;
int anyCol=0;
int colIndex;
int rwidth;
#ifdef DEBUG
stp_erprintf("pass length %d\n", pass_length);
#endif
if ((((width*caps->x_raster_res)/xdpi)+offset) > ((caps->max_paper_width*caps->x_raster_res)/72)) {
#ifdef DEBUG
stp_erprintf("!! Line too long !! reduce it from %d", width);
#endif
width = ((((caps->max_paper_width*caps->x_raster_res)/72) - offset)*xdpi)/caps->x_raster_res;
#ifdef DEBUG
stp_erprintf(" down to %d\n", width);
#endif
}
#ifdef DEBUG
stp_erprintf("lexmark: printer line initialized.\n");
#endif
if (direction) {
xStart = -get_lr_shift(mode);
xEnd = width-1;
xIter = 1;
rwidth = xEnd - xStart;
} else {
xStart = width-1;
xEnd = -get_lr_shift(mode);
rwidth = xStart - xEnd;
xIter = -1;
}
p = lexmark_init_line(mode, prnBuf, pass_length, offset, rwidth,
direction,
ink_parameter, caps);
#ifdef DEBUG
stp_erprintf("lexmark: xStart %d, xEnd %d, xIter %d.\n", xStart, xEnd, xIter);
#endif
yCount = 2;
for (x=xStart; x != xEnd; x+=xIter) {
int anyDots=0;
switch(caps->model) {
case m_z52:
tbits = p;
*(p++) = 0x3F;
tbits[1] = 0;
p++;
break;
case m_3200:
case m_z42:
tbits = p;
p += 4;
break;
case m_lex7500:
break;
}
pixelline =0;
valid_bytes = 0;
anyDots =0;
x1 = x+get_lr_shift(mode);
for (colIndex=0; colIndex < 3; colIndex++) {
for (dy=head_colors[colIndex].head_nozzle_start,y=head_colors[colIndex].v_start*yCount;
(dy < head_colors[colIndex].head_nozzle_end);
y+=yCount, dy++) {
if (head_colors[colIndex].line != NULL) {
pixelline = pixelline << 1;
if ((x >= 0) &&
((dy - head_colors[colIndex].head_nozzle_start) < (head_colors[colIndex].used_jets/2)))
pixelline = pixelline | ((head_colors[colIndex].line[(y*length)+(x/8)] >> (7-(x%8))) & 0x1);
pixelline = pixelline << 1;
if ((x1 < width) &&
(((dy - head_colors[colIndex].head_nozzle_start)+1) < (head_colors[colIndex].used_jets/2)))
pixelline = pixelline | ((head_colors[colIndex].line[(((yCount>>1)+y)*length)+ (x1/8)] >> (7-(x1%8))) & 0x1);
} else {
pixelline = pixelline << 2;
}
switch(caps->model) {
case m_z52:
if ((dy%8) == 7) {
anyDots |= pixelline;
if (pixelline) {
valid_bytes = valid_bytes >> 1;
*((p++)) = (unsigned char)(pixelline >> 8);
*((p++)) = (unsigned char)(pixelline & 0xff);
} else {
valid_bytes = valid_bytes >> 1;
valid_bytes |= 0x1000;
}
pixelline =0;
}
break;
case m_3200:
case m_z42:
if((dy % 4) == 3)
{
anyDots |= pixelline;
valid_bytes <<= 1;
if(pixelline)
*(p++) = (unsigned char)(pixelline & 0xff);
else
valid_bytes |= 0x01;
pixelline = 0;
}
break;
case m_lex7500:
break;
}
}
}
switch(caps->model) {
case m_z52:
if (pass_length != 208) {
valid_bytes = valid_bytes >> 1;
valid_bytes |= 0x1000;
}
tbits[0] = 0x20 | ((unsigned char)((valid_bytes >> 8) & 0x1f));
tbits[1] = (unsigned char)(valid_bytes & 0xff);
break;
case m_z42:
if ((p-tbits) & 1) *(p++)=0;
case m_3200:
tbits[0] = 0x80 | ((unsigned char)((valid_bytes >> 24) & 0x1f));
tbits[1] = (unsigned char)((valid_bytes >> 16) & 0xff);
tbits[2] = (unsigned char)((valid_bytes >> 8) & 0xff);
tbits[3] = (unsigned char)(valid_bytes & 0xff);
break;
case m_lex7500:
break;
}
if (anyDots) {
anyCol = 1;
} else {
#ifdef DEBUG
#endif
}
}
#ifdef DEBUG
stp_erprintf("lexmark: 4\n");
#endif
clen=((unsigned char *)p)-prnBuf;
switch(caps->model) {
case m_z52:
case m_z42:
prnBuf[IDX_SEQLEN] =(unsigned char)(clen >> 24);
prnBuf[IDX_SEQLEN+1] =(unsigned char)(clen >> 16);
prnBuf[IDX_SEQLEN+2] =(unsigned char)(clen >> 8);
prnBuf[IDX_SEQLEN+3]=(unsigned char)(clen & 0xFF);
break;
case m_3200:
prnBuf[18] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 16);
prnBuf[19] = (unsigned char)((clen - LXM_3200_HEADERSIZE) >> 8);
prnBuf[20] = (unsigned char)((clen - LXM_3200_HEADERSIZE) & 0xff);
prnBuf[23] = (unsigned char)lexmark_calc_3200_checksum(&prnBuf[16]);
break;
default:
break;
}
if (anyCol) {
paper_shift(v, (*paperShift), caps);
*paperShift=0;
stp_zfwrite((const char *)prnBuf,1,clen,v);
#ifdef DEBUG
lex_write_tmp_file(dbgfileprn, (void *)prnBuf,clen);
stp_erprintf("lexmark: line written.\n");
#endif
return 1;
} else {
#ifdef DEBUG
stp_erprintf("-- empty line\n");
#endif
return 0;
}
return 0;
}
#ifdef DEBUG
const stp_vars_t *lex_open_tmp_file() {
int i;
const stp_vars_t *ofile;
char tmpstr[256];
stp_erprintf(" create file !\n");
for (i=0, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r");
ofile != NULL;
i++, sprintf(tmpstr, "/tmp/xx%d.prn", i), ofile = fopen(tmpstr, "r")) {
if (ofile != NULL)
{
fclose(ofile);
}
}
stp_erprintf("Create file %s !\n", tmpstr);
ofile = fopen(tmpstr, "wb");
if (ofile == NULL)
{
stp_erprintf("Can't create file !\n");
stp_abort();
}
return ofile;
}
void lex_tmp_file_deinit(const stp_vars_t *file) {
stp_erprintf("Close file %lx\n", file);
fclose(file);
}
const stp_vars_t *lex_write_tmp_file(const stp_vars_t *ofile, void *data,int length) {
fwrite(data, 1, length, ofile);
}
#endif
static void
flush_pass(stp_vars_t *v, int passno, int vertical_subpass)
{
stp_lineoff_t *lineoffs = stp_get_lineoffsets_by_pass(v, passno);
stp_lineactive_t *lineactive = stp_get_lineactive_by_pass(v, passno);
const stp_linebufs_t *bufs = stp_get_linebases_by_pass(v, passno);
stp_pass_t *pass = stp_get_pass_by_pass(v, passno);
stp_linecount_t *linecount = stp_get_linecount_by_pass(v, passno);
lexm_privdata_weave *pd =
(lexm_privdata_weave *) stp_get_component_data(v, "Driver");
int width = pd->width;
int hoffset = pd->hoffset;
int model = pd->model;
int xdpi = pd->xdpi;
int ydpi = pd->ydpi;
int physical_xdpi = pd->physical_xdpi;
int lwidth = (width + (pd->horizontal_weave - 1)) / pd->horizontal_weave;
int microoffset = vertical_subpass & (pd->horizontal_weave - 1);
int prn_mode;
int j;
const lexmark_cap_t * caps= lexmark_get_model_capabilities(model);
int paperShift;
Lexmark_head_colors head_colors[3]={{0, NULL, 0, 64/2, 64},
{0, NULL, 64/2, 128/2, 64},
{0, NULL, 128/2, 192/2, 64}};
#ifdef DEBUG
stp_erprintf("Lexmark: flush_pass, here we are !\n");
stp_erprintf(" passno %i, pd->ncolors %i, width %d, lwidth %d, linecount k % d, linecount m % d, bitwidth %d\n",
passno, pd->ncolors, width, lwidth, pd->bitwidth);
stp_erprintf("microoffset %d, vertical_subpass %d, pd->horizontal_weave %d\n", microoffset,vertical_subpass, pd->horizontal_weave);
stp_erprintf("Lexmark: last_pass_offset %d, logicalpassstart %d\n", pd->last_pass_offset, pass->logicalpassstart);
stp_erprintf("Lexmark: vertical adapt: caps->y_raster_res %d, ydpi %d, \n", caps->y_raster_res, ydpi);
#endif
if (1) {
#ifdef DEBUG
stp_erprintf("1\n");
stp_erprintf("\n");
stp_erprintf("lineoffs[0].v[j] %d\n", lineoffs[0].v[0]);
stp_erprintf("lineoffs[0].v[j] %d\n", lineoffs[0].v[1]);
#endif
switch (physical_xdpi) {
case 300:
prn_mode = PRINT_MODE_300;
break;
case 600:
prn_mode = PRINT_MODE_600;
break;
case 1200:
prn_mode = PRINT_MODE_1200;
break;
default:
#ifdef DEBUG
stp_erprintf("Eror: Unsupported phys resolution (%d)\n", physical_xdpi);
#endif
return;
break;
}
paperShift = (pass->logicalpassstart - pd->last_pass_offset) * (caps->y_raster_res/ydpi);
if ((STP_ECOLOR_C < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_C] > 0))
{
head_colors[0].line = bufs[0].v[STP_ECOLOR_C];
head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_C];
}
else
{
head_colors[0].line = NULL;
head_colors[0].used_jets = 0;
}
if ((STP_ECOLOR_M < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_M] > 0))
{
head_colors[1].line = bufs[0].v[STP_ECOLOR_M];
head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_M];
}
else
{
head_colors[1].line = 0;
head_colors[1].used_jets = 0;
}
if ((STP_ECOLOR_Y < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_Y] > 0))
{
head_colors[2].line = bufs[0].v[STP_ECOLOR_Y];
head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_Y];
}
else
{
head_colors[2].line = 0;
head_colors[2].used_jets = 0;
}
if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
#ifdef DEBUG
stp_erprintf("lexmark_write: lwidth %d\n", lwidth);
#endif
lexmark_write(v,
pd->outbuf,
&paperShift,
pd->direction,
pd->jets,
caps,
pd->ink_parameter,
xdpi,
2,
head_colors,
(lwidth+7)/8,
prn_mode | COLOR_MODE_C | COLOR_MODE_Y | COLOR_MODE_M,
ydpi,
lwidth,
hoffset+microoffset,
0 );
if (pd->bidirectional)
pd->direction = (pd->direction +1) & 1;
}
if (pd->jets != 208)
{
if ((STP_ECOLOR_LC < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LC] > 0))
{
head_colors[0].line = bufs[0].v[STP_ECOLOR_LC];
head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_LC];
}
else
{
head_colors[0].line = 0;
head_colors[0].used_jets = 0;
}
if ((STP_ECOLOR_LM < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_LM] > 0))
{
head_colors[1].line = bufs[0].v[STP_ECOLOR_LM];
head_colors[1].used_jets = linecount[0].v[STP_ECOLOR_LM];
}
else
{
head_colors[1].line = 0;
head_colors[1].used_jets = 0;
}
if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
{
head_colors[2].line = bufs[0].v[STP_ECOLOR_K];
head_colors[2].used_jets = linecount[0].v[STP_ECOLOR_K];
}
else
{
head_colors[2].line = 0;
head_colors[2].used_jets = 0;
}
}
else
{
if ((STP_ECOLOR_K < pd->ncolors) && (lineactive[0].v[STP_ECOLOR_K] > 0))
{
head_colors[0].line = bufs[0].v[STP_ECOLOR_K];
head_colors[0].used_jets = linecount[0].v[STP_ECOLOR_K];
head_colors[0].head_nozzle_start = 0;
head_colors[0].head_nozzle_end = pd->jets/2;
head_colors[2].line = NULL;
head_colors[2].used_jets = 0;
head_colors[2].head_nozzle_start = 0;
head_colors[2].head_nozzle_end = 0;
head_colors[1].line = NULL;
head_colors[1].used_jets = 0;
head_colors[1].head_nozzle_start = 0;
head_colors[1].head_nozzle_end = 0;
}
else
{
head_colors[2].line = NULL;
head_colors[2].used_jets = 0;
head_colors[2].head_nozzle_start = 0;
head_colors[2].head_nozzle_end = 0;
head_colors[1].line = NULL;
head_colors[1].used_jets = 0;
head_colors[1].head_nozzle_start = 0;
head_colors[1].head_nozzle_end = 0;
head_colors[0].line = NULL;
head_colors[0].used_jets = 0;
head_colors[0].head_nozzle_start = 0;
head_colors[0].head_nozzle_end = 0;
}
}
if ((head_colors[0].line != 0) || (head_colors[1].line != 0) || (head_colors[2].line != 0)) {
lexmark_write(v,
pd->outbuf,
&paperShift,
pd->direction,
pd->jets,
caps,
pd->ink_parameter,
xdpi,
2,
head_colors,
(lwidth+7)/8,
prn_mode | COLOR_MODE_LC | COLOR_MODE_LM | COLOR_MODE_K,
ydpi,
lwidth,
hoffset+microoffset,
0 );
if (pd->bidirectional)
{
pd->direction = (pd->direction +1) & 1;
}
}
pd->last_pass_offset = pass->logicalpassstart - (paperShift / (caps->y_raster_res/ydpi));
}
for (j = 0; j < pd->ncolors; j++)
{
lineoffs[0].v[j] = 0;
linecount[0].v[j] = 0;
}
#ifdef DEBUG
stp_erprintf("lexmark_write finished\n");
#endif
}
#ifdef DEBUG
static void testprint(testdata *td)
{
int icol, i;
char dummy1[256], dummy2[256];
lexmark_linebufs_t linebufs;
for (i=0; i < (sizeof(linebufs.v)/sizeof(linebufs.v[0])); i++) {
linebufs.v[i] = NULL;
}
td->ifile = fopen("/t1.ppm", "rb");
if (td->ifile != NULL) {
fscanf(td->ifile, "%[^{]{%[^\"]\"%d %d %d %d\",", dummy1, dummy2, &(td->x), &(td->y), &(td->cols), &(td->deep));
td->cols -= 1;
td->input_line = (char *)stp_malloc(td->x+10);
stp_erprintf("<%s> <%s>\n", dummy1, dummy2);
stp_erprintf("%d %d %d %d\n", td->x, td->y, td->cols, td->deep);
if (td->cols > 16) {
stp_erprintf("too many colors !!\n");
return;
}
fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, dummy2, dummy2);
for (icol=0; icol < td->cols; icol++) {
fscanf(td->ifile, "%[^\"]\"%c c %[^\"]\",", dummy1, &(td->colchar[icol]), dummy2);
stp_erprintf("colchar %d <%c>\n", i, td->colchar[icol]);
}
if (td->cols > 5) {
td->cols = 7;
for (icol=0; icol < td->cols; icol++) {
linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8);
}
} else if (td->cols > 4) {
td->cols = 5;
for (icol=0; icol < td->cols; icol++) {
linebufs.v[icol] = (char *)stp_malloc((td->x+7)/8);
}
} else {
td->cols = 1;
linebufs.v[0] = (char *)stp_malloc((td->x+7)/8);
}
} else {
stp_erprintf("can't open file !\n");
}
}
static void readtestprintline(testdata *td, lexmark_linebufs_t *linebufs)
{
char dummy1[256];
int icol, ix;
stp_erprintf("start readtestprintline\n");
for (icol=0; icol < 7; icol++) {
if (linebufs->v[icol] != NULL) {
memset(linebufs->v[icol], 0, (td->x+7)/8);
}
}
stp_erprintf("1 readtestprintline cols %d\n", td->cols);
fscanf(td->ifile, "%[^\"]\"%[^\"]\",", dummy1, td->input_line);
for (icol=0; icol < td->cols; icol++) {
for (ix=0; ix < td->x; ix++) {
if (td->input_line[ix] == td->colchar[icol]) {
if (icol != 0) {
linebufs->v[icol-1][ix/8] |= 1 << (ix%8);
} else {
linebufs->p.y[ix/8] |= 1 << (ix%8);
linebufs->p.m[ix/8] |= 1 << (ix%8);
linebufs->p.c[ix/8] |= 1 << (ix%8);
}
}
}
}
}
#endif
static stp_family_t print_lexmark_module_data =
{
&print_lexmark_printfuncs,
NULL
};
static int
print_lexmark_module_init(void)
{
return stp_family_register(print_lexmark_module_data.printer_list);
}
static int
print_lexmark_module_exit(void)
{
return stp_family_unregister(print_lexmark_module_data.printer_list);
}
#define stp_module_version print_lexmark_LTX_stp_module_version
#define stp_module_data print_lexmark_LTX_stp_module_data
stp_module_version_t stp_module_version = {0, 0};
stp_module_t stp_module_data =
{
"lexmark",
VERSION,
"Lexmark family driver",
STP_MODULE_CLASS_FAMILY,
NULL,
print_lexmark_module_init,
print_lexmark_module_exit,
(void *) &print_lexmark_module_data
};