diff options
Diffstat (limited to 'src/main/print-dyesub.c')
-rw-r--r-- | src/main/print-dyesub.c | 10291 |
1 files changed, 10291 insertions, 0 deletions
diff --git a/src/main/print-dyesub.c b/src/main/print-dyesub.c new file mode 100644 index 0000000..70fcc39 --- /dev/null +++ b/src/main/print-dyesub.c @@ -0,0 +1,10291 @@ +/* + * + * Print plug-in DyeSub driver (formerly Olympus driver) for Gutenprint + * + * Copyright 2003-2006 Michael Mraka (Michael.Mraka@linux.cz) + * + * Copyright 2007-2018 Solomon Peachy (pizza@shaftnet.org) + * + * The plug-in is based on the code of the RAW plugin for the GIMP of + * Michael Sweet (mike@easysw.com) and Robert Krawitz (rlk@alum.mit.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +/* + * This file must include only standard C header files. The core code must + * compile on generic platforms that don't support glib, gimp, gtk, etc. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gutenprint/gutenprint.h> +#include "gutenprint-internal.h" +#include <gutenprint/gutenprint-intl-internal.h> +#include <string.h> +#include <stdio.h> +#include <limits.h> +#include <time.h> /* For strftime() and localtime_r() */ +#ifdef __GNUC__ +#define inline __inline__ +#endif + +//#define S6145_YMC + +#define DYESUB_FEATURE_NONE 0x00000000 +#define DYESUB_FEATURE_FULL_WIDTH 0x00000001 +#define DYESUB_FEATURE_FULL_HEIGHT 0x00000002 +#define DYESUB_FEATURE_BLOCK_ALIGN 0x00000004 +#define DYESUB_FEATURE_BORDERLESS 0x00000008 +#define DYESUB_FEATURE_WHITE_BORDER 0x00000010 +#define DYESUB_FEATURE_PLANE_INTERLACE 0x00000020 +#define DYESUB_FEATURE_PLANE_LEFTTORIGHT 0x00000040 +#define DYESUB_FEATURE_ROW_INTERLACE 0x00000080 +#define DYESUB_FEATURE_DUPLEX 0x00000800 +#define DYESUB_FEATURE_MONOCHROME 0x00001000 +#define DYESUB_FEATURE_NATIVECOPIES 0x00002000 + +#define DYESUB_PORTRAIT 0 +#define DYESUB_LANDSCAPE 1 + +#define OP_JOB_START 1 +#define OP_JOB_PRINT 2 +#define OP_JOB_END 4 + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif /* !MIN */ +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif /* !MAX */ +#define PX(pt,dpi) (int)(((stp_dimension_t)(pt) * (stp_resolution_t)(dpi) / (stp_resolution_t)72) + 0.5f) +#define PT(px,dpi) ((stp_resolution_t)(px) * (stp_resolution_t)72 / (stp_dimension_t)(dpi)) +#define PT1 PT +#define LIST(list_t, list_name, items_t, items_name) \ + static const list_t list_name = \ + { \ + items_name, sizeof(items_name) / sizeof(items_t) \ + } + +#define MAX_INK_CHANNELS 3 +#define SIZE_THRESHOLD 6 + +/* + * Random implementation from POSIX.1-2001 to yield reproducible results. + */ +typedef struct +{ + const char *output_type; + int output_channels; + const char *name; + const char *channel_order; +} ink_t; + +typedef struct { + const ink_t *item; + size_t n_items; +} ink_list_t; + +typedef struct { + const char* name; + stp_resolution_t w_dpi; + stp_resolution_t h_dpi; +} dyesub_resolution_t; + +typedef struct { + const dyesub_resolution_t *item; + size_t n_items; +} dyesub_resolution_list_t; + +typedef struct { + stp_papersize_t psize; + int print_mode; +} dyesub_pagesize_t; + +#define DEFINE_PAPER(__n, __t, __w, __h, __bl, __br, __bt, __bb, __pm) \ + { \ + .psize = { \ + .name = __n, \ + .text = N_(__t), \ + .width = __w, \ + .height = __h, \ + .top = __bt, \ + .left = __bl, \ + .bottom = __bb, \ + .right = __br, \ + .paper_unit = PAPERSIZE_ENGLISH_STANDARD, \ + .paper_size_type = PAPERSIZE_TYPE_STANDARD, \ + }, \ + .print_mode = __pm, \ + } + +#define DEFINE_PAPER_SIMPLE(__n, __t, __w, __h, __pm) \ + DEFINE_PAPER(__n, __t, __w, __h, 0, 0, 0, 0, __pm) + +typedef struct { + const dyesub_pagesize_t *item; + size_t n_items; +} dyesub_pagesize_list_t; + +typedef struct { + const char* res_name; + const char* pagesize_name; + int width_px; + int height_px; +} dyesub_printsize_t; + +typedef struct { + const dyesub_printsize_t *item; + size_t n_items; +} dyesub_printsize_list_t; + +typedef struct { + const char *name; + const char *text; + const stp_raw_t seq; +} overcoat_t; + +typedef struct { + const overcoat_t *item; + size_t n_items; +} overcoat_list_t; + +typedef struct { + const char* name; + const char* text; + const stp_raw_t seq; +} dyesub_media_t; + +typedef struct { + const dyesub_media_t *item; + size_t n_items; +} dyesub_media_list_t; + +typedef struct { + const char* name; + const char *text; +} dyesub_stringitem_t; + +typedef struct { + const dyesub_stringitem_t *item; + size_t n_items; +} dyesub_stringlist_t; + +/* Private data for some of the major dyesub driver families */ +typedef struct +{ + int multicut; + int nocutwaste; + const char *print_speed; /* DS820 only */ +} dnp_privdata_t; + +typedef struct +{ + int quality; + int finedeep; + int contrast; +} mitsu9550_privdata_t; + +typedef struct +{ + int quality; + int overcoat_offset; + int use_lut; + int sharpen; + int delay; + int deck; +} mitsu70x_privdata_t; + +typedef struct +{ + int sharpen; +} kodak9810_privdata_t; + +typedef struct +{ + int sharpen; + int matte_intensity; +} kodak8500_privdata_t; + +typedef struct +{ + int matte_intensity; + int dust_removal; +} shinko1245_privdata_t; + +typedef struct +{ + int clear_mem; + int cont_print; + int gamma; + int flags; + int comment; + int contrast; + int sharpen; + int brightness; + char usercomment[40]; + char commentbuf[19]; /* With one extra byte for null termination */ +} mitsu_p95d_privdata_t; + +typedef struct +{ + int resin_k; + int reject; + int colorsure; + int holokote; + int holokote_custom; + int holopatch; + int overcoat; + int overcoat_dpx; + const char *overcoat_hole; /* XXX TODO: add custom option? */ + const char *overcoat_hole_dpx; /* XXX TODO: add custom option? */ + int align_start; + int align_end; + int power_color; + int power_resin; + int power_overcoat; + int gamma; + int duplex; + char mag1[79]; /* Mag stripe row 1, 78 alphanumeric */ + char mag2[40]; /* Mag stripe row 2, 39 numeric */ + char mag3[107]; /* Mag stripe row 3, 106 numeric */ + int mag_coer; /* 1 = high, 0 = low */ +} magicard_privdata_t; + +/* Private data for dyesub driver as a whole */ +typedef struct +{ + stp_resolution_t w_dpi, h_dpi; + stp_dimension_t w_size, h_size; + char plane; + int block_min_w, block_min_h; + int block_max_w, block_max_h; + const char* pagesize; + const overcoat_t* overcoat; + const dyesub_media_t* media; + const char* slot; + int print_mode; + const char* duplex_mode; + int page_number; + int copies; + int horiz_offset; + union { + dnp_privdata_t dnp; + mitsu9550_privdata_t m9550; + mitsu70x_privdata_t m70x; + kodak9810_privdata_t k9810; + kodak8500_privdata_t k8500; + shinko1245_privdata_t s1245; + mitsu_p95d_privdata_t m95d; + magicard_privdata_t magicard; + } privdata; +} dyesub_privdata_t; + +typedef struct { + int out_channels; + int ink_channels; + const char *ink_order; + int byteswap; + int plane_interlacing; + int row_interlacing; + unsigned char empty_byte[MAX_INK_CHANNELS]; /* one for each color plane */ + unsigned short **image_data; + int outh_px, outw_px, outt_px, outb_px, outl_px, outr_px; + int imgh_px, imgw_px; + int prnh_px, prnw_px, prnt_px, prnb_px, prnl_px, prnr_px; + int print_mode; /* portrait or landscape */ + int image_rows; + int plane_lefttoright; +} dyesub_print_vars_t; + +typedef struct /* printer specific parameters */ +{ + int model; /* printer model number from printers.xml*/ + const ink_list_t *inks; + const dyesub_resolution_list_t *resolution; + const dyesub_pagesize_list_t *pages; + const dyesub_printsize_list_t *printsize; + int block_size; /* Really # of rows in a block */ + int features; + void (*printer_init_func)(stp_vars_t *); + void (*printer_end_func)(stp_vars_t *); + void (*plane_init_func)(stp_vars_t *); + void (*plane_end_func)(stp_vars_t *); + void (*block_init_func)(stp_vars_t *); + void (*block_end_func)(stp_vars_t *); + void (*adjust_curves)(stp_vars_t *); + const overcoat_list_t *overcoat; + const dyesub_media_list_t *media; + void (*job_start_func)(stp_vars_t *); + void (*job_end_func)(stp_vars_t *); + const stp_parameter_t *parameters; + int parameter_count; + int (*load_parameters)(const stp_vars_t *, const char *name, stp_parameter_t *); + int (*parse_parameters)(stp_vars_t *); +} dyesub_cap_t; + + +static int dyesub_feature(const dyesub_cap_t *caps, int feature); +static const dyesub_cap_t* dyesub_get_model_capabilities(const stp_vars_t *v, int model); +static const overcoat_t* dyesub_get_overcoat_pattern(stp_vars_t *v); +static const dyesub_media_t* dyesub_get_mediatype(stp_vars_t *v); +static void dyesub_nputc(stp_vars_t *v, char byte, int count); +static void dyesub_adjust_curve(stp_vars_t *v, + const char *color_adj, + const char *color_curve); + +static dyesub_privdata_t * +get_privdata(stp_vars_t *v) +{ + return (dyesub_privdata_t *) stp_get_component_data(v, "Driver"); +} + +static const ink_t cmy_inks[] = +{ + { "CMY", 3, "CMY", "\1\2\3" }, +}; + +LIST(ink_list_t, cmy_ink_list, ink_t, cmy_inks); + +static const ink_t ymc_inks[] = +{ + { "CMY", 3, "CMY", "\3\2\1" }, +}; + +LIST(ink_list_t, ymc_ink_list, ink_t, ymc_inks); + +static const ink_t rgb_inks[] = +{ + { "RGB", 3, "RGB", "\1\2\3" }, +}; + +LIST(ink_list_t, rgb_ink_list, ink_t, rgb_inks); + +static const ink_t bgr_inks[] = +{ + { "RGB", 3, "RGB", "\3\2\1" }, +}; + +LIST(ink_list_t, bgr_ink_list, ink_t, bgr_inks); + +static const ink_t w_inks[] = +{ + { "Whitescale", 1, "BW", "\1" }, +}; + +LIST(ink_list_t, w_ink_list, ink_t, w_inks); + +/* Olympus P-10 */ +static const dyesub_resolution_t res_310dpi[] = +{ + { "310x310", 310, 310}, +}; + +LIST(dyesub_resolution_list_t, res_310dpi_list, dyesub_resolution_t, res_310dpi); + +static const dyesub_pagesize_t p10_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1280,310), PT1(1848,310), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1144,310), PT1(1591,310), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, p10_page_list, dyesub_pagesize_t, p10_page); + +static const dyesub_printsize_t p10_printsize[] = +{ + { "310x310", "w288h432", 1280, 1848}, + { "310x310", "B7", 1144, 1591}, +}; + +LIST(dyesub_printsize_list_t, p10_printsize_list, dyesub_printsize_t, p10_printsize); + +static void p10_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\033R\033M\033S\2\033N\1\033D\1\033Y", 1, 15, v); + stp_write_raw(&(pd->overcoat->seq), v); /* overcoat */ + stp_zfwrite("\033Z\0", 1, 3, v); +} + +static void p10_printer_end_func(stp_vars_t *v) +{ + stp_zfwrite("\033P", 1, 2, v); +} + +static void p10_block_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zprintf(v, "\033T%c", pd->plane); + stp_put16_le(pd->block_min_w, v); + stp_put16_le(pd->block_min_h, v); + stp_put16_le(pd->block_max_w + 1, v); + stp_put16_le(pd->block_max_h + 1, v); +} + +static const overcoat_t p10_overcoat[] = +{ + {"Coated", N_("Coated"), {1, "\x00"}}, + {"None", N_("None"), {1, "\x02"}}, +}; + +LIST(overcoat_list_t, p10_overcoat_list, overcoat_t, p10_overcoat); + + +/* Olympus P-200 series */ +static const dyesub_resolution_t res_320dpi[] = +{ + { "320x320", 320, 320}, +}; + +LIST(dyesub_resolution_list_t, res_320dpi_list, dyesub_resolution_t, res_320dpi); + +static const dyesub_pagesize_t p200_page[] = +{ + DEFINE_PAPER( "ISOB7", "80x125mm", PT(960,320), PT(1280,320), 16, 17, 33, 33, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, p200_page_list, dyesub_pagesize_t, p200_page); + +static const dyesub_printsize_t p200_printsize[] = +{ + { "320x320", "ISOB7", 960, 1280}, +}; + +LIST(dyesub_printsize_list_t, p200_printsize_list, dyesub_printsize_t, p200_printsize); + +static void p200_printer_init_func(stp_vars_t *v) +{ + stp_zfwrite("S000001\0S010001\1", 1, 16, v); +} + +static void p200_plane_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zprintf(v, "P0%d9999", 3 - pd->plane+1 ); + stp_put32_be(pd->w_size * pd->h_size, v); +} + +static void p200_printer_end_func(stp_vars_t *v) +{ + stp_zprintf(v, "P000001\1"); +} + +static const char p200_adj_any[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.000000 0.039216 0.078431 0.117647 0.152941 0.192157 0.231373 0.266667\n" + "0.301961 0.341176 0.376471 0.411765 0.447059 0.482353 0.513725 0.549020\n" + "0.580392 0.615686 0.647059 0.678431 0.709804 0.741176 0.768627 0.796078\n" + "0.827451 0.854902 0.878431 0.905882 0.929412 0.949020 0.972549 0.988235\n" + "1.000000\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static void p200_adjust_curves(stp_vars_t *v) +{ + dyesub_adjust_curve(v, p200_adj_any, "CyanCurve"); + dyesub_adjust_curve(v, p200_adj_any, "MagentaCurve"); + dyesub_adjust_curve(v, p200_adj_any, "YellowCurve"); +} + +/* Olympus P-300 series */ +static const dyesub_resolution_t p300_res[] = +{ + { "306x306", 306, 306}, + { "153x153", 153, 153}, +}; + +LIST(dyesub_resolution_list_t, p300_res_list, dyesub_resolution_t, p300_res); + +static const dyesub_pagesize_t p300_page[] = +{ + DEFINE_PAPER( "A6", "A6", PT1(1024,306), PT1(1376,306), 28, 28, 48, 48, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, p300_page_list, dyesub_pagesize_t, p300_page); + +static const dyesub_printsize_t p300_printsize[] = +{ + { "306x306", "A6", 1024, 1376}, + { "153x153", "A6", 512, 688}, +}; + +LIST(dyesub_printsize_list_t, p300_printsize_list, dyesub_printsize_t, p300_printsize); + +static void p300_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\033\033\033C\033N\1\033F\0\1\033MS\xff\xff\xff" + "\033Z", 1, 19, v); + stp_put16_be(pd->w_dpi, v); + stp_put16_be(pd->h_dpi, v); +} + +static void p300_plane_end_func(stp_vars_t *v) +{ + const char *c = "CMY"; + dyesub_privdata_t *pd = get_privdata(v); + + stp_zprintf(v, "\033\033\033P%cS", c[pd->plane-1]); + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: p300_plane_end_func: %c\n", + c[pd->plane-1]); +} + +static void p300_block_init_func(stp_vars_t *v) +{ + const char *c = "CMY"; + dyesub_privdata_t *pd = get_privdata(v); + + stp_zprintf(v, "\033\033\033W%c", c[pd->plane-1]); + stp_put16_be(pd->block_min_h, v); + stp_put16_be(pd->block_min_w, v); + stp_put16_be(pd->block_max_h, v); + stp_put16_be(pd->block_max_w, v); + + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: p300_block_init_func: %d-%dx%d-%d\n", + pd->block_min_w, pd->block_max_w, + pd->block_min_h, pd->block_max_h); +} + +static const char p300_adj_cyan[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.078431 0.211765 0.250980 0.282353 0.309804 0.333333 0.352941 0.368627\n" + "0.388235 0.403922 0.427451 0.443137 0.458824 0.478431 0.498039 0.513725\n" + "0.529412 0.545098 0.556863 0.576471 0.592157 0.611765 0.627451 0.647059\n" + "0.666667 0.682353 0.701961 0.713725 0.725490 0.729412 0.733333 0.737255\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char p300_adj_magenta[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.047059 0.211765 0.250980 0.278431 0.305882 0.333333 0.349020 0.364706\n" + "0.380392 0.396078 0.415686 0.435294 0.450980 0.466667 0.482353 0.498039\n" + "0.513725 0.525490 0.541176 0.556863 0.572549 0.592157 0.611765 0.631373\n" + "0.650980 0.670588 0.694118 0.705882 0.721569 0.741176 0.745098 0.756863\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char p300_adj_yellow[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.047059 0.117647 0.203922 0.250980 0.274510 0.301961 0.321569 0.337255\n" + "0.352941 0.364706 0.380392 0.396078 0.407843 0.423529 0.439216 0.450980\n" + "0.466667 0.482353 0.498039 0.513725 0.533333 0.552941 0.572549 0.596078\n" + "0.615686 0.635294 0.650980 0.666667 0.682353 0.690196 0.701961 0.713725\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static void p300_adjust_curves(stp_vars_t *v) +{ + dyesub_adjust_curve(v, p300_adj_cyan, "CyanCurve"); + dyesub_adjust_curve(v, p300_adj_magenta, "MagentaCurve"); + dyesub_adjust_curve(v, p300_adj_yellow, "YellowCurve"); +} + +/* Olympus P-400 series */ +static const dyesub_resolution_t res_314dpi[] = +{ + { "314x314", 314, 314}, +}; + +LIST(dyesub_resolution_list_t, res_314dpi_list, dyesub_resolution_t, res_314dpi); + +static const dyesub_pagesize_t p400_page[] = +{ + DEFINE_PAPER( "A4", "A4", PT1(2400,314), PT1(3200,314), 22, 22, 54, 54, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10", "A5 wide", PT1(2000,314), PT1(2400,314), 58, 59, 84, 85, DYESUB_PORTRAIT), + DEFINE_PAPER( "C6", "2 Postcards (A4)", PT1(1328,314), PT1(1920,314), 9, 9, 9, 9, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, p400_page_list, dyesub_pagesize_t, p400_page); + +static const dyesub_printsize_t p400_printsize[] = +{ + { "314x314", "A4", 2400, 3200}, + { "314x314", "c8x10", 2000, 2400}, + { "314x314", "C6", 1328, 1920}, +}; + +LIST(dyesub_printsize_list_t, p400_printsize_list, dyesub_printsize_t, p400_printsize); + +static void p400_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int wide = (strcmp(pd->pagesize, "c8x10") == 0 + || strcmp(pd->pagesize, "C6") == 0); + + stp_zprintf(v, "\033ZQ"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033FP"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033ZF"); + stp_putc((wide ? '\x40' : '\x00'), v); dyesub_nputc(v, '\0', 60); + stp_zprintf(v, "\033ZS"); + if (wide) + { + stp_put16_be(pd->h_size, v); + stp_put16_be(pd->w_size, v); + } + else + { + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + } + dyesub_nputc(v, '\0', 57); + stp_zprintf(v, "\033ZP"); dyesub_nputc(v, '\0', 61); +} + +static void p400_plane_init_func(stp_vars_t *v) +{ + stp_zprintf(v, "\033ZC"); dyesub_nputc(v, '\0', 61); +} + +static void p400_plane_end_func(stp_vars_t *v) +{ + stp_zprintf(v, "\033P"); dyesub_nputc(v, '\0', 62); +} + +static void p400_block_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int wide = (strcmp(pd->pagesize, "c8x10") == 0 + || strcmp(pd->pagesize, "C6") == 0); + + stp_zprintf(v, "\033Z%c", '3' - pd->plane + 1); + if (wide) + { + stp_put16_be(pd->h_size - pd->block_max_h - 1, v); + stp_put16_be(pd->w_size - pd->block_max_w - 1, v); + stp_put16_be(pd->block_max_h - pd->block_min_h + 1, v); + stp_put16_be(pd->block_max_w - pd->block_min_w + 1, v); + } + else + { + stp_put16_be(pd->block_min_w, v); + stp_put16_be(pd->block_min_h, v); + stp_put16_be(pd->block_max_w - pd->block_min_w + 1, v); + stp_put16_be(pd->block_max_h - pd->block_min_h + 1, v); + } + dyesub_nputc(v, '\0', 53); +} + +static const char p400_adj_cyan[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.003922 0.031373 0.058824 0.090196 0.125490 0.156863 0.184314 0.219608\n" + "0.250980 0.278431 0.309804 0.341176 0.376471 0.403922 0.439216 0.470588\n" + "0.498039 0.517647 0.533333 0.545098 0.564706 0.576471 0.596078 0.615686\n" + "0.627451 0.647059 0.658824 0.678431 0.690196 0.705882 0.721569 0.737255\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char p400_adj_magenta[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.003922 0.031373 0.062745 0.098039 0.125490 0.156863 0.188235 0.215686\n" + "0.250980 0.282353 0.309804 0.345098 0.376471 0.407843 0.439216 0.470588\n" + "0.501961 0.521569 0.549020 0.572549 0.592157 0.619608 0.643137 0.662745\n" + "0.682353 0.713725 0.737255 0.756863 0.784314 0.807843 0.827451 0.850980\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char p400_adj_yellow[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.003922 0.027451 0.054902 0.090196 0.121569 0.156863 0.184314 0.215686\n" + "0.250980 0.282353 0.309804 0.345098 0.372549 0.400000 0.435294 0.466667\n" + "0.498039 0.525490 0.552941 0.580392 0.607843 0.631373 0.658824 0.678431\n" + "0.698039 0.725490 0.760784 0.784314 0.811765 0.839216 0.866667 0.890196\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static void p400_adjust_curves(stp_vars_t *v) +{ + dyesub_adjust_curve(v, p400_adj_cyan, "CyanCurve"); + dyesub_adjust_curve(v, p400_adj_magenta, "MagentaCurve"); + dyesub_adjust_curve(v, p400_adj_yellow, "YellowCurve"); +} + +/* Olympus P-440 series */ +static const dyesub_pagesize_t p440_page[] = +{ + DEFINE_PAPER( "A4", "A4", PT1(2508,314), PT1(3200,314), 10, 9, 54, 54, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10", "A5 wide", PT1(2000,314), PT1(2508,314), 58, 59, 72, 72, DYESUB_PORTRAIT), + DEFINE_PAPER( "C6", "2 Postcards (A4)", PT1(1328,314), PT1(1920,314), 9, 9, 9, 9, DYESUB_PORTRAIT), + DEFINE_PAPER( "w255h581", "A6 wide", PT1(892,314), PT1(2320,314), 25, 25, 25, 24, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, p440_page_list, dyesub_pagesize_t, p440_page); + +static const dyesub_printsize_t p440_printsize[] = +{ + { "314x314", "A4", 2508, 3200}, + { "314x314", "c8x10", 2000, 2508}, + { "314x314", "C6", 1328, 1920}, + { "314x314", "w255h581", 892, 2320}, +}; + +LIST(dyesub_printsize_list_t, p440_printsize_list, dyesub_printsize_t, p440_printsize); + +static void p440_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int wide = strcmp(pd->pagesize, "A4") != 0; + + stp_zprintf(v, "\033FP"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033Y"); + stp_write_raw(&(pd->overcoat->seq), v); /* overcoat */ + dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033FC"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033ZF"); + stp_putc((wide ? '\x40' : '\x00'), v); dyesub_nputc(v, '\0', 60); + stp_zprintf(v, "\033N\1"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033ZS"); + if (wide) + { + stp_put16_be(pd->h_size, v); + stp_put16_be(pd->w_size, v); + } + else + { + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + } + dyesub_nputc(v, '\0', 57); + if (strcmp(pd->pagesize, "C6") == 0) + { + stp_zprintf(v, "\033ZC"); dyesub_nputc(v, '\0', 61); + } +} + +static void p440_printer_end_func(stp_vars_t *v) +{ + stp_zprintf(v, "\033P"); dyesub_nputc(v, '\0', 62); +} + +static void p440_block_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int wide = strcmp(pd->pagesize, "A4") != 0; + + stp_zprintf(v, "\033ZT"); + if (wide) + { + stp_put16_be(pd->h_size - pd->block_max_h - 1, v); + stp_put16_be(pd->w_size - pd->block_max_w - 1, v); + stp_put16_be(pd->block_max_h - pd->block_min_h + 1, v); + stp_put16_be(pd->block_max_w - pd->block_min_w + 1, v); + } + else + { + stp_put16_be(pd->block_min_w, v); + stp_put16_be(pd->block_min_h, v); + stp_put16_be(pd->block_max_w - pd->block_min_w + 1, v); + stp_put16_be(pd->block_max_h - pd->block_min_h + 1, v); + } + dyesub_nputc(v, '\0', 53); +} + +static void p440_block_end_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int pad = (64 - (((pd->block_max_w - pd->block_min_w + 1) + * (pd->block_max_h - pd->block_min_h + 1) * 3) % 64)) % 64; + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub: max_x %d min_x %d max_y %d min_y %d\n", + pd->block_max_w, pd->block_min_w, + pd->block_max_h, pd->block_min_h); + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: olympus-p440 padding=%d\n", pad); + dyesub_nputc(v, '\0', pad); +} + + +/* Olympus P-S100 */ +static const dyesub_pagesize_t ps100_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1254,306), PT1(1808,306), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1120,306), PT1(1554,306), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, ps100_page_list, dyesub_pagesize_t, ps100_page); + +static const dyesub_printsize_t ps100_printsize[] = +{ + { "306x306", "w288h432", 1254, 1808}, + { "306x306", "B7", 1120, 1554}, +}; + +LIST(dyesub_printsize_list_t, ps100_printsize_list, dyesub_printsize_t, ps100_printsize); + +static void ps100_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zprintf(v, "\033U"); dyesub_nputc(v, '\0', 62); + + /* stp_zprintf(v, "\033ZC"); dyesub_nputc(v, '\0', 61); */ + + stp_zprintf(v, "\033W"); dyesub_nputc(v, '\0', 62); + + stp_zfwrite("\x30\x2e\x00\xa2\x00\xa0\x00\xa0", 1, 8, v); + stp_put16_be(pd->h_size, v); /* paper height (px) */ + stp_put16_be(pd->w_size, v); /* paper width (px) */ + dyesub_nputc(v, '\0', 3); + stp_putc(pd->copies, v); /* number of copies */ + dyesub_nputc(v, '\0', 8); + stp_putc('\1', v); + dyesub_nputc(v, '\0', 15); + stp_putc('\6', v); + dyesub_nputc(v, '\0', 23); + + stp_zfwrite("\033ZT\0", 1, 4, v); + stp_put16_be(0, v); /* image width offset (px) */ + stp_put16_be(0, v); /* image height offset (px) */ + stp_put16_be(pd->w_size, v); /* image width (px) */ + stp_put16_be(pd->h_size, v); /* image height (px) */ + dyesub_nputc(v, '\0', 52); +} + +static void ps100_printer_end_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int pad = (64 - (((pd->block_max_w - pd->block_min_w + 1) + * (pd->block_max_h - pd->block_min_h + 1) * 3) % 64)) % 64; + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub: max_x %d min_x %d max_y %d min_y %d\n", + pd->block_max_w, pd->block_min_w, + pd->block_max_h, pd->block_min_h); + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: olympus-ps100 padding=%d\n", pad); + dyesub_nputc(v, '\0', pad); /* padding to 64B blocks */ + + stp_zprintf(v, "\033PY"); dyesub_nputc(v, '\0', 61); + stp_zprintf(v, "\033u"); dyesub_nputc(v, '\0', 62); +} + + +/* Canon CP-10 */ +static const dyesub_resolution_t res_300dpi[] = +{ + { "300x300", 300, 300}, +}; + +LIST(dyesub_resolution_list_t, res_300dpi_list, dyesub_resolution_t, res_300dpi); + +static const dyesub_pagesize_t cp10_page[] = +{ + DEFINE_PAPER( "w155h244", "Card 54x86mm", PT1(662,300), PT1(1040,300), 6, 6, 29, 29, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, cp10_page_list, dyesub_pagesize_t, cp10_page); + +static const dyesub_printsize_t cp10_printsize[] = +{ + { "300x300", "w155h244", 662, 1040}, +}; + +LIST(dyesub_printsize_list_t, cp10_printsize_list, dyesub_printsize_t, cp10_printsize); + +/* Canon CP-100 series */ +static const dyesub_pagesize_t cpx00_page[] = +{ + DEFINE_PAPER( "Postcard", "Postcard 100x148mm", PT1(1232,300), PT1(1808,300), 13, 13, 16, 19, DYESUB_PORTRAIT), + DEFINE_PAPER( "w253h337", "CP_L 89x119mm", PT1(1100,300), PT1(1456,300), 13, 13, 15, 15, DYESUB_PORTRAIT), + DEFINE_PAPER( "w155h244", "Card 54x86mm", PT1(672,300), PT1(1040,300), 13, 13, 15, 15, DYESUB_LANDSCAPE), +}; + +LIST(dyesub_pagesize_list_t, cpx00_page_list, dyesub_pagesize_t, cpx00_page); + +static const dyesub_printsize_t cpx00_printsize[] = +{ + { "300x300", "Postcard", 1232, 1808}, + { "300x300", "w253h337", 1100, 1456}, + { "300x300", "w155h244", 672, 1040}, +}; + +LIST(dyesub_printsize_list_t, cpx00_printsize_list, dyesub_printsize_t, cpx00_printsize); + +static void cp10_printer_init_func(stp_vars_t *v) +{ + stp_put16_be(0x4000, v); + dyesub_nputc(v, '\0', 10); +} + +static void cpx00_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? '\1' : + (strcmp(pd->pagesize, "w253h337") == 0 ? '\2' : + (strcmp(pd->pagesize, "w155h244") == 0 ? + (strcmp(stp_get_driver(v),"canon-cp10") == 0 ? + '\0' : '\3' ) : + (strcmp(pd->pagesize, "w283h566") == 0 ? '\4' : + '\1' )))); + + stp_put16_be(0x4000, v); + stp_putc('\0', v); + stp_putc(pg, v); + dyesub_nputc(v, '\0', 8); +} + +static void cpx00_plane_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_put16_be(0x4001, v); + stp_putc(3 - pd->plane, v); + stp_putc('\0', v); + stp_put32_le(pd->w_size * pd->h_size, v); + dyesub_nputc(v, '\0', 4); +} + +static const char cpx00_adj_cyan[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.000000 0.035294 0.070588 0.101961 0.117647 0.168627 0.180392 0.227451\n" + "0.258824 0.286275 0.317647 0.341176 0.376471 0.411765 0.427451 0.478431\n" + "0.505882 0.541176 0.576471 0.611765 0.654902 0.678431 0.705882 0.737255\n" + "0.764706 0.792157 0.811765 0.839216 0.862745 0.894118 0.909804 0.925490\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char cpx00_adj_magenta[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.011765 0.019608 0.035294 0.047059 0.054902 0.101961 0.133333 0.156863\n" + "0.192157 0.235294 0.274510 0.321569 0.360784 0.403922 0.443137 0.482353\n" + "0.521569 0.549020 0.584314 0.619608 0.658824 0.705882 0.749020 0.792157\n" + "0.831373 0.890196 0.933333 0.964706 0.988235 0.992157 0.992157 0.996078\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char cpx00_adj_yellow[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"32\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.003922 0.015686 0.015686 0.023529 0.027451 0.054902 0.094118 0.129412\n" + "0.180392 0.219608 0.250980 0.286275 0.317647 0.341176 0.388235 0.427451\n" + "0.470588 0.509804 0.552941 0.596078 0.627451 0.682353 0.768627 0.796078\n" + "0.890196 0.921569 0.949020 0.968627 0.984314 0.992157 0.992157 1.000000\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static void cpx00_adjust_curves(stp_vars_t *v) +{ + dyesub_adjust_curve(v, cpx00_adj_cyan, "CyanCurve"); + dyesub_adjust_curve(v, cpx00_adj_magenta, "MagentaCurve"); + dyesub_adjust_curve(v, cpx00_adj_yellow, "YellowCurve"); +} + +/* Canon CP-220 series */ +static const dyesub_pagesize_t cp220_page[] = +{ + DEFINE_PAPER( "Postcard", "Postcard 100x148mm", PT1(1232,300), PT1(1808,300), 13, 13, 16, 19, DYESUB_PORTRAIT), + DEFINE_PAPER( "w253h337", "CP_L 89x119mm", PT1(1100,300), PT1(1456,300), 13, 13, 15, 15, DYESUB_PORTRAIT), + DEFINE_PAPER( "w155h244", "Card 54x86mm", PT1(672,300), PT1(1040,300), 13, 13, 15, 15, DYESUB_LANDSCAPE), + DEFINE_PAPER( "w283h566", "Wide 100x200mm", PT1(1232,300), PT1(2416,300), 13, 13, 20, 20, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, cp220_page_list, dyesub_pagesize_t, cp220_page); + +static const dyesub_printsize_t cp220_printsize[] = +{ + { "300x300", "Postcard", 1232, 1808}, + { "300x300", "w253h337", 1100, 1456}, + { "300x300", "w155h244", 672, 1040}, + { "300x300", "w283h566", 1232, 2416}, +}; + +LIST(dyesub_printsize_list_t, cp220_printsize_list, dyesub_printsize_t, cp220_printsize); + +/* Canon SELPHY CP790 */ +static void cp790_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? '\0' : + (strcmp(pd->pagesize, "w253h337") == 0 ? '\1' : + (strcmp(pd->pagesize, "w155h244") == 0 ? '\2' : + (strcmp(pd->pagesize, "w283h566") == 0 ? '\3' : + '\0' )))); + + stp_put16_be(0x4000, v); + stp_putc(pg, v); + stp_putc('\0', v); + dyesub_nputc(v, '\0', 8); + stp_put32_le(pd->w_size * pd->h_size, v); +} + +/* Canon SELPHY ES series */ +static void es1_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x11 : + (strcmp(pd->pagesize, "w253h337") == 0 ? 0x12 : + (strcmp(pd->pagesize, "w155h244") == 0 ? 0x13 : 0x11))); + + stp_put16_be(0x4000, v); + stp_putc(0x10, v); /* 0x20 for P-BW */ + stp_putc(pg, v); + dyesub_nputc(v, '\0', 8); +} + +static void es1_plane_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + unsigned char plane = 0; + + switch (pd->plane) { + case 3: /* Y */ + plane = 0x01; + break; + case 2: /* M */ + plane = 0x03; + break; + case 1: /* C */ + plane = 0x07; + break; + } + + stp_put16_be(0x4001, v); + stp_putc(0x1, v); /* 0x02 for P-BW */ + stp_putc(plane, v); + stp_put32_le(pd->w_size * pd->h_size, v); + dyesub_nputc(v, '\0', 4); +} + +static void es2_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg2 = 0x0; + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x1: + (strcmp(pd->pagesize, "w253h337") == 0 ? 0x2 : + (strcmp(pd->pagesize, "w155h244") == 0 ? 0x3 : 0x1))); + + if (pg == 0x03) + pg2 = 0x01; + + stp_put16_be(0x4000, v); + stp_putc(pg, v); + stp_putc(0x0, v); + + stp_putc(0x2, v); + dyesub_nputc(v, 0x0, 2); + stp_putc(0x0, v); /* 0x1 for P-BW */ + + dyesub_nputc(v, 0x0, 3); + stp_putc(pg2, v); + stp_put32_le(pd->w_size * pd->h_size, v); +} + +static void es2_plane_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_put16_be(0x4001, v); + stp_putc(4 - pd->plane, v); + stp_putc(0x0, v); + dyesub_nputc(v, '\0', 8); +} + +static void es3_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x1: + (strcmp(pd->pagesize, "w253h337") == 0 ? 0x2 : + (strcmp(pd->pagesize, "w155h244") == 0 ? 0x3 : 0x1))); + + /* We also have Pg and Ps (Gold/Silver) papers on the ES3/30/40 */ + + stp_put16_be(0x4000, v); + stp_putc(pg, v); + stp_putc(0x0, v); /* 0x1 for P-BW */ + dyesub_nputc(v, 0x0, 8); + stp_put32_le(pd->w_size * pd->h_size, v); +} + +static void es3_printer_end_func(stp_vars_t *v) +{ + stp_put16_be(0x4020, v); + dyesub_nputc(v, 0x0, 10); +} + +static void es40_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x0: + (strcmp(pd->pagesize, "w253h337") == 0 ? 0x1 : + (strcmp(pd->pagesize, "w155h244") == 0 ? 0x2 : 0x0))); + + /* We also have Pg and Ps (Gold/Silver) papers on the ES3/30/40 */ + + stp_put16_be(0x4000, v); + stp_putc(pg, v); + stp_putc(0x0, v); /* 0x1 for P-BW */ + dyesub_nputc(v, 0x0, 8); + + stp_put32_le(pd->w_size * pd->h_size, v); +} + +/* Canon SELPHY CP900 */ +static void cp900_printer_end_func(stp_vars_t *v) +{ + dyesub_nputc(v, 0x0, 4); +} + +/* Canon CP820/CP910/CP1000/CP1200 and beynod */ +static const dyesub_pagesize_t cp910_page[] = +{ + DEFINE_PAPER( "Postcard", "Postcard 100x148mm", PT1(1248,300), PT1(1872,300), 13, 13, 16, 19, DYESUB_PORTRAIT), + DEFINE_PAPER( "w253h337", "CP_L 89x119mm", PT1(1152,300), PT1(1472,300), 13, 13, 15, 15, DYESUB_PORTRAIT), + DEFINE_PAPER( "w155h244", "Card 54x86mm", PT1(668,300), PT1(1088,300), 13, 13, 15, 15, DYESUB_LANDSCAPE), +}; + +LIST(dyesub_pagesize_list_t, cp910_page_list, dyesub_pagesize_t, cp910_page); + +static const dyesub_printsize_t cp910_printsize[] = +{ + { "300x300", "Postcard", 1248, 1872}, + { "300x300", "w253h337", 1152, 1472}, + { "300x300", "w155h244", 668, 1088}, +}; + +LIST(dyesub_printsize_list_t, cp910_printsize_list, dyesub_printsize_t, cp910_printsize); + +static void cp910_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg; + + stp_zfwrite("\x0f\x00\x00\x40\x00\x00\x00\x00", 1, 8, v); + stp_zfwrite("\x00\x00\x00\x00\x00\x00\x01\x00", 1, 8, v); + stp_putc(0x01, v); + stp_putc(0x00, v); + + pg = (strcmp(pd->pagesize, "Postcard") == 0 ? 0x50 : + (strcmp(pd->pagesize, "w253h337") == 0 ? 0x4c : + (strcmp(pd->pagesize, "w155h244") == 0 ? 0x43 : + 0x50 ))); + stp_putc(pg, v); + + dyesub_nputc(v, '\0', 4); + stp_putc(0x01, v); + + stp_put32_le(pd->w_size, v); + stp_put32_le(pd->h_size, v); +} + +/* Sony DPP-EX5, DPP-EX7 */ +static const dyesub_resolution_t res_403dpi[] = +{ + { "403x403", 403, 403}, +}; + +LIST(dyesub_resolution_list_t, res_403dpi_list, dyesub_resolution_t, res_403dpi); + +/* only Postcard pagesize is supported */ +static const dyesub_pagesize_t dppex5_page[] = +{ + DEFINE_PAPER( "w288h432", "Postcard", PT1(1664,403), PT1(2466,403), 13, 14, 18, 17, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dppex5_page_list, dyesub_pagesize_t, dppex5_page); + +static const dyesub_printsize_t dppex5_printsize[] = +{ + { "403x403", "w288h432", 1664, 2466}, +}; + +LIST(dyesub_printsize_list_t, dppex5_printsize_list, dyesub_printsize_t, dppex5_printsize); + +static void dppex5_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("DPEX\0\0\0\x80", 1, 8, v); + stp_zfwrite("DPEX\0\0\0\x82", 1, 8, v); + stp_zfwrite("DPEX\0\0\0\x84", 1, 8, v); + stp_put32_be(pd->w_size, v); + stp_put32_be(pd->h_size, v); + stp_zfwrite("S\0o\0n\0y\0 \0D\0P\0P\0-\0E\0X\0\x35\0", 1, 24, v); + dyesub_nputc(v, '\0', 40); + stp_zfwrite("\1\4\0\4\xdc\0\x24\0\3\3\1\0\1\0\x82\0", 1, 16, v); + stp_zfwrite("\xf4\5\xf8\3\x64\0\1\0\x0e\0\x93\1\2\0\1\0", 1, 16, v); + stp_zfwrite("\x93\1\1\0\0\0", 1, 6, v); + stp_zfwrite("P\0o\0s\0t\0 \0c\0a\0r\0d\0", 1, 18, v); + dyesub_nputc(v, '\0', 46); + stp_zfwrite("\x93\1\x18", 1, 3, v); + dyesub_nputc(v, '\0', 19); + stp_zfwrite("\2\0\0\0\3\0\0\0\1\0\0\0\1", 1, 13, v); + dyesub_nputc(v, '\0', 19); + stp_zprintf(v, "5EPD"); + dyesub_nputc(v, '\0', 4); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /*overcoat pattern*/ + stp_zfwrite("\0d\0d\0d", 1, 6, v); + dyesub_nputc(v, '\0', 21); +} + +static void dppex5_block_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("DPEX\0\0\0\x85", 1, 8, v); + stp_put32_be((pd->block_max_w - pd->block_min_w + 1) + * (pd->block_max_h - pd->block_min_h + 1) * 3, v); +} + +static void dppex5_printer_end(stp_vars_t *v) +{ + stp_zfwrite("DPEX\0\0\0\x83", 1, 8, v); + stp_zfwrite("DPEX\0\0\0\x81", 1, 8, v); +} + +static const overcoat_t dppex5_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x00"}}, + {"Texture", N_("Texture"), {1, "\x01"}}, +}; + +LIST(overcoat_list_t, dppex5_overcoat_list, overcoat_t, dppex5_overcoat); + + +/* Sony UP-DP10 */ +static const dyesub_pagesize_t updp10_page[] = +{ + DEFINE_PAPER( "w288h432", "UPC-10P23 (4x6)", PT(1200,300), PT(1800,300), 12, 12, 18, 18, DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h387", "UPC-10P34 (4x5)", PT(1200,300), PT(1600,300), 12, 12, 16, 16, DYESUB_LANDSCAPE), +}; + +LIST(dyesub_pagesize_list_t, updp10_page_list, dyesub_pagesize_t, updp10_page); + +static const dyesub_printsize_t updp10_printsize[] = +{ + { "300x300", "w288h432", 1200, 1800}, + { "300x300", "w288h387", 1200, 1600}, +}; + +LIST(dyesub_printsize_list_t, updp10_printsize_list, dyesub_printsize_t, updp10_printsize); + +static void updp10_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x98\xff\xff\xff\xff\xff\xff\xff" + "\x09\x00\x00\x00\x1b\xee\x00\x00" + "\x00\x02\x00\x00\x01\x12\x00\x00" + "\x00\x1b\xe1\x00\x00\x00\x0b\x00" + "\x00\x04", 1, 34, v); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /*overcoat pattern*/ + stp_zfwrite("\x00\x00\x00\x00", 1, 4, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\x14\x00\x00\x00\x1b\x15\x00\x00" + "\x00\x0d\x00\x00\x00\x00\x00\x07" + "\x00\x00\x00\x00", 1, 20, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_put32_le(pd->w_size*pd->h_size*3+11, v); + stp_zfwrite("\x1b\xea\x00\x00\x00\x00", 1, 6, v); + stp_put32_be(pd->w_size*pd->h_size*3, v); + stp_zfwrite("\x00", 1, 1, v); +} + +static void updp10_printer_end_func(stp_vars_t *v) +{ + stp_zfwrite("\xff\xff\xff\xff\x07\x00\x00\x00" + "\x1b\x0a\x00\x00\x00\x00\x00\xfd" + "\xff\xff\xff\xff\xff\xff\xff" + , 1, 23, v); +} + +static const overcoat_t updp10_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x00"}}, + {"Texture", N_("Texture"), {1, "\x08"}}, + {"Matte", N_("Matte"), {1, "\x0c"}}, +}; + +LIST(overcoat_list_t, updp10_overcoat_list, overcoat_t, updp10_overcoat); + +static const char updp10_adj_cyan[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.113725 0.188235 0.247059 0.286275 0.317647 0.345098 0.368627 0.384314\n" + "0.400000 0.407843 0.423529 0.439216 0.450980 0.466667 0.482353 0.498039\n" + "0.509804 0.525490 0.545098 0.560784 0.580392 0.596078 0.619608 0.643137\n" + "0.662745 0.686275 0.709804 0.729412 0.756863 0.780392 0.811765 0.843137\n" + "1.000000\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char updp10_adj_magenta[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.105882 0.211765 0.286275 0.333333 0.364706 0.388235 0.403922 0.415686\n" + "0.427451 0.439216 0.450980 0.462745 0.478431 0.494118 0.505882 0.521569\n" + "0.537255 0.552941 0.568627 0.584314 0.600000 0.619608 0.643137 0.662745\n" + "0.682353 0.709804 0.733333 0.760784 0.792157 0.823529 0.858824 0.890196\n" + "1.000000\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static const char updp10_adj_yellow[] = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<gutenprint>\n" + "<curve wrap=\"nowrap\" type=\"spline\" gamma=\"0\">\n" + "<sequence count=\"33\" lower-bound=\"0\" upper-bound=\"1\">\n" + "0.101961 0.160784 0.196078 0.227451 0.243137 0.254902 0.266667 0.286275\n" + "0.309804 0.337255 0.368627 0.396078 0.423529 0.443137 0.462745 0.478431\n" + "0.501961 0.517647 0.537255 0.556863 0.576471 0.596078 0.619608 0.643137\n" + "0.666667 0.690196 0.709804 0.737255 0.760784 0.780392 0.796078 0.803922\n" + "1.000000\n" + "</sequence>\n" + "</curve>\n" + "</gutenprint>\n"; + +static void updp10_adjust_curves(stp_vars_t *v) +{ + dyesub_adjust_curve(v, updp10_adj_cyan, "CyanCurve"); + dyesub_adjust_curve(v, updp10_adj_magenta, "MagentaCurve"); + dyesub_adjust_curve(v, updp10_adj_yellow, "YellowCurve"); +} + +/* Sony UP-DR100 */ +static const dyesub_pagesize_t updr100_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1382,334), PT1(2048,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1210,334), PT1(1710,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1710,334), PT1(2380,334), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2048,334), PT1(2724,334), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, updr100_page_list, dyesub_pagesize_t, updr100_page); + +static const dyesub_printsize_t updr100_printsize[] = +{ + { "334x334", "w288h432", 1382, 2048}, + { "334x334", "B7", 1210, 1710}, + { "334x334", "w360h504", 1710, 2380}, + { "334x334", "w432h576", 2048, 2724}, +}; + +LIST(dyesub_printsize_list_t, updr100_printsize_list, dyesub_printsize_t, updr100_printsize); + +static void updr100_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("UPD8D\x00\x00\x00\x10\x03\x00\x00", 1, 12, v); + stp_put32_le(pd->w_size, v); + stp_put32_le(pd->h_size, v); + stp_zfwrite("\x1e\x00\x03\x00\x01\x00\x4e\x01\x00\x00", 1, 10, v); + stp_write_raw(&(pd->overcoat->seq), v); /* overcoat pattern */ + dyesub_nputc(v, '\0', 13); + stp_zfwrite("\x01\x00\x01\x00\x03", 1, 5, v); + dyesub_nputc(v, '\0', 19); +} + +static void updr100_printer_end_func(stp_vars_t *v) +{ + stp_zfwrite("UPD8D\x00\x00\x00\x02", 1, 9, v); + dyesub_nputc(v, '\0', 25); + stp_zfwrite("\x9d\x02\x00\x04\x00\x00\xc0\xe7" + "\x9d\x02\x54\xe9\x9d\x02\x9d\x71" + "\x00\x73\xfa\x71\x00\x73\xf4\xea" + "\x9d\x02\xa8\x3e\x00\x73\x9c\xeb\x9d\x02" + , 1, 34, v); +} + +static const overcoat_t updr100_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x01"}}, + {"Texture", N_("Texture"), {1, "\x03"}}, + {"Matte", N_("Matte"), {1, "\x04"}}, +}; + +LIST(overcoat_list_t, updr100_overcoat_list, overcoat_t, updr100_overcoat); + + +/* Sony UP-DR150 */ +static const dyesub_resolution_t res_334dpi[] = +{ + { "334x334", 334, 334}, +}; + +LIST(dyesub_resolution_list_t, res_334dpi_list, dyesub_resolution_t, res_334dpi); + +static const dyesub_pagesize_t updr150_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1382,334), PT1(2048,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1210,334), PT1(1728,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1728,334), PT1(2380,334), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2048,334), PT1(2724,334), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, updr150_page_list, dyesub_pagesize_t, updr150_page); + +static const dyesub_printsize_t updr150_printsize[] = +{ + { "334x334", "w288h432", 1382, 2048}, + { "334x334", "B7", 1210, 1728}, + { "334x334", "w360h504", 1728, 2380}, + { "334x334", "w432h576", 2048, 2724}, +}; + +LIST(dyesub_printsize_list_t, updr150_printsize_list, dyesub_printsize_t, updr150_printsize); + +static void updr150_200_printer_init_func(stp_vars_t *v, int updr200) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg; + + stp_zfwrite("\x6a\xff\xff\xff" + "\xef\xff\xff\xff", 1, 8, v); + + if (strcmp(pd->pagesize,"B7") == 0) + pg = '\x01'; + else if (strcmp(pd->pagesize,"w288h432") == 0) + pg = '\x02'; + else if (updr200 && strcmp(pd->pagesize,"w288h432-div2") == 0) + pg = '\x02'; + else if (strcmp(pd->pagesize,"w360h504") == 0) + pg = '\x03'; + else if (updr200 && strcmp(pd->pagesize,"w360h504-div2") == 0) + pg = '\x03'; + else if (strcmp(pd->pagesize,"w432h576") == 0) + pg = '\x04'; + else if (updr200 && strcmp(pd->pagesize,"w432h576-div2") == 0) + pg = '\x04'; + else + pg = 0; + + stp_put32_le(pg, v); + + stp_zfwrite("\xfc\xff\xff\xff" + "\xfb\xff\xff\xff" + "\xf4\xff\xff\xff" + "\xf5\xff\xff\xff", + 1, 16, v); + + /* Multicut mode */ + if (updr200) { + if (!strcmp(pd->pagesize,"w288h432-div2") || + !strcmp(pd->pagesize,"w360h504-div2") || + !strcmp(pd->pagesize,"w432h576-div2")) + pg = 0x01; + else + pg = 0x02; + } else { + pg = 0x01; + } + + stp_put32_le(pg, v); + + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\xe5\x00\x00\x00\x08\x00" + "\x08\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x01\x00" + "\xed\xff\xff\xff" + "\x07\x00\x00\x00" + "\x1b\xee\x00\x00\x00\x02\x00" + "\x02\x00\x00\x00" + "\x00", 1, 43, v); + stp_putc(pd->copies, v); + + if (updr200) { /* UP-DR200-specific! */ + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\xc0\x00\x03\x00\x05\x00", 1, 11, v); + } + stp_zfwrite("\x05\x00\x00\x00" + "\x02\x03\x00\x01", 1, 8, v); + + /* Multicut mode */ + if (updr200) { + if (!strcmp(pd->pagesize,"w288h432-div2") || + !strcmp(pd->pagesize,"w360h504-div2") || + !strcmp(pd->pagesize,"w432h576-div2")) + stp_putc(0x02, v); + else + stp_putc(0x00, v); + } else { + stp_putc(0x00, v); + } + + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\x15\x00\x00\x00\x0d\x00" + "\x0d\x00\x00\x00" + "\x00\x00\x00\x00\x07\x00\x00\x00\x00", 1, 24, v); + + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + + stp_zfwrite("\xf9\xff\xff\xff", + 1, 4, v); + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\xe1\x00\x00\x00\x0b\x00" + "\x0b\x00\x00\x00\x00\x80", 1, 17, v); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /*overcoat pattern*/ + + stp_zfwrite("\x00\x00\x00\x00", 1, 4, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\xf8\xff\xff\xff", 1, 4, v); + + /* Each data block has this header. Can actually have multiple blocks! */ + stp_zfwrite("\xec\xff\xff\xff", 1, 4, v); + stp_zfwrite("\x0b\x00\x00\x00\x1b\xea" + "\x00\x00\x00\x00", 1, 10, v); + stp_put32_be(pd->w_size*pd->h_size*3, v); + stp_zfwrite("\x00", 1, 1, v); + stp_put32_le(pd->w_size*pd->h_size*3, v); +} + +static void updr150_printer_init_func(stp_vars_t *v) +{ + updr150_200_printer_init_func(v, 0); +} + +static void updr150_printer_end_func(stp_vars_t *v) +{ + stp_zfwrite("\xeb\xff\xff\xff" + "\xfc\xff\xff\xff" + "\xfa\xff\xff\xff", + 1, 12, v); + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\x0a\x00\x00\x00\x00\x00" + "\x07\x00\x00\x00" + "\x1b\x17\x00\x00\x00\x00\x00", + 1, 22, v); + stp_zfwrite("\xf3\xff\xff\xff", + 1, 4, v); +} + +/* Sony UP-DR200 */ +static const dyesub_pagesize_t updr200_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1382,334), PT1(2048,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1382,334), PT1(2048,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1210,334), PT1(1728,334), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1728,334), PT1(2380,334), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w360h504-div2", "3.5x5*2", PT1(1728,334), PT1(2420,334), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2048,334), PT1(2724,334), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(2048,334), PT1(2764,334), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, updr200_page_list, dyesub_pagesize_t, updr200_page); + +static const dyesub_printsize_t updr200_printsize[] = +{ + { "334x334", "w288h432", 1382, 2048}, + { "334x334", "w288h432-div2", 1382, 2048}, + { "334x334", "B7", 1210, 1728}, + { "334x334", "w360h504", 1728, 2380}, + { "334x334", "w360h504-div2", 1728, 2420}, + { "334x334", "w432h576", 2048, 2724}, + { "334x334", "w432h576-div2", 2048, 2764}, +}; + +LIST(dyesub_printsize_list_t, updr200_printsize_list, dyesub_printsize_t, updr200_printsize); + +static const overcoat_t updr200_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x00"}}, + {"Matte", N_("Matte"), {1, "\x0c"}}, + {"Glossy_NoCorr", N_("Glossy_NoCorr"), {1, "\x10"}}, + {"Matte_NoCorr", N_("Matte_NoCorr"), {1, "\x1c"}}, +}; + +LIST(overcoat_list_t, updr200_overcoat_list, overcoat_t, updr200_overcoat); + +static void updr200_printer_init_func(stp_vars_t *v) +{ + updr150_200_printer_init_func(v, 1); +} + +/* Sony UP-CR10L / DNP SL10 */ +static const dyesub_pagesize_t upcr10_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1248,300), PT1(1848,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1100,300), PT1(1536,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1536,300), PT1(2148,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, upcr10_page_list, dyesub_pagesize_t, upcr10_page); + +static const dyesub_printsize_t upcr10_printsize[] = +{ + { "300x300", "w288h432", 1248, 1848}, + { "300x300", "B7", 1100, 1536}, + { "300x300", "w360h504", 1536, 2148}, +}; + +LIST(dyesub_printsize_list_t, upcr10_printsize_list, dyesub_printsize_t, upcr10_printsize); + +static void upcr10_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x60\xff\xff\xff" + "\xf8\xff\xff\xff" + "\xfd\xff\xff\xff\x14\x00\x00\x00" + "\x1b\x15\x00\x00\x00\x0d\x00\x00" + "\x00\x00\x00\x07\x00\x00\x00\x00", 1, 32, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\xfb\xff\xff\xff" + "\xf4\xff\xff\xff\x0b\x00\x00\x00" + "\x1b\xea\x00\x00\x00\x00", 1, 18, v); + stp_put32_be(pd->w_size * pd->h_size * 3, v); + stp_putc(0, v); + stp_put32_le(pd->w_size * pd->h_size * 3, v); +} + +static void upcr10_printer_end_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\xf3\xff\xff\xff" + "\x0f\x00\x00\x00" + "\x1b\xe5\x00\x00\x00\x08\x00\x00" + "\x00\x00\x00\x00\x00\x0d\x00", 1, 23, v); + stp_zfwrite("\x12\x00\x00\x00\x1b\xe1\x00\x00" + "\x000x0b\x00\x00\x80\x08\x00\x00" + "\x00\x00", 1, 18, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\xfa\xff\xff\xff" + "\x09\x00\x00\x00" + "\x1b\xee\x00\x00\x00\x02\x00\x00", 1, 16, v); + stp_putc(pd->copies, v); + stp_zfwrite("\x07\x00\x00\x00" + "\x1b\x17\x00\x00\x00\x00\x00", 1, 11, v); + stp_zfwrite("\xf9\xff\xff\xff" + "\xfc\xff\xff\xff" + "\x07\x00\x00\x00" + "\x1b\x17\x00\x00\x00\x00\x00", 1, 19, v); + stp_zfwrite("\xf7\xff\xff\xff", 1, 4, v); +} + +/* Fujifilm CX-400 */ +static const dyesub_pagesize_t cx400_page[] = +{ + DEFINE_PAPER( "w288h432", "4x6", PT1(1268,310), PT1(1658,310), 24, 24, 23, 22, DYESUB_PORTRAIT), + DEFINE_PAPER( "w288h387", "4x5 3/8", PT1(1268,310), PT1(1842,310), 24, 24, 23, 23, DYESUB_PORTRAIT), + DEFINE_PAPER( "w288h504", "4x7", PT1(1268,310), PT1(2208,310), 24, 24, 23, 22, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, cx400_page_list, dyesub_pagesize_t, cx400_page); + +static const dyesub_printsize_t cx400_printsize[] = +{ + { "310x310", "w288h387", 1268, 1658}, + { "310x310", "w288h432", 1268, 1842}, + { "310x310", "w288h504", 1268, 2208}, +}; + +LIST(dyesub_printsize_list_t, cx400_printsize_list, dyesub_printsize_t, cx400_printsize); + +static void cx400_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = '\0'; + const char *pname = "XXXXXX"; + + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub: fuji driver %s\n", stp_get_driver(v)); + if (strcmp(stp_get_driver(v),"fujifilm-cx400") == 0) + pname = "NX1000"; + else if (strcmp(stp_get_driver(v),"fujifilm-cx550") == 0) + pname = "QX200\0"; + + stp_zfwrite("FUJIFILM", 1, 8, v); + stp_zfwrite(pname, 1, 6, v); + stp_putc('\0', v); + stp_put16_le(pd->w_size, v); + stp_put16_le(pd->h_size, v); + if (strcmp(pd->pagesize,"w288h504") == 0) + pg = '\x0d'; + else if (strcmp(pd->pagesize,"w288h432") == 0) + pg = '\x0c'; + else if (strcmp(pd->pagesize,"w288h387") == 0) + pg = '\x0b'; + stp_putc(pg, v); + stp_zfwrite("\x00\x00\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00" + "\x00\x00\x2d\x00\x00\x00\x00", 1, 19, v); + stp_zfwrite("FUJIFILM", 1, 8, v); + stp_zfwrite(pname, 1, 6, v); + stp_putc('\1', v); +} + +/* Fujifilm NX-500 */ +static const dyesub_resolution_t res_306dpi[] = +{ + { "306x306", 306, 306}, +}; + +LIST(dyesub_resolution_list_t, res_306dpi_list, dyesub_resolution_t, res_306dpi); + +static const dyesub_pagesize_t nx500_page[] = +{ + DEFINE_PAPER( "Postcard", "Postcard", PT1(1024,306), PT1(1518,306), 21, 21, 29, 29, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, nx500_page_list, dyesub_pagesize_t, nx500_page); + +static const dyesub_printsize_t nx500_printsize[] = +{ + { "306x306", "Postcard", 1024, 1518}, +}; + +LIST(dyesub_printsize_list_t, nx500_printsize_list, dyesub_printsize_t, nx500_printsize); + +static void nx500_printer_init_func(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("INFO-QX-20--MKS\x00\x00\x00M\x00W\00A\x00R\00E", 1, 27, v); + dyesub_nputc(v, '\0', 21); + stp_zfwrite("\x80\x00\x02", 1, 3, v); + dyesub_nputc(v, '\0', 20); + stp_zfwrite("\x02\x01\x01", 1, 3, v); + dyesub_nputc(v, '\0', 2); + stp_put16_le(pd->h_size, v); + stp_put16_le(pd->w_size, v); + stp_zfwrite("\x00\x02\x00\x70\x2f", 1, 5, v); + dyesub_nputc(v, '\0', 43); +} + + +/* Kodak Easyshare Dock family */ +static const dyesub_pagesize_t kodak_dock_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1248,300), PT1(1856,300), DYESUB_PORTRAIT), /* 4x6 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_dock_page_list, dyesub_pagesize_t, kodak_dock_page); + +static const dyesub_printsize_t kodak_dock_printsize[] = +{ + { "300x300", "w288h432", 1248, 1856}, +}; + +LIST(dyesub_printsize_list_t, kodak_dock_printsize_list, dyesub_printsize_t, kodak_dock_printsize); + +static void kodak_dock_printer_init(stp_vars_t *v) +{ + stp_put16_be(0x3000, v); + dyesub_nputc(v, '\0', 10); +} + +static void kodak_dock_plane_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_put16_be(0x3001, v); + stp_put16_le(3 - pd->plane, v); + stp_put32_le(pd->w_size*pd->h_size, v); + dyesub_nputc(v, '\0', 4); +} + +/* Kodak 6800 */ +static const dyesub_pagesize_t kodak_6800_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), /* 4x6 */ + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), /* 6x8 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_6800_page_list, dyesub_pagesize_t, kodak_6800_page); + +static const dyesub_printsize_t kodak_6800_printsize[] = +{ + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w432h576", 1844, 2434}, +}; + +LIST(dyesub_printsize_list_t, kodak_6800_printsize_list, dyesub_printsize_t, kodak_6800_printsize); + +static const overcoat_t kodak_6800_overcoat[] = +{ + {"Coated", N_("Coated"), {1, "\x01"}}, + {"None", N_("None"), {1, "\x00"}}, +}; + +LIST(overcoat_list_t, kodak_6800_overcoat_list, overcoat_t, kodak_6800_overcoat); + +/* Kodak 6850 */ +static const dyesub_pagesize_t kodak_6850_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), /* 4x6 */ + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), /* 5x7 */ + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), /* 6x8 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_6850_page_list, dyesub_pagesize_t, kodak_6850_page); + +static const dyesub_printsize_t kodak_6850_printsize[] = +{ + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w360h504", 1548, 2140}, + { "300x300", "w432h576", 1844, 2434}, +}; + +LIST(dyesub_printsize_list_t, kodak_6850_printsize_list, dyesub_printsize_t, kodak_6850_printsize); + +static unsigned short short_to_packed_bcd(unsigned short val) +{ + unsigned short bcd; + unsigned short i; + + /* Handle from 0-9999 */ + i = val % 10; + bcd = i; + val /= 10; + i = val % 10; + bcd |= (i << 4); + val /= 10; + i = val % 10; + bcd |= (i << 8); + val /= 10; + i = val % 10; + bcd |= (i << 12); + + return bcd; +} + +static void kodak_68xx_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x03\x1b\x43\x48\x43\x0a\x00\x01", 1, 8, v); + stp_put16_be(short_to_packed_bcd(pd->copies), v); /* Number of copies in BCD */ + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + + if (!strcmp(pd->pagesize,"w288h432")) + stp_putc(0x00, v); + else if (!strcmp(pd->pagesize,"w432h576")) + stp_putc(0x06, v); + else if (!strcmp(pd->pagesize,"w360h504")) + stp_putc(0x07, v); + else + stp_putc(0x00, v); /* Just in case */ + + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x00, v); +} + +/* Kodak 605 */ +static const dyesub_pagesize_t kodak_605_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), /* 4x6 */ + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1500,300), PT1(2100,300), DYESUB_PORTRAIT), /* 5x7 */ + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), /* 6x8 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_605_page_list, dyesub_pagesize_t, kodak_605_page); + +static const dyesub_printsize_t kodak_605_printsize[] = +{ + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w360h504", 1500, 2100}, + { "300x300", "w432h576", 1844, 2434}, +}; + +LIST(dyesub_printsize_list_t, kodak_605_printsize_list, dyesub_printsize_t, kodak_605_printsize); + +static void kodak_605_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x01\x40\x0a\x00\x01", 1, 5, v); + stp_put16_be(short_to_packed_bcd(pd->copies), v); /* Number of copies in BCD */ + stp_putc(0x00, v); + stp_put16_le(pd->w_size, v); + stp_put16_le(pd->h_size, v); + + if (!strcmp(pd->pagesize,"w288h432")) + stp_putc(0x01, v); + else if (!strcmp(pd->pagesize,"w432h576")) + stp_putc(0x03, v); + else if (!strcmp(pd->pagesize,"w360h504")) + stp_putc(0x02, v); + else + stp_putc(0x01, v); + + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x00, v); +} + +static const overcoat_t kodak_605_overcoat[] = +{ + {"Coated", N_("Coated"), {1, "\x02"}}, + {"None", N_("None"), {1, "\x01"}}, +}; + +LIST(overcoat_list_t, kodak_605_overcoat_list, overcoat_t, kodak_605_overcoat); + +/* Kodak 1400 */ +static const dyesub_resolution_t res_301dpi[] = +{ + { "301x301", 301, 301}, +}; + +LIST(dyesub_resolution_list_t, res_301dpi_list, dyesub_resolution_t, res_301dpi); + +static const dyesub_pagesize_t kodak_1400_page[] = +{ + /* Printer has 1" non-printable area on top and bottom of page, not part of + data sent over. + + Printer requires full-bleed data horizontally. However, not all pixels + are actually printed. 35+35 (8x14 paper) or 76+76 (8x12 paper) are + effectively discarded (ie ~0.125" and ~0.250" respectively). + + The printer can technically print a little wider but these dimensions are + defined by the lamination area, which is fixed. + */ + DEFINE_PAPER( "w612h864", "8.5x12", PT1(2560,301), PT(3010,301)+72*2, PT1(76,301), PT(76,301), 72, 72, DYESUB_PORTRAIT), /* 8x12 */ + DEFINE_PAPER( "Legal", "8.5x14", PT1(2560,301), PT(3612,301)+72*2, PT1(35,301), PT1(35,301), 72, 72, DYESUB_PORTRAIT), /* 8x14 */ + DEFINE_PAPER( "A4", "A4", PT1(2560,301), PT(3010,301)+72*2, PT1(76,301), PT(76,301), 0, 0, DYESUB_PORTRAIT), /* A4, identical to 8x12 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_1400_page_list, dyesub_pagesize_t, kodak_1400_page); + +static const dyesub_media_t kodak_1400_media[] = +{ + { "Glossy", N_("Glossy"), {2, "\x00\x3c"}}, + { "Matte+5", N_("Matte +5"), {2, "\x01\x28"}}, + { "Matte+4", N_("Matte +4"), {2, "\x01\x2e"}}, + { "Matte+3", N_("Matte +3"), {2, "\x01\x34"}}, + { "Matte+2", N_("Matte +2"), {2, "\x01\x3a"}}, + { "Matte+1", N_("Matte +1"), {2, "\x01\x40"}}, + { "Matte", N_("Matte"), {2, "\x01\x46"}}, + { "Matte-1", N_("Matte -1"), {2, "\x01\x52"}}, + { "Matte-2", N_("Matte -2"), {2, "\x01\x5e"}}, + { "Matte-3", N_("Matte -3"), {2, "\x01\x6a"}}, + { "Matte-4", N_("Matte -4"), {2, "\x01\x76"}}, + { "Matte-5", N_("Matte -5"), {2, "\x01\x82"}}, +}; +LIST(dyesub_media_list_t, kodak_1400_media_list, dyesub_media_t, kodak_1400_media); + +static const dyesub_printsize_t kodak_1400_printsize[] = +{ + { "301x301", "w612h864", 2560, 3010}, + { "301x301", "Legal", 2560, 3612}, + { "301x301", "A4", 2560, 3010}, +}; + +LIST(dyesub_printsize_list_t, kodak_1400_printsize_list, dyesub_printsize_t, kodak_1400_printsize); + +static void kodak_1400_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("PGHD", 1, 4, v); + stp_put16_le(pd->w_size, v); + dyesub_nputc(v, 0x00, 2); + stp_put16_le(pd->h_size, v); + dyesub_nputc(v, 0x00, 2); + stp_put32_le(pd->h_size*pd->w_size, v); + dyesub_nputc(v, 0x00, 4); + stp_zfwrite((pd->media->seq).data, 1, 1, v); /* Matte or Glossy? */ + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x01, v); + stp_zfwrite((const char*)((pd->media->seq).data) + 1, 1, 1, v); /* Lamination intensity */ + dyesub_nputc(v, 0x00, 12); +} + +/* Kodak 805 */ +static const dyesub_pagesize_t kodak_805_page[] = +{ + /* Identical to the Kodak 1400 except for the lack of A4 support. + See the 1400 comments for explanations of this. */ + DEFINE_PAPER( "w612h864", "8.5x12", PT1(2560,301), PT(3010,301)+72*2, PT1(76,301), PT(76,301), 72, 72, DYESUB_PORTRAIT), /* 8x12 */ + DEFINE_PAPER( "Legal", "8.5x14", PT1(2560,301), PT(3612,301)+72*2, PT1(35,301), PT1(35,301), 72, 72, DYESUB_PORTRAIT), /* 8x14 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_805_page_list, dyesub_pagesize_t, kodak_805_page); + +static const dyesub_printsize_t kodak_805_printsize[] = +{ + { "301x301", "w612h864", 2560, 3010}, + { "301x301", "Legal", 2560, 3612}, +}; + +LIST(dyesub_printsize_list_t, kodak_805_printsize_list, dyesub_printsize_t, kodak_805_printsize); + +static void kodak_805_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("PGHD", 1, 4, v); + stp_put16_le(pd->w_size, v); + dyesub_nputc(v, 0x00, 2); + stp_put16_le(pd->h_size, v); + dyesub_nputc(v, 0x00, 2); + stp_put32_le(pd->h_size*pd->w_size, v); + dyesub_nputc(v, 0x00, 5); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x01, v); + stp_putc(0x3c, v); /* Lamination intensity; fixed on glossy media */ + dyesub_nputc(v, 0x00, 12); +} + +/* Kodak 9810 / 8800 */ +static const dyesub_pagesize_t kodak_9810_page[] = +{ + DEFINE_PAPER_SIMPLE( "c8x10", "8x10", PT1(2464,300), PT1(3024,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864", "8x12", PT1(2464,300), PT1(3624,300), DYESUB_PORTRAIT), +}; +LIST(dyesub_pagesize_list_t, kodak_9810_page_list, dyesub_pagesize_t, kodak_9810_page); + +static const dyesub_printsize_t kodak_9810_printsize[] = +{ + { "300x300", "c8x10", 2464, 3024}, + { "300x300", "w576h864", 2464, 3624}, +}; + +LIST(dyesub_printsize_list_t, kodak_9810_printsize_list, dyesub_printsize_t, kodak_9810_printsize); + +static const overcoat_t kodak_9810_overcoat[] = +{ + {"Coated", N_("Coated"), {3, "\x4f\x6e\x20"}}, + {"None", N_("None"), {3, "\x4f\x66\x66"}}, +}; + +LIST(overcoat_list_t, kodak_9810_overcoat_list, overcoat_t, kodak_9810_overcoat); + +static const stp_parameter_t kodak_9810_parameters[] = +{ + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 18 is normal, 24 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define kodak_9810_parameter_count (sizeof(kodak_9810_parameters) / sizeof(const stp_parameter_t)) + +static int +kodak_9810_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 18; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 24; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int kodak_9810_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.k9810.sharpen = stp_get_int_parameter(v, "Sharpen"); + + return 1; +} + +static void kodak_9810_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + +/* Command stream header */ + stp_putc(0x1b, v); + stp_zfwrite("MndROSETTA V001.00100000020525072696E74657242696E4D6F74726C", 1, 59, v); + + /* Begin Job */ + stp_putc(0x1b, v); + stp_zfwrite("MndBgnJob Print ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(8, v); + stp_zfwrite("\x56\x30\x30\x31\x2e\x30\x30\x30", 1, 8, v); + + /* Job Definition Start */ + stp_putc(0x1b, v); + stp_zfwrite("FlsSrtJbDefSetup ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* Paper selection */ + stp_putc(0x1b, v); + stp_zfwrite("FlsJbMkMed Name ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(64, v); + if (pd->h_size == 3624) { + stp_zfwrite("YMCX 8x12 Glossy", 1, 16, v); + } else { + stp_zfwrite("YMCX 8x10 Glossy", 1, 16, v); + } + dyesub_nputc(v, 0x00, 48); + + /* Paper Selection II */ + stp_putc(0x1b, v); + stp_zfwrite("FlsPgMedia Name ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(64, v); + stp_zfwrite("\x38\x22", 1, 2, v); + dyesub_nputc(v, 0x00, 62); + + /* Lamination */ + stp_putc(0x1b, v); + stp_zfwrite("FlsJbLam ", 1, 11, v); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + dyesub_nputc(v, 0x20, 5); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* Job Definition End */ + stp_putc(0x1b, v); + stp_zfwrite("FlsStpJbDef ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* Begin Page */ + stp_putc(0x1b, v); + stp_zfwrite("MndBgnLPageNormal ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(4, v); + stp_put32_be(1, v); + + /* Page dimensions I -- maybe this is physical media size? */ + stp_putc(0x1b, v); + stp_zfwrite("MndSetLPage ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(8, v); + stp_put32_be(pd->w_size, v); + stp_put32_be(pd->h_size, v); + + /* Page dimensions II -- maybe this is image data size? */ + stp_putc(0x1b, v); + stp_zfwrite("MndImSpec Size ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(16, v); + stp_put32_be(pd->w_size, v); + stp_put32_be(pd->h_size, v); + stp_put32_be(pd->w_size, v); + stp_put32_be(0, v); + + /* Positioning within page? */ + stp_putc(0x1b, v); + stp_zfwrite("FlsImPositnSpecify ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(8, v); + stp_put32_be(0, v); /* Presumably X */ + stp_put32_be(0, v); /* Presumably Y */ + + /* Sharpening */ + stp_putc(0x1b, v); + stp_zfwrite("FlsImSharp SetLevel", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(2, v); + stp_putc(0xFF, v); + stp_putc(pd->privdata.k9810.sharpen, v); + + /* Number of Copies */ + stp_putc(0x1b, v); + stp_zfwrite("FlsPgCopies ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(4, v); + stp_put32_be(pd->copies, v); + + /* Mirroring */ + stp_putc(0x1b, v); + stp_zfwrite("FlsPgMirrorNone ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* Rotation */ + stp_putc(0x1b, v); + stp_zfwrite("FlsPgRotateNone ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* Cut list -- seems to be list of be16 row offsets for cuts. */ + stp_putc(0x1b, v); + stp_zfwrite("FlsCutList ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(4, v); + + /* Cut at start/end of sheet */ + if (pd->h_size == 3624) { + stp_zfwrite("\x00\x0c\x0e\x1c", 1, 4, v); + } else { + stp_zfwrite("\x00\x0c\x0b\xc4", 1, 4, v); + } + +#if 0 /* Additional Known Cut lists */ + /* Single cut, down the center */ + stp_put32_be(6, v); + if (pd->h_size == 3624) { + stp_zfwrite("\x00\x0c\x07\x14\x0e\x1c", 1, 6, v); + } else { + stp_zfwrite("\x00\x0c\x05\xe8\x0b\xc4", 1, 6, v); + } + /* Double-Slug Cut, down the center */ + stp_put32_be(8, v); + if (pd->h_size == 3624) { + stp_zfwrite("\x00\x0c\x07\x01\x07\x27\x0e\x1c", 1, 6, v); + } else { + stp_zfwrite("\x00\x0c\x05\xd5\x05\xfb\x0b\xc4", 1, 6, v); + } +#endif + +} + +static void kodak_9810_printer_end(stp_vars_t *v) +{ + /* End Page */ + stp_putc(0x1b, v); + stp_zfwrite("MndEndLPage ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); + + /* End Job */ + stp_putc(0x1b, v); + stp_zfwrite("MndEndJob ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be(0, v); +} + +static void kodak_9810_plane_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Data block */ + stp_putc(0x1b, v); + stp_zfwrite("FlsData Block ", 1, 19, v); + dyesub_nputc(v, 0x00, 4); + stp_put32_be((pd->w_size * pd->h_size) + 8, v); + stp_zfwrite("Image ", 1, 8, v); +} + +/* Kodak 8810 */ +static const dyesub_pagesize_t kodak_8810_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h576", "8x4", PT1(1208,300), PT1(2464,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "c8x10", "8x10", PT1(2464,300), PT1(3024,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "A4", "203x297mm", PT1(2464,300), PT1(3531,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864", "8x12", PT1(2464,300), PT1(3624,300), DYESUB_PORTRAIT), +}; +LIST(dyesub_pagesize_list_t, kodak_8810_page_list, dyesub_pagesize_t, kodak_8810_page); + +static const dyesub_printsize_t kodak_8810_printsize[] = +{ + { "300x300", "w288h576", 1208, 2464}, + { "300x300", "c8x10", 2464, 3024}, + { "300x300", "A4", 2464, 3531}, + { "300x300", "w576h864", 2464, 3624}, +}; + +LIST(dyesub_printsize_list_t, kodak_8810_printsize_list, dyesub_printsize_t, kodak_8810_printsize); + +static const overcoat_t kodak_8810_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x03"}}, + {"Satin", N_("Satin"), {1, "\x02"}}, + {"None", N_("None"), {1, "\x01"}}, +}; + +LIST(overcoat_list_t, kodak_8810_overcoat_list, overcoat_t, kodak_8810_overcoat); + +static void kodak_8810_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_putc(0x01, v); + stp_putc(0x40, v); + stp_putc(0x12, v); + stp_putc(0x00, v); + stp_putc(0x01, v); + stp_put16_le(pd->copies, v); + stp_put16_le(pd->w_size, v); + stp_put16_le(pd->h_size, v); + stp_put16_le(pd->w_size, v); + stp_put16_le(pd->h_size, v); + dyesub_nputc(v, 0, 4); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x00, v); /* Method -- 00 is normal, 02 is x2, 03 is x3 */ + stp_putc(0x00, v); /* Reserved */ +} + +/* Kodak 7000/7010 */ +static const dyesub_pagesize_t kodak_7000_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), /* 4x6 */ + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), /* 6x8 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_7000_page_list, dyesub_pagesize_t, kodak_7000_page); + +static const dyesub_printsize_t kodak_7000_printsize[] = +{ + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w432h576", 1844, 2434}, +}; + +LIST(dyesub_printsize_list_t, kodak_7000_printsize_list, dyesub_printsize_t, kodak_7000_printsize); +static const overcoat_t kodak_7000_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x02"}}, + {"Satin", N_("Satin"), {1, "\x03"}}, +}; + +LIST(overcoat_list_t, kodak_7000_overcoat_list, overcoat_t, kodak_7000_overcoat); + +static void kodak_70xx_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x01\x40\x0a\x00\x01", 1, 5, v); + stp_put16_le(pd->copies, v); + stp_put16_le(pd->w_size, v); + stp_put16_le(pd->h_size, v); + + if (!strcmp(pd->pagesize,"w288h432")) + stp_putc(0x01, v); + else if (!strcmp(pd->pagesize,"w432h576")) + stp_putc(0x03, v); + else if (!strcmp(pd->pagesize,"w360h504")) + stp_putc(0x06, v); + else + stp_putc(0x01, v); + + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); + stp_putc(0x00, v); +} + +/* Kodak 7015 */ +static const dyesub_pagesize_t kodak_7015_page[] = +{ + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), /* 5x7 */ +}; + +LIST(dyesub_pagesize_list_t, kodak_7015_page_list, dyesub_pagesize_t, kodak_7015_page); + +static const dyesub_printsize_t kodak_7015_printsize[] = +{ + { "300x300", "w360h504", 1548, 2140}, +}; + +LIST(dyesub_printsize_list_t, kodak_7015_printsize_list, dyesub_printsize_t, kodak_7015_printsize); + +/* Kodak Professional 8500 */ +static const dyesub_pagesize_t kodak_8500_page[] = +{ + DEFINE_PAPER_SIMPLE( "w612h864", "8.5x12", PT1(2508,314), PT1(3134,314), DYESUB_PORTRAIT), /* 8.5x12 & A4 */ + DEFINE_PAPER_SIMPLE( "Letter", "8.5x11", PT1(2508,314), PT1(2954,314), DYESUB_PORTRAIT), /* Letter */ +}; + +LIST(dyesub_pagesize_list_t, kodak_8500_page_list, dyesub_pagesize_t, kodak_8500_page); + +static const dyesub_printsize_t kodak_8500_printsize[] = +{ + { "314x314", "w612h864", 2508, 3134}, + { "314x314", "Letter", 2508, 2954}, +}; + +LIST(dyesub_printsize_list_t, kodak_8500_printsize_list, dyesub_printsize_t, kodak_8500_printsize); + +static const dyesub_media_t kodak_8500_media[] = +{ + { "Glossy", N_("Glossy"), {1, "\x00"}}, + { "Matte", N_("Matte"), {1, "\x01"}}, +}; +LIST(dyesub_media_list_t, kodak_8500_media_list, dyesub_media_t, kodak_8500_media); + +static const overcoat_t kodak_8500_overcoat[] = +{ + {"Coated", N_("Coated"), {1, "\x00"}}, + {"None", N_("None"), {1, "\x02"}}, +}; + +LIST(overcoat_list_t, kodak_8500_overcoat_list, overcoat_t, kodak_8500_overcoat); + +static const stp_parameter_t kodak_8500_parameters[] = +{ + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (-5 through +5)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MatteIntensity", N_("Matte Intensity"), "Color=No,Category=Advanced Printer Setup", + N_("Strength of matte lamination pattern (-5 through +5)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define kodak_8500_parameter_count (sizeof(kodak_8500_parameters) / sizeof(const stp_parameter_t)) + +static int +kodak_8500_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -5; + description->bounds.integer.upper = 5; + description->is_active = 1; + } + else if (strcmp(name, "MatteIntensity") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -5; + description->bounds.integer.upper = 5; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int kodak_8500_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.k8500.sharpen = stp_get_int_parameter(v, "Sharpen"); + pd->privdata.k8500.matte_intensity = stp_get_int_parameter(v, "MatteIntensity"); + + return 1; +} + +static void kodak_8500_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + +/* Start with NULL block */ + dyesub_nputc(v, 0x00, 64); + /* Number of copies */ + stp_putc(0x1b, v); + stp_putc(0x4e, v); + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ + dyesub_nputc(v, 0x00, 61); + /* Paper type. Fixed. */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x46, v); + stp_putc(0x00, v); /* Fixed */ + dyesub_nputc(v, 0x00, 60); + /* Print dimensions */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x53, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 57); + /* Sharpening */ + stp_putc(0x1b, v); + stp_putc(0x46, v); + stp_putc(0x50, v); + stp_putc(pd->privdata.k8500.sharpen, v); + dyesub_nputc(v, 0x00, 60); + /* Lamination */ + stp_putc(0x1b, v); + stp_putc(0x59, v); + if (*((const char*)((pd->overcoat->seq).data)) == 0x02) { /* No lamination */ + stp_putc(0x02, v); + stp_putc(0x00, v); + } else { + stp_zfwrite((const char*)((pd->media->seq).data), 1, + (pd->media->seq).bytes, v); + if (*((const char*)((pd->media->seq).data)) == 0x01) { /* Matte */ + stp_putc(pd->privdata.k8500.matte_intensity, v); + } else { + stp_putc(0x00, v); + } + } + dyesub_nputc(v, 0x00, 60); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x46, v); + stp_putc(0x47, v); + dyesub_nputc(v, 0x00, 61); + + /* Data header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x54, v); + dyesub_nputc(v, 0x00, 2); + stp_put16_be(0, v); /* Starting row for this block */ + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); /* Number of rows in this block */ + dyesub_nputc(v, 0x00, 53); +} + +static void kodak_8500_printer_end(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Pad data to 64-byte block */ + unsigned int length = pd->w_size * pd->h_size * 3; + length %= 64; + if (length) { + length = 64 - length; + dyesub_nputc(v, 0x00, length); + } + + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + dyesub_nputc(v, 0x00, 62); +} + +/* Mitsubishi P95D/DW */ +static const dyesub_resolution_t res_325dpi[] = +{ + { "325x325", 325, 325}, +}; + +LIST(dyesub_resolution_list_t, res_325dpi_list, dyesub_resolution_t, res_325dpi); + +/* All are "custom" page sizes.. bleh.. */ +static const dyesub_pagesize_t mitsu_p95d_page[] = +{ + DEFINE_PAPER_SIMPLE( "w213h284", "1280x960", PT1(960,325), PT1(1280,325), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w227h284", "1280x1024", PT1(1024,325), PT1(1280,325), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w284h284", "1280x1280", PT1(1280,325), PT1(1280,325), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w284h426", "1280x1920", PT1(1280,325), PT1(1920,325), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w284h1277", "1280x5760", PT1(1280,325), PT1(5760,325), DYESUB_PORTRAIT), + /* A true "custom" size, printer will cut at the image boundary */ + DEFINE_PAPER_SIMPLE( "Custom", "Custom", PT1(1280,325), -1, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_p95d_page_list, dyesub_pagesize_t, mitsu_p95d_page); + +static const dyesub_printsize_t mitsu_p95d_printsize[] = +{ + { "325x325", "w213h284", 960, 1280}, + { "325x325", "w227h284", 1024, 1280}, + { "325x325", "w284h284", 1280, 1280}, + { "325x325", "w284h426", 1280, 1920}, + { "325x325", "w284h1277", 1280, 5760}, + { "325x325", "Custom", 1280, 5760}, /* Maximum */ +}; + +LIST(dyesub_printsize_list_t, mitsu_p95d_printsize_list, dyesub_printsize_t, mitsu_p95d_printsize); + +static const dyesub_media_t mitsu_p95d_medias[] = +{ + {"Standard", N_("Standard (KP61B)"), {1, "\x00"}}, + {"HighDensity", N_("High Density (KP65HM)"), {1, "\x01"}}, + {"HighGlossy", N_("High Glossy (KP91HG)"), {1, "\x02"}}, + {"HighGlossyK95HG", N_("High Glosy (K95HG)"), {1, "\x03"}}, +}; + +LIST(dyesub_media_list_t, mitsu_p95d_media_list, dyesub_media_t, mitsu_p95d_medias); + +static const dyesub_stringitem_t mitsu_p95d_gammas[] = +{ + { "Printer", N_ ("Printer-Defined Setting") }, + { "T1", N_ ("Table 1") }, + { "T2", N_ ("Table 2") }, + { "T3", N_ ("Table 3") }, + { "T4", N_ ("Table 4") }, + { "T5", N_ ("Table 5") }, + { "LUT", N_ ("Use LUT") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_gamma_list, dyesub_stringitem_t, mitsu_p95d_gammas); + +static const dyesub_stringitem_t mitsu_p95d_buzzers[] = +{ + { "Off", N_ ("Off") }, + { "Low", N_ ("Low") }, + { "High", N_ ("High") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_buzzer_list, dyesub_stringitem_t, mitsu_p95d_buzzers); + +static const dyesub_stringitem_t mitsu_p95d_cutters[] = +{ + { "PaperSave", N_ ("Paper Save") }, + { "4mm", N_ ("4mm") }, + { "5mm", N_ ("5mm") }, + { "6mm", N_ ("6mm") }, + { "7mm", N_ ("7mm") }, + { "8mm", N_ ("8mm") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_cutter_list, dyesub_stringitem_t, mitsu_p95d_cutters); + +static const dyesub_stringitem_t mitsu_p95d_comments[] = +{ + { "Off", N_ ("Off") }, + { "Settings", N_ ("Printer Settings") }, + { "Date", N_ ("Date") }, + { "DateTime", N_ ("Date and Time") }, +}; +LIST(dyesub_stringlist_t, mitsu_p95d_comment_list, dyesub_stringitem_t, mitsu_p95d_comments); + +static const stp_parameter_t mitsu_p95d_parameters[] = +{ + { + "P95Gamma", N_("Printer Gamma Correction"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Gamma Correction"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Buzzer", N_("Printer Buzzer"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Buzzer"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MediaCut", N_("Media Cut Length"), "Color=No,Category=Advanced Printer Setup", + N_("Media Cut Length"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Comment", N_("Generate Comment"), "Color=No,Category=Advanced Printer Setup", + N_("Generate Comment"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ClearMemory", N_("Clear Memory"), "Color=No,Category=Advanced Printer Setup", + N_("Clear Memory"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ContinuousPrint", N_("Continuous Printing"), "Color=No,Category=Advanced Printer Setup", + N_("Continuous Printing"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P95Brightness", N_("Brightness"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Brightness Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P95Contrast", N_("Contrast"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Contrast Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UserComment", N_("User Comment"), "Color=No,Category=Advanced Printer Setup", + N_("User-specified comment (0-34 characters from 0x20->0x7E), null terminated if under 34 characters long"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu_p95d_parameter_count (sizeof(mitsu_p95d_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu_p95d_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "P95Gamma") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_gamma_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "Buzzer") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_buzzer_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 2)->name; + description->is_active = 1; + } else if (strcmp(name, "MediaCut") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_cutter_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 2)->name; + description->is_active = 1; + } else if (strcmp(name, "Comment") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_comment_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "ClearMemory") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "ContinuousPrint") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "P95Brightness") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "P95Contrast") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "UserComment") == 0) { + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu_p95d_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + const char *gamma = stp_get_string_parameter(v, "P95Gamma"); + const char *buzzer = stp_get_string_parameter(v, "Buzzer"); + const char *cutter = stp_get_string_parameter(v, "MediaCut"); + const char *comment = stp_get_string_parameter(v, "Comment"); + const stp_raw_t *usercomment = NULL; + + /* Sanity check */ + if (stp_check_raw_parameter(v, "UserComment", STP_PARAMETER_ACTIVE)) { + usercomment = stp_get_raw_parameter(v, "UserComment"); + if (usercomment->bytes > 34) { + stp_eprintf(v, _("StpUserComment must be between 0 and 34 bytes!\n")); + return 0; + } + } + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.m95d.clear_mem = stp_get_boolean_parameter(v, "ClearMemory"); + pd->privdata.m95d.cont_print = stp_get_boolean_parameter(v, "ContinuousPrint"); + + if (pd->copies > 200) + pd->copies = 200; + + pd->privdata.m95d.brightness = stp_get_int_parameter(v, "P95Brightness"); + pd->privdata.m95d.contrast = stp_get_int_parameter(v, "P95Contrast"); + + if (!strcmp(gamma, "Printer")) { + pd->privdata.m95d.gamma = 0x00; + } else if (!strcmp(gamma, "T1")) { + pd->privdata.m95d.gamma = 0x01; + } else if (!strcmp(gamma, "T2")) { + pd->privdata.m95d.gamma = 0x02; + } else if (!strcmp(gamma, "T3")) { + pd->privdata.m95d.gamma = 0x03; + } else if (!strcmp(gamma, "T4")) { + pd->privdata.m95d.gamma = 0x04; + } else if (!strcmp(gamma, "T5")) { + pd->privdata.m95d.gamma = 0x05; + } else if (!strcmp(gamma, "LUT")) { + pd->privdata.m95d.gamma = 0x10; + } + + if (!strcmp(buzzer, "Off")) { + pd->privdata.m95d.flags |= 0x00; + } else if (!strcmp(buzzer, "Low")) { + pd->privdata.m95d.flags |= 0x02; + } else if (!strcmp(buzzer, "High")) { + pd->privdata.m95d.flags |= 0x03; + } + + if (!strcmp(cutter, "PaperSave")) { + pd->privdata.m95d.flags |= 0x54; + } else if (!strcmp(cutter, "4mm")) { + pd->privdata.m95d.flags |= 0x40; + } else if (!strcmp(cutter, "5mm")) { + pd->privdata.m95d.flags |= 0x50; + } else if (!strcmp(cutter, "6mm")) { + pd->privdata.m95d.flags |= 0x60; + } else if (!strcmp(cutter, "7mm")) { + pd->privdata.m95d.flags |= 0x70; + } else if (!strcmp(cutter, "8mm")) { + pd->privdata.m95d.flags |= 0x80; + } + + if (!strcmp(comment, "Off")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 0; + } else if (!strcmp(comment, "Settings")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 1; + } else if (!strcmp(comment, "Date")) { + struct tm tmp; + time_t t; + t = stpi_time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F", &tmp); + pd->privdata.m95d.comment = 2; + } else if (!strcmp(comment, "DateTime")) { + struct tm tmp; + time_t t; + t = stpi_time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F %R", &tmp); + pd->privdata.m95d.comment = 3; + } + + if (usercomment) { + if (strncmp("None", usercomment->data, usercomment->bytes)) { + int i; + memcpy(pd->privdata.m95d.usercomment, usercomment->data, usercomment->bytes); + if (usercomment->bytes < 34) + pd->privdata.m95d.usercomment[usercomment->bytes] = 0; + for (i = 0 ; i < usercomment->bytes ; i++) { + if (pd->privdata.m95d.usercomment[i] < 0x20 || + pd->privdata.m95d.usercomment[i] > 0x7F) + pd->privdata.m95d.usercomment[i] = 0x20; + } + } + } else { + memset(pd->privdata.m95d.usercomment, 0x20, sizeof(pd->privdata.m95d.usercomment)); + } + + return 1; +} + +static const char *p95d_lut = "\x00\x12\x01\x5e\x03\x52\x05\xdc\x08\x66\x0a\x96\x0c\x3a\x0d\x70\x0e\x42\x0e\xce\x0f\x32\x0f\x78\x0f\xa0\x0f\xb4\x0f\xc8\x0f\xd8\x0f\xff"; /* Taken from "P95D.lut" dated 2016-05-25 */ + +static void mitsu_p95d_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Header */ + stp_putc(0x1b, v); + stp_putc(0x51, v); + + /* Clear memory */ + if (pd->privdata.m95d.clear_mem) { + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x43, v); + stp_putc(0x00, v); + } + + /* Page Setup */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x00, v); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 6); + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ + + /* This is only set under Windows if a "custom" size is selected, + but the USB comms always show it set to 1... */ + if (!strcmp(pd->pagesize,"Custom")) + stp_putc(0x01, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 31); + + /* Print Options */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x4a, v); + stp_putc(0xaa, v); + stp_putc(0x00, v); + stp_putc(0x20, v); + stp_zfwrite((pd->media->seq).data, 1, 1, v); /* Media Type */ + stp_putc(0x00, v); + stp_putc(0x00, v); + stp_putc(0x64, v); + if (pd->privdata.m95d.cont_print) + stp_putc(0xff, v); + else + stp_putc(pd->copies, v); + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.comment, v); + stp_zfwrite(pd->privdata.m95d.commentbuf, 1, sizeof(pd->privdata.m95d.commentbuf) -1, v); + dyesub_nputc(v, 0x00, 3); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 11); + stp_putc(pd->privdata.m95d.flags, v); + + /* Gamma */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x15, v); + if (pd->privdata.m95d.gamma == 0x10) + stp_putc(0x01, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(pd->privdata.m95d.gamma, v); + stp_putc(pd->privdata.m95d.brightness, v); + stp_putc(pd->privdata.m95d.contrast, v); + stp_putc(0x00, v); + + if (pd->privdata.m95d.gamma == 0x10) { + stp_zfwrite(p95d_lut, 1, sizeof(p95d_lut), v); /* XXX only for K95HG? */ + } else { + dyesub_nputc(v, 0x00, 34); + } + + /* User Comment */ + stp_putc(0x1b, v); + stp_putc(0x58, v); + stp_zfwrite(pd->privdata.m95d.usercomment, 1, sizeof(pd->privdata.m95d.usercomment), v); +} + +static void mitsu_p95d_plane_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Plane header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x74, v); + stp_putc(0x00, v); + stp_put16_be(0, v); /* Column Offset */ + stp_put16_be(0, v); /* Row Offset */ + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ +} + +static void mitsu_p95d_printer_end(stp_vars_t *v) +{ + /* Kick off the actual print */ + stp_putc(0x1b, v); + stp_putc(0x50, v); +} + +/* Mitsubishi P93D/DW */ + +static const dyesub_media_t mitsu_p93d_medias[] = +{ + {"Standard", N_("Standard (KP61B)"), {1, "\x02"}}, + {"HighDensity", N_("High Density (KP65HM)"), {1, "\x00"}}, + {"HighGlossy", N_("High Glossy (KP91HG)"), {1, "\x01"}}, +}; + +LIST(dyesub_media_list_t, mitsu_p93d_media_list, dyesub_media_t, mitsu_p93d_medias); + +static const dyesub_stringitem_t mitsu_p93d_gammas[] = +{ + { "T1", N_ ("Table 1") }, + { "T2", N_ ("Table 2") }, + { "T3", N_ ("Table 3") }, + { "T4", N_ ("Table 4") }, + { "T5", N_ ("Table 5") }, +}; +LIST(dyesub_stringlist_t, mitsu_p93d_gamma_list, dyesub_stringitem_t, mitsu_p93d_gammas); + +static const stp_parameter_t mitsu_p93d_parameters[] = +{ + { + "P93Gamma", N_("Printer Gamma Correction"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Gamma Correction"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Buzzer", N_("Printer Buzzer"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Buzzer"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "PaperSaving", N_("Paper Saving Mode"), "Color=Yes,Category=Advanced Printer Setup", + N_("Paper Saving Mode"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Comment", N_("Generate Comment"), "Color=No,Category=Advanced Printer Setup", + N_("Generate Comment"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ClearMemory", N_("Clear Memory"), "Color=No,Category=Advanced Printer Setup", + N_("Clear Memory"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ContinuousPrint", N_("Continuous Printing"), "Color=No,Category=Advanced Printer Setup", + N_("Continuous Printing"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P93Brightness", N_("Brightness"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Brightness Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "P93Contrast", N_("Contrast"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Contrast Adjustment"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (1 is soft, 1 is normal, 2 is hard"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UserComment", N_("User Comment"), "Color=No,Category=Advanced Printer Setup", + N_("User-specified comment (0-40 characters from 0x20->0x7E), null terminated if under 40 characters long"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu_p93d_parameter_count (sizeof(mitsu_p93d_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu_p93d_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "P93Gamma") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p93d_gamma_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "Buzzer") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_buzzer_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 2)->name; + description->is_active = 1; + } else if (strcmp(name, "PaperSaving") == 0) { + description->deflt.boolean = 0; + description->is_active = 1; + } else if (strcmp(name, "Comment") == 0) { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_p95d_comment_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else if (strcmp(name, "ClearMemory") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "ContinuousPrint") == 0) { + description->is_active = 1; + description->deflt.boolean = 0; + } else if (strcmp(name, "P93Brightness") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "P93Contrast") == 0) { + description->deflt.integer = 0; + description->bounds.integer.lower = -127; + description->bounds.integer.upper = 127; + description->is_active = 1; + } else if (strcmp(name, "Sharpen") == 0) { + description->deflt.integer = 1; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 2; + description->is_active = 1; + } else if (strcmp(name, "UserComment") == 0) { + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu_p93d_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + const char *gamma = stp_get_string_parameter(v, "P93Gamma"); + const char *buzzer = stp_get_string_parameter(v, "Buzzer"); + const char *comment = stp_get_string_parameter(v, "Comment"); + const stp_raw_t *usercomment = NULL; + + /* Sanity check */ + if (stp_check_raw_parameter(v, "UserComment", STP_PARAMETER_ACTIVE)) { + usercomment = stp_get_raw_parameter(v, "UserComment"); + if (usercomment->bytes > 40) { + stp_eprintf(v, _("StpUserComment must be between 0 and 40 bytes!\n")); + return 0; + } + } + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + pd->privdata.m95d.clear_mem = stp_get_boolean_parameter(v, "ClearMemory"); + pd->privdata.m95d.cont_print = stp_get_boolean_parameter(v, "ContinuousPrint"); + + if (pd->copies > 200) + pd->copies = 200; + + if (!strcmp(gamma, "T1")) { + pd->privdata.m95d.gamma = 0x00; + } else if (!strcmp(gamma, "T2")) { + pd->privdata.m95d.gamma = 0x01; + } else if (!strcmp(gamma, "T3")) { + pd->privdata.m95d.gamma = 0x02; + } else if (!strcmp(gamma, "T4")) { + pd->privdata.m95d.gamma = 0x03; + } else if (!strcmp(gamma, "T5")) { + pd->privdata.m95d.gamma = 0x04; + } + + if (!strcmp(buzzer, "Off")) { + pd->privdata.m95d.flags |= 0x00; + } else if (!strcmp(buzzer, "Low")) { + pd->privdata.m95d.flags |= 0x02; + } else if (!strcmp(buzzer, "High")) { + pd->privdata.m95d.flags |= 0x03; + } + + pd->privdata.m95d.brightness = stp_get_int_parameter(v, "P93Brightness"); + pd->privdata.m95d.contrast = stp_get_int_parameter(v, "P93Contrast"); + pd->privdata.m95d.sharpen = stp_get_int_parameter(v, "Sharpen"); + + if (stp_get_boolean_parameter(v, "PaperSaving")) { + pd->privdata.m95d.flags |= 0x04; + } + + if (!strcmp(comment, "Off")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 0; + } else if (!strcmp(comment, "Settings")) { + memset(pd->privdata.m95d.commentbuf, 0, sizeof(pd->privdata.m95d.commentbuf)); + pd->privdata.m95d.comment = 1; + } else if (!strcmp(comment, "Date")) { + struct tm tmp; + time_t t; + t = stpi_time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F", &tmp); + pd->privdata.m95d.comment = 2; + } else if (!strcmp(comment, "DateTime")) { + struct tm tmp; + time_t t; + t = stpi_time(NULL); + localtime_r(&t, &tmp); + strftime(pd->privdata.m95d.commentbuf, sizeof(pd->privdata.m95d.commentbuf), " %F %R", &tmp); + pd->privdata.m95d.comment = 3; + } + + if (usercomment) { + if (strncmp("None", usercomment->data, usercomment->bytes)) { + int i; + memcpy(pd->privdata.m95d.usercomment, usercomment->data, usercomment->bytes); + if (usercomment->bytes < 40) + pd->privdata.m95d.usercomment[usercomment->bytes] = 0; + for (i = 0 ; i < usercomment->bytes ; i++) { + if (pd->privdata.m95d.usercomment[i] < 0x20 || + pd->privdata.m95d.usercomment[i] > 0x7F) + pd->privdata.m95d.usercomment[i] = 0x20; + } + } + } else { + memset(pd->privdata.m95d.usercomment, 0x20, sizeof(pd->privdata.m95d.usercomment)); + } + + return 1; +} + +static void mitsu_p93d_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Header */ + stp_putc(0x1b, v); + stp_putc(0x51, v); + + /* Clear memory */ + if (pd->privdata.m95d.clear_mem) { + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x43, v); + stp_putc(0x00, v); + } + + /* Page Setup */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + dyesub_nputc(v, 0x00, 8); + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ + + /* This is only set under Windows if a "custom" size is selected, + but the USB comms always show it set to 1... */ + if (!strcmp(pd->pagesize,"Custom")) + stp_putc(0x01, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 31); + + /* Print Options */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x4a, v); + stp_putc(0xaa, v); + stp_putc(0x00, v); + stp_putc(0x00, v); + stp_zfwrite((pd->media->seq).data, 1, 1, v); /* Media Type */ + stp_putc(0x00, v); + stp_putc(0x00, v); + stp_putc(0x00, v); + if (pd->privdata.m95d.cont_print) + stp_putc(0xff, v); + else + stp_putc(pd->copies, v); + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.comment, v); + stp_zfwrite(pd->privdata.m95d.commentbuf, 1, sizeof(pd->privdata.m95d.commentbuf) -1, v); + dyesub_nputc(v, 0x00, 3); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 11); + stp_putc(pd->privdata.m95d.flags, v); + + /* Gamma */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0xd5, v); + dyesub_nputc(v, 0x00, 6); + + stp_putc(pd->privdata.m95d.sharpen, v); // XXX + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.gamma, v); + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.brightness, v); + stp_putc(0x00, v); + stp_putc(pd->privdata.m95d.contrast, v); + dyesub_nputc(v, 0x00, 31); + + /* User Comment */ + stp_putc(0x1b, v); + stp_putc(0x58, v); + stp_zfwrite(pd->privdata.m95d.usercomment, 1, sizeof(pd->privdata.m95d.usercomment), v); +} + +/* Mitsubishi CP3020D/DU/DE */ +static const dyesub_pagesize_t mitsu_cp3020d_page[] = +{ + DEFINE_PAPER_SIMPLE( "A4", "A4", PT1(2508,314), PT1(3134,314), DYESUB_PORTRAIT), /* A4 */ + DEFINE_PAPER_SIMPLE( "Legal", "Letter Long", PT1(2508,314), PT1(3762,314), DYESUB_PORTRAIT), /* Letter */ +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp3020d_page_list, dyesub_pagesize_t, mitsu_cp3020d_page); + +static const dyesub_printsize_t mitsu_cp3020d_printsize[] = +{ + { "314x314", "A4", 2508, 3134}, + { "314x314", "Legal", 2508, 3762}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp3020d_printsize_list, dyesub_printsize_t, mitsu_cp3020d_printsize); + +static void mitsu_cp3020d_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Start with NULL block */ + dyesub_nputc(v, 0x00, 64); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x51, v); + dyesub_nputc(v, 0x00, 62); + /* Paper type */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x46, v); + if (pd->h_size == 3762) + stp_putc(0x04, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 60); + /* Number of copies */ + stp_putc(0x1b, v); + stp_putc(0x4e, v); + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ + dyesub_nputc(v, 0x00, 61); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x46, v); + stp_putc(0x53, v); + dyesub_nputc(v, 0x00, 61); + /* Lamination. Fixed on. */ + stp_putc(0x1b, v); + stp_putc(0x59, v); + dyesub_nputc(v, 0x00, 62); + /* High Contrast */ + stp_putc(0x1b, v); + stp_putc(0x46, v); + stp_putc(0x43, v); + stp_putc(0x00, v); /* XXX or 0x01 for "High Contrast" */ + dyesub_nputc(v, 0x00, 60); + /* Print dimensions */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x53, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 57); +} + +static void mitsu_cp3020d_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + dyesub_nputc(v, 0x00, 62); +} + +static void mitsu_cp3020d_plane_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Plane data header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x30 + 4 - pd->plane, v); /* Y = x31, M = x32, C = x33 */ + dyesub_nputc(v, 0x00, 2); + stp_put16_be(0, v); /* Starting row for this block */ + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); /* Number of rows in this block */ + dyesub_nputc(v, 0x00, 53); +} + +static void mitsu_cp3020d_plane_end(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + /* Pad data to 64-byte block */ + unsigned int length = pd->w_size * pd->h_size; + length %= 64; + if (length) { + length = 64 - length; + dyesub_nputc(v, 0x00, length); + } +} + +/* Mitsubishi CP3020DA/DAE */ +static void mitsu_cp3020da_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Init */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x10, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 32); + /* Page count */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x20, v); + stp_putc(0x00, v); + stp_putc(0x02, v); + dyesub_nputc(v, 0x00, 19); + stp_putc(pd->copies > 50 ? 50 : pd->copies, v); /* 1-50 */ + dyesub_nputc(v, 0x00, 20); + /* Contrast ? */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0xf0, v); + dyesub_nputc(v, 0x00, 4); + stp_putc(0x00, v); /* x00 = Photo, x01 = High Contrast, x02 = Natural */ + dyesub_nputc(v, 0x00, 39); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x20, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 37); +} + +static void mitsu_cp3020da_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x51, v); + stp_putc(0x50, v); +} + +static void mitsu_cp3020da_plane_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Plane data header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x54, v); + stp_putc(0x00, v); + stp_put16_be(0, v); /* Starting column for this block */ + stp_put16_be(0, v); /* Starting row for this block */ + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); /* Number of rows in this block */ +} + +/* Mitsubishi 9500D/DW */ +static const dyesub_resolution_t res_m9500[] = +{ + { "346x346", 346, 346}, + { "346x792", 346, 792}, +}; + +LIST(dyesub_resolution_list_t, res_m9500_list, dyesub_resolution_t, res_m9500); + +static const dyesub_pagesize_t mitsu_cp9500_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1240,346), PT1(1812,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1416,346), PT1(2152,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1812,346), PT1(2452,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2152,346), PT1(2792,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(2152,346), PT1(3146,346), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9500_page_list, dyesub_pagesize_t, mitsu_cp9500_page); + +static const dyesub_printsize_t mitsu_cp9500_printsize[] = +{ + { "346x346", "B7", 1240, 1812}, + { "346x792", "B7", 2480, 1812}, + { "346x346", "w288h432", 1416, 2152}, + { "346x792", "w288h432", 2832, 2152}, + { "346x346", "w360h504", 1812, 2452}, + { "346x792", "w360h504", 1812, 4904}, + { "346x346", "w432h576", 2152, 2792}, + { "346x792", "w432h576", 2152, 5584}, + { "346x346", "w432h648", 2152, 3146}, + { "346x792", "w432h648", 2152, 6292}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9500_printsize_list, dyesub_printsize_t, mitsu_cp9500_printsize); + +static void mitsu_cp9500_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Init */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x22, v); + stp_putc(0xa8, v); + stp_putc(0x03, v); + dyesub_nputc(v, 0x00, 18); + stp_put16_be(pd->copies, v); + dyesub_nputc(v, 0x00, 19); + stp_putc(0x01, v); + /* Parameters 1 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x10, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 32); + /* Parameters 2 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0xf0, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(0x00, v); // XXX 0x01 for "High Contrast" mode + dyesub_nputc(v, 0x00, 38); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x70, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 36); +} + +static void mitsu_cp9500_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x57, v); + stp_putc(0x00, v); +} + +static const dyesub_stringitem_t mitsu9500_contrasts[] = +{ + { "Photo", N_ ("Photo") }, + { "HighContrast", N_ ("High Contrast") }, +}; +LIST(dyesub_stringlist_t, mitsu9500_contrast_list, dyesub_stringitem_t, mitsu9500_contrasts); + +static const stp_parameter_t mitsu9500_parameters[] = +{ + { + "CP9500Contrast", N_("Printer Contrast"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Contrast"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu9500_parameter_count (sizeof(mitsu9500_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu9500_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "CP9500Contrast") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu9500_contrast_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu9500_parse_parameters(stp_vars_t *v) +{ + const char *contrast = stp_get_string_parameter(v, "CP9500Contrast"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + if (strcmp(contrast, "HighContrast") == 0) { + pd->privdata.m9550.contrast = 1; + } else { + pd->privdata.m9550.contrast = 0; + } + + return 1; +} + +/* Mitsubishi 9550D/DW */ +static const dyesub_resolution_t res_346dpi[] = +{ + { "346x346", 346, 346}, +}; + +LIST(dyesub_resolution_list_t, res_346dpi_list, dyesub_resolution_t, res_346dpi); + +static const dyesub_pagesize_t mitsu_cp9550_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1240,346), PT1(1812,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1416,346), PT1(2152,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1416,346), PT1(2152,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1812,346), PT1(2452,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2152,346), PT1(2792,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(2152,346), PT1(2956,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(2152,346), PT1(3146,346), DYESUB_PORTRAIT), + /* XXX also 3.3x6 and 3.5x6! + XXX also 4x6*2, 4.4*6*2, 3x6*3, 2x6*4! (Built on 6x9 media) */ +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9550_page_list, dyesub_pagesize_t, mitsu_cp9550_page); + +static const dyesub_printsize_t mitsu_cp9550_printsize[] = +{ + { "346x346", "B7", 1240, 1812}, + { "346x346", "w288h432", 1416, 2152}, + { "346x346", "w288h432-div2", 1416, 2152}, + { "346x346", "w360h504", 1812, 2452}, + { "346x346", "w432h576", 2152, 2792}, + { "346x346", "w432h612", 2152, 2956}, + { "346x346", "w432h648", 2152, 3146}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9550_printsize_list, dyesub_printsize_t, mitsu_cp9550_printsize); + +static const dyesub_stringitem_t mitsu9550_qualities[] = +{ + { "Fine", N_ ("Fine") }, + { "SuperFine", N_ ("Super Fine") }, + { "FineDeep", N_ ("Fine Deep") } +}; +LIST(dyesub_stringlist_t, mitsu9550_quality_list, dyesub_stringitem_t, mitsu9550_qualities); + +static const stp_parameter_t mitsu9550_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu9550_parameter_count (sizeof(mitsu9550_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu9550_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu9550_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu9550_parse_parameters(stp_vars_t *v) +{ + const char *quality = stp_get_string_parameter(v, "PrintSpeed"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + pd->privdata.m9550.quality = 0; + pd->privdata.m9550.finedeep = 0; + + /* Parse options */ + if (strcmp(quality, "SuperFine") == 0) { + pd->privdata.m9550.quality = 0x80; + } else if (strcmp(quality, "FineDeep") == 0) { + pd->privdata.m9550.finedeep = 1; + } + + return 1; +} + +static void mitsu_cp9550_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Init */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x10, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 32); + /* Parameters 1 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x22, v); + stp_putc(0x08, v); + stp_putc(0x03, v); + dyesub_nputc(v, 0x00, 18); + stp_put16_be(pd->copies, v); + dyesub_nputc(v, 0x00, 2); + if (strcmp(pd->pagesize,"w288h432-div2") == 0) + stp_putc(0x83, v); + else + stp_putc(0x00, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(pd->privdata.m9550.quality, v); + dyesub_nputc(v, 0x00, 10); + stp_putc(0x01, v); + /* Parameters 2 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x22, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x40, v); + dyesub_nputc(v, 0x00, 5); + stp_putc(pd->privdata.m9550.finedeep, v); + dyesub_nputc(v, 0x00, 38); + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x70, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 36); +} + +static void mitsu_cp9550_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x46, v); + stp_putc(0x00, v); +} + +/* Mitsubishi CP9550DW-S */ + +static const dyesub_pagesize_t mitsu_cp9550s_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1416,346), PT1(2152,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1416,346), PT1(2152,346), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1812,346), PT1(2452,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(2152,346), PT1(2792,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(2152,346), PT1(2956,346), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(2152,346), PT1(3146,346), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9550s_page_list, dyesub_pagesize_t, mitsu_cp9550s_page); + +static const dyesub_printsize_t mitsu_cp9550s_printsize[] = +{ + { "346x346", "w288h432", 1416, 2152}, + { "346x346", "w288h432-div2", 1416, 2152}, + { "346x346", "w360h504", 1812, 2452}, + { "346x346", "w432h576", 2152, 2792}, + { "346x346", "w432h612", 2152, 2956}, + { "346x346", "w432h648", 2152, 3146}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9550s_printsize_list, dyesub_printsize_t, mitsu_cp9550s_printsize); + +static void mitsu_cp9550s_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x47, v); + stp_putc(0x00, v); +} + +/* Mitsubishi 9600D/DW */ +static const dyesub_resolution_t res_mitsu9600_dpi[] = +{ + { "300x300", 300, 300}, + { "600x600", 600, 600}, +}; + +LIST(dyesub_resolution_list_t, res_mitsu9600_dpi_list, dyesub_resolution_t, res_mitsu9600_dpi); + +static const dyesub_pagesize_t mitsu_cp9600_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1572,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1868,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1572,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1868,300), PT1(2442,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(1868,300), PT1(2564,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1868,300), PT1(2730,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9600_page_list, dyesub_pagesize_t, mitsu_cp9600_page); + +static const dyesub_printsize_t mitsu_cp9600_printsize[] = +{ + { "300x300", "B7", 1076, 1572}, + { "600x600", "B7", 2152, 3144}, + { "300x300", "w288h432", 1228, 1868}, + { "600x600", "w288h432", 2458, 3736}, + { "300x300", "w360h504", 1572, 2128}, + { "600x600", "w360h504", 3144, 4256}, + { "300x300", "w432h576", 1868, 2442}, + { "600x600", "w432h576", 3736, 4846}, + { "300x300", "w432h612", 1868, 2564}, + { "600x600", "w432h612", 3736, 5130}, + { "300x300", "w432h648", 1868, 2730}, + { "600x600", "w432h648", 3736, 5462}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9600_printsize_list, dyesub_printsize_t, mitsu_cp9600_printsize); + +static void mitsu_cp9600_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Parameters 1 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x22, v); + stp_putc(0x00, v); + stp_putc(0x03, v); + dyesub_nputc(v, 0x00, 18); + stp_put16_be(pd->copies, v); + dyesub_nputc(v, 0x00, 19); + stp_putc(0x01, v); + /* Parameters 2 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(0x10, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + dyesub_nputc(v, 0x00, 32); + /* Parameters 3 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x60, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 37); +} + +static void mitsu_cp9600_printer_end(stp_vars_t *v) +{ + /* Page Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x48, v); + stp_putc(0x00, v); +} + +/* Mitsubishi 9810D/DW */ +static const dyesub_pagesize_t mitsu_cp9810_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1572,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1868,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1572,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1868,300), PT1(2442,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(1868,300), PT1(2564,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1868,300), PT1(2730,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cp9810_page_list, dyesub_pagesize_t, mitsu_cp9810_page); + +static const dyesub_printsize_t mitsu_cp9810_printsize[] = +{ + { "300x300", "B7", 1076, 1572}, + { "300x300", "w288h432", 1228, 1868}, + { "300x300", "w360h504", 1572, 2128}, + { "300x300", "w432h576", 1868, 2442}, + { "300x300", "w432h612", 1868, 2564}, + { "300x300", "w432h648", 1868, 2730}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cp9810_printsize_list, dyesub_printsize_t, mitsu_cp9810_printsize); + +static const overcoat_t mitsu_cp9810_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x00"}}, + {"Matte", N_("Matte"), {1, "\x01"}}, +}; + +LIST(overcoat_list_t, mitsu_cp9810_overcoat_list, overcoat_t, mitsu_cp9810_overcoat); + +static const dyesub_stringitem_t mitsu9810_qualities[] = +{ + { "Fine", N_ ("Fine (Standard Media") }, + { "FineHG", N_ ("Fine (High Grade Media)") }, + { "SuperFine", N_ ("Super Fine") }, +}; +LIST(dyesub_stringlist_t, mitsu9810_quality_list, dyesub_stringitem_t, mitsu9810_qualities); + +static const stp_parameter_t mitsu98xx_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", + N_("Use Internal Color Correction"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu98xx_parameter_count (sizeof(mitsu98xx_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu98xx_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu9810_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "UseLUT") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu98xx_parse_parameters(stp_vars_t *v) +{ + const char *quality = stp_get_string_parameter(v, "PrintSpeed"); + dyesub_privdata_t *pd = get_privdata(v); + const overcoat_t *overcoat = NULL; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + pd->privdata.m9550.quality = 0; + + /* Parse options */ + if (strcmp(quality, "SuperFine") == 0) { + pd->privdata.m9550.quality = 0x80; + } else if (strcmp(quality, "FineHG") == 0) { + pd->privdata.m9550.quality = 0x11; /* Extension, backend corrects */ + } else if (strcmp(quality, "Fine") == 0) { + pd->privdata.m9550.quality = 0x10; + } + + pd->privdata.m70x.use_lut = stp_get_boolean_parameter(v, "UseLUT"); + + /* Matte lamination forces SuperFine mode */ + if (caps->overcoat) { + overcoat = dyesub_get_overcoat_pattern(v); + if (*((const char*)((overcoat->seq).data)) != 0x00) { + pd->privdata.m9550.quality = 0x80; + } + } + + return 1; +} + +static void mitsu_cp98xx_printer_init(stp_vars_t *v, int model) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Init */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x20, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x0a, v); + stp_putc(model, v); + dyesub_nputc(v, 0x00, 7); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + if (model == 0x90) { + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination */ + } else { + stp_putc(0x00, v); + } + dyesub_nputc(v, 0x00, 31); + + /* Parameters 1 */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x21, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x80, v); + stp_putc(0x00, v); + stp_putc(0x22, v); + stp_putc(0x08, v); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 18); + stp_put16_be(pd->copies, v); + dyesub_nputc(v, 0x00, 8); + stp_putc(pd->privdata.m9550.quality, v); + dyesub_nputc(v, 0x00, 9); + stp_putc(pd->privdata.m70x.use_lut, v); /* Use LUT? EXTENSION! */ + stp_putc(0x01, v); + + /* Unknown */ + stp_putc(0x1b, v); + stp_putc(0x57, v); + stp_putc(0x26, v); + stp_putc(0x2e, v); + stp_putc(0x00, v); + stp_putc(0x70, v); + dyesub_nputc(v, 0x00, 6); + stp_putc(0x01, v); + stp_putc(0x01, v); + dyesub_nputc(v, 0x00, 36); + + /* Put out a single plane header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x54, v); + stp_putc(0x80, v); /* special flag to say this is 8bpp packed BGR */ + stp_put16_be(0, v); /* Starting column for this block */ + stp_put16_be(0, v); /* Starting row for this block */ + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); /* Number of rows in this block */ +} + +static void mitsu_cp9810_printer_init(stp_vars_t *v) +{ + mitsu_cp98xx_printer_init(v, 0x90); +} + +static void mitsu_cp9800_printer_init(stp_vars_t *v) +{ + mitsu_cp98xx_printer_init(v, 0x10); +} + +static void mitsu_cp9810_printer_end(stp_vars_t *v) +{ + /* Job Footer */ + stp_putc(0x1b, v); + stp_putc(0x50, v); + stp_putc(0x4c, v); /* XXX 9800DW-S uses 0x4e, backend corrects */ + stp_putc(0x00, v); +} + +/* Mitsubishi CP-D70D/CP-D707 */ +static const dyesub_pagesize_t mitsu_cpd70x_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1568,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w360h504-div2", "3.5x5*2", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1820,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1864,300), PT1(2422,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(1864,300), PT1(2564,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1864,300), PT1(2730,300), DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1864,300), PT1(2730,300), 0, 0, PT1(236,300), 0, DYESUB_PORTRAIT), +#if 0 /* Theoretically supported, no way to test */ + DEFINE_PAPER_SIMPLE( "w432h576-div4", "2x6*4", PT1(1864,300), PT1(2730,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648-div3", "3x6*3", PT1(1864,300), PT1(2730,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648-div2", "4.4x6*2", PT1(1864,300), PT1(2730,300), DYESUB_PORTRAIT), +#endif +}; + +LIST(dyesub_pagesize_list_t, mitsu_cpd70x_page_list, dyesub_pagesize_t, mitsu_cpd70x_page); + +static const dyesub_printsize_t mitsu_cpd70x_printsize[] = +{ + { "300x300", "B7", 1076, 1568}, + { "300x300", "w288h432", 1228, 1864}, + { "300x300", "w288h432-div2", 1228, 1864}, + { "300x300", "w360h504", 1568, 2128}, + { "300x300", "w360h504-div2", 1568, 2128}, + { "300x300", "w432h432", 1820, 1864}, + { "300x300", "w432h576", 1864, 2422}, + { "300x300", "w432h612", 1864, 2564}, + { "300x300", "w432h648", 1864, 2730}, + { "300x300", "w432h576-div2", 1864, 2730}, +#if 0 + { "300x300", "w432h576-div4", 1864, 2730}, + { "300x300", "w432h648-div3", 1864, 2730}, + { "300x300", "w432h648-div2", 1864, 2730}, +#endif +}; + +LIST(dyesub_printsize_list_t, mitsu_cpd70x_printsize_list, dyesub_printsize_t, mitsu_cpd70x_printsize); + +static const overcoat_t mitsu_cpd70x_overcoat[] = +{ + {"Glossy", N_("Glossy"), {1, "\x00"}}, + {"Matte", N_("Matte"), {1, "\x02"}}, +}; + +LIST(overcoat_list_t, mitsu_cpd70x_overcoat_list, overcoat_t, mitsu_cpd70x_overcoat); + +static const dyesub_stringitem_t mitsu70x_qualities[] = +{ + { "Fine", N_ ("Fine") }, + { "SuperFine", N_ ("Super Fine") }, + { "UltraFine", N_ ("Ultra Fine") } +}; +LIST(dyesub_stringlist_t, mitsu70x_quality_list, dyesub_stringitem_t, mitsu70x_qualities); + +static const stp_parameter_t mitsu70x_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", + N_("Use Internal Color Correction"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 1 is min, 9 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu70x_parameter_count (sizeof(mitsu70x_parameters) / sizeof(const stp_parameter_t)) + +static const dyesub_stringitem_t mitsu707_decks[] = +{ + { "Auto", N_ ("Automatic") }, + { "Lower", N_ ("Lower Deck") }, + { "Upper", N_ ("Upper Deck") } +}; +LIST(dyesub_stringlist_t, mitsu707_deck_list, dyesub_stringitem_t, mitsu707_decks); + +static const stp_parameter_t mitsu707_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", + N_("Use Internal Color Correction"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 1 is min, 9 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Deck", N_("Printer Deck"), "Color=No,Category=Advanced Printer Setup", + N_("Printer Deck"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu707_parameter_count (sizeof(mitsu707_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu70x_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu70x_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "UseLUT") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 4; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 9; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int +mitsu707_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu70x_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "UseLUT") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 4; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 9; + description->is_active = 1; + } + else if (strcmp(name, "Deck") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu707_deck_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu70x_parse_parameters(stp_vars_t *v) +{ + const char *quality = stp_get_string_parameter(v, "PrintSpeed"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + if (strcmp(quality, "SuperFine") == 0) { + pd->privdata.m70x.quality = 3; + } else if (strcmp(quality, "UltraFine") == 0) { + pd->privdata.m70x.quality = 4; + } else if (strcmp(quality, "Fine") == 0) { + pd->privdata.m70x.quality = 0; + } else { + pd->privdata.m70x.quality = 0; + } + + /* For D707 only */ + pd->privdata.m70x.deck = 0; + if (stp_check_string_parameter(v, "Deck", STP_PARAMETER_ACTIVE)) { + const char *deck = stp_get_string_parameter(v, "Deck"); + if (strcmp(deck, "Auto") == 0) + pd->privdata.m70x.deck = 0; + else if (strcmp(deck, "Lower") == 0) + pd->privdata.m70x.deck = 1; + else if (strcmp(deck, "Upper") == 0) + pd->privdata.m70x.deck = 2; + } + + pd->privdata.m70x.use_lut = stp_get_boolean_parameter(v, "UseLUT"); + pd->privdata.m70x.sharpen = stp_get_int_parameter(v, "Sharpen"); + + return 1; +} + +static void mitsu_cpd70k60_job_start(stp_vars_t *v) +{ + /* Printer wakeup, once per job. */ + stp_putc(0x1b, v); + stp_putc(0x45, v); + stp_putc(0x57, v); + stp_putc(0x55, v); + dyesub_nputc(v, 0x00, 508); +} + +static void mitsu_cpd70k60_printer_init(stp_vars_t *v, unsigned char model) +{ + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + dyesub_privdata_t *pd = get_privdata(v); + + /* Each copy gets this.. */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x54, v); + stp_putc(model, v); /* k60 == x00, EK305 == x90, d70x/d80 == x01, ask300 = 0x80 */ + dyesub_nputc(v, 0x00, 12); + + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + if (caps->overcoat && *((const char*)((pd->overcoat->seq).data)) != 0x00) { + stp_put16_be(pd->w_size, v); + if (model == 0x00 || model == 0x90) { + pd->privdata.m70x.overcoat_offset = 0; + if (!pd->privdata.m70x.quality) + pd->privdata.m70x.quality = 4; /* Matte Lamination forces UltraFine on K60 or K305 */ + } else { + /* Overcoat a slightly larger boundary in Matte mode */ + pd->privdata.m70x.overcoat_offset = 12; + if (!pd->privdata.m70x.quality) + pd->privdata.m70x.quality = 3; /* Matte Lamination forces Superfine (or UltraFine) */ + } + stp_put16_be(pd->h_size + pd->privdata.m70x.overcoat_offset, v); + } else { + /* Glossy lamination here */ + stp_put16_be(0, v); + stp_put16_be(0, v); + } + stp_putc(pd->privdata.m70x.quality, v); + dyesub_nputc(v, 0x00, 7); + + if (model == 0x01) { + stp_putc(pd->privdata.m70x.deck, v); /* D70x: 0x00 Auto deck selection, 0x01 for Lower, 0x02 for Upper. */ + } else { + stp_putc(0x01, v); /* All others have a single "lower" deck */ + } + dyesub_nputc(v, 0x00, 7); + + stp_putc(0x00, v); /* Lamination always enabled */ + + if (caps->overcoat) { + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination mode */ + } else { + stp_putc(0x00, v); + } + dyesub_nputc(v, 0x00, 6); + + /* Multi-cut control */ + if (strcmp(pd->pagesize,"w432h576-div2") == 0) { + stp_putc(0x01, v); +#if 0 + } else if (strcmp(pd->pagesize,"w432h648-div2") == 0) { + stp_putc(0x02, v); + } else if (strcmp(pd->pagesize,"w432h648-div3") == 0) { + stp_putc(0x03, v); + } else if (strcmp(pd->pagesize,"w432h576-div4") == 0) { + stp_putc(0x04, v); +#endif + } else if (strcmp(pd->pagesize,"w360h504-div2") == 0) { + stp_putc(0x01, v); + } else if (strcmp(pd->pagesize,"w288h432-div2") == 0) { + stp_putc(0x05, v); + } else { + stp_putc(0x00, v); + } + dyesub_nputc(v, 0x00, 12); + /* The next four bytes are EXTENSIONS, backend consumes! */ + stp_putc(pd->privdata.m70x.sharpen, v); + stp_putc(0x01, v); /* Mark as 8bpp BGR rather than 16bpp YMC cooked */ + stp_putc(pd->privdata.m70x.use_lut, v); /* Use LUT? */ + stp_putc(0x01, v); /* Tell the backend the data's in the proper order */ + /* end extension */ + dyesub_nputc(v, 0x00, 447); /* Pad to 512-byte block */ +} + +static void mitsu_cpd70x_printer_init(stp_vars_t *v) +{ + mitsu_cpd70k60_printer_init(v, 0x01); +} + +/* Mitsubishi CP-K60D */ +static const dyesub_pagesize_t mitsu_cpk60_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1568,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1218,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1218,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w360h504-div2", "3.5x5*2", PT1(1568,300), PT1(2190,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1820,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1864,300), PT1(2422,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1864,300), PT1(2454,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cpk60_page_list, dyesub_pagesize_t, mitsu_cpk60_page); + +static const dyesub_printsize_t mitsu_cpk60_printsize[] = +{ + { "300x300", "B7", 1076, 1568}, + { "300x300", "w288h432", 1218, 1864}, + { "300x300", "w288h432-div2", 1218, 1864}, + { "300x300", "w360h504", 1568, 2128}, + { "300x300", "w360h504-div2", 1568, 2190}, + { "300x300", "w432h432", 1820, 1864}, + { "300x300", "w432h576", 1864, 2422}, + { "300x300", "w432h576-div2", 1864, 2454}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cpk60_printsize_list, dyesub_printsize_t, mitsu_cpk60_printsize); + +static void mitsu_cpk60_printer_init(stp_vars_t *v) +{ + mitsu_cpd70k60_printer_init(v, 0x00); +} + +/* Identical to the D70 except for one fewer quality mode */ +static const dyesub_stringitem_t mitsu_k60_qualities[] = +{ + { "Fine", N_ ("Fine") }, + { "UltraFine", N_ ("Ultra Fine") } +}; +LIST(dyesub_stringlist_t, mitsu_k60_quality_list, dyesub_stringitem_t, mitsu_k60_qualities); + +static int +mitsu_k60_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_k60_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "UseLUT") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 4; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 9; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static const dyesub_pagesize_t mitsu_cpd80_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h360", "5x5", PT1(1524,300), PT1(1568,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1864,300), PT1(1820,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1864,300), PT1(2422,300), DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1864,300), PT1(2730,300), 0, 0, PT1(236,300), 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cpd80_page_list, dyesub_pagesize_t, mitsu_cpd80_page); + +static const dyesub_printsize_t mitsu_cpd80_printsize[] = +{ + { "300x300", "w288h432", 1228, 1864}, + { "300x300", "w288h432-div2", 1228, 1864}, + { "300x300", "w360h360", 1524, 1568}, + { "300x300", "w360h504", 1568, 2128}, + { "300x300", "w432h432", 1864, 1820}, + { "300x300", "w432h576", 1864, 2422}, + { "300x300", "w432h576-div2", 1864, 2730}, +}; + +LIST(dyesub_printsize_list_t, mitsu_cpd80_printsize_list, dyesub_printsize_t, mitsu_cpd80_printsize); + +/* Kodak 305 */ +static const dyesub_pagesize_t kodak305_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1218,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1218,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1820,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1864,300), PT1(2422,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1864,300), PT1(2454,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, kodak305_page_list, dyesub_pagesize_t, kodak305_page); + +static const dyesub_printsize_t kodak305_printsize[] = +{ + { "300x300", "w288h432", 1218, 1864}, + { "300x300", "w288h432-div2", 1218, 1864}, + { "300x300", "w432h432", 1820, 1864}, + { "300x300", "w432h576", 1864, 2422}, + { "300x300", "w432h576-div2", 1864, 2454}, +}; + +LIST(dyesub_printsize_list_t, kodak305_printsize_list, dyesub_printsize_t, kodak305_printsize); + +static void kodak305_printer_init(stp_vars_t *v) +{ + mitsu_cpd70k60_printer_init(v, 0x90); +} + +/* Mitsubishi CP-D90D */ +static const dyesub_pagesize_t mitsu_cpd90_page[] = +{ + DEFINE_PAPER_SIMPLE( "w144h432", "2x6", PT1(625,300), PT1(1852,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1550,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1226,300), PT1(1852,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1226,300), PT1(1852,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1550,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w360h360", "5x5", PT1(1527,300), PT1(1550,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1827,300), PT1(1852,300), DYESUB_LANDSCAPE), + // XXX add 6x6+2x6! + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1852,300), PT1(2428,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1852,300), PT1(2488,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h612", "6x8.5", PT1(1852,300), PT1(2568,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1852,300), PT1(2729,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648-div2", "4.4x6*2", PT1(1852,300), PT1(2728,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648-div3", "3x6*2", PT1(1852,300), PT1(2724,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648-div4", "2x6*4", PT1(1852,300), PT1(2628,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, mitsu_cpd90_page_list, dyesub_pagesize_t, mitsu_cpd90_page); + +static const dyesub_printsize_t mitsu_cpd90_printsize[] = +{ + { "300x300", "w144h432", 625, 1852}, + { "300x300", "B7", 1076, 1550}, + { "300x300", "w288h432", 1226, 1852}, + { "300x300", "w288h432-div2", 1226, 1852}, + { "300x300", "w360h360", 1527, 1550}, + { "300x300", "w360h504", 1550, 2128}, + { "300x300", "w432h432", 1827, 1852}, + // XXX add 6x6+2x6! + { "300x300", "w432h576", 1852, 2428}, + { "300x300", "w432h576-div2", 1852, 2488}, + { "300x300", "w432h612", 1852, 2568}, + { "300x300", "w432h648", 1852, 2729}, + { "300x300", "w432h648-div2", 1852, 2728}, + { "300x300", "w432h648-div3", 1852, 2724}, + { "300x300", "w432h648-div4", 1852, 2628}, +}; +LIST(dyesub_printsize_list_t, mitsu_cpd90_printsize_list, dyesub_printsize_t, mitsu_cpd90_printsize); + +static const dyesub_stringitem_t mitsu_d90_qualities[] = +{ + { "Auto", N_ ("Automatic") }, + { "Fine", N_ ("Fine") }, + { "UltraFine", N_ ("Ultra Fine") } +}; +LIST(dyesub_stringlist_t, mitsu_d90_quality_list, dyesub_stringitem_t, mitsu_d90_qualities); + +static const stp_parameter_t mitsu_d90_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "UseLUT", N_("Internal Color Correction"), "Color=Yes,Category=Advanced Printer Setup", + N_("Use Internal Color Correction"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Sharpen", N_("Image Sharpening"), "Color=No,Category=Advanced Printer Setup", + N_("Sharpening to apply to image (0 is off, 1 is min, 9 is max"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "ComboWait", N_("Combo Print Wait Time"), "Color=No,Category=Advanced Printer Setup", + N_("How many seconds to wait for a second print before starting"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define mitsu_d90_parameter_count (sizeof(mitsu_d90_parameters) / sizeof(const stp_parameter_t)) + +static int +mitsu_d90_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &mitsu_d90_quality_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "UseLUT") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "Sharpen") == 0) + { + description->deflt.integer = 4; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 9; + description->is_active = 1; + } + else if (strcmp(name, "ComboWait") == 0) + { + description->deflt.integer = 5; + description->bounds.integer.lower = 1; + description->bounds.integer.upper = 25; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int mitsu_d90_parse_parameters(stp_vars_t *v) +{ + const char *quality = stp_get_string_parameter(v, "PrintSpeed"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + if (strcmp(quality, "UltraFine") == 0) { + pd->privdata.m70x.quality = 3; + } else if (strcmp(quality, "Fine") == 0) { + pd->privdata.m70x.quality = 2; + } else { + pd->privdata.m70x.quality = 0; + } + + pd->privdata.m70x.use_lut = stp_get_boolean_parameter(v, "UseLUT"); + pd->privdata.m70x.sharpen = stp_get_int_parameter(v, "Sharpen"); + pd->privdata.m70x.delay = stp_get_int_parameter(v, "ComboWait"); + + return 1; +} + +static void mitsu_cpd90_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Start things going */ + stp_putc(0x1b, v); + stp_putc(0x53, v); + stp_putc(0x50, v); + stp_putc(0x30, v); + stp_putc(0x00, v); + stp_putc(0x33, v); + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ + stp_putc(0x64, v); + stp_putc(0x00, v); + stp_putc(0x00, v); + stp_putc(0x01, v); + stp_putc(0x00, v); + + if (strcmp(pd->pagesize,"w432h576-div2") == 0) { + stp_putc(0x01, v); + stp_putc(0x04, v); + stp_putc(0xbe, v); + dyesub_nputc(v, 0x00, 6); + } else if (strcmp(pd->pagesize,"w288h432-div2") == 0) { + stp_putc(0x00, v); + stp_putc(0x02, v); + stp_putc(0x65, v); + dyesub_nputc(v, 0x00, 6); + } else if (strcmp(pd->pagesize,"w432h648-div2") == 0) { + stp_putc(0x01, v); + stp_putc(0x05, v); + stp_putc(0x36, v); + dyesub_nputc(v, 0x00, 6); + } else if (strcmp(pd->pagesize,"w432h648-div3") == 0) { + stp_putc(0x00, v); + stp_putc(0x03, v); + stp_putc(0x90, v); + stp_putc(0x00, v); + stp_putc(0x07, v); + stp_putc(0x14, v); + dyesub_nputc(v, 0x00, 3); + } else if (strcmp(pd->pagesize,"w432h648-div4") == 0) { + stp_putc(0x00, v); + stp_putc(0x02, v); + stp_putc(0x97, v); + stp_putc(0x00, v); + stp_putc(0x05, v); + stp_putc(0x22, v); + stp_putc(0x00, v); + stp_putc(0x07, v); + stp_putc(0xad, v); + } else { + dyesub_nputc(v, 0x00, 9); + } + dyesub_nputc(v, 0x00, 24); + + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination mode */ + stp_putc(pd->privdata.m70x.quality, v); + stp_putc(pd->privdata.m70x.use_lut, v); + stp_putc(pd->privdata.m70x.sharpen, v); /* Horizontal */ + stp_putc(pd->privdata.m70x.sharpen, v); /* Vertical */ + dyesub_nputc(v, 0x00, 11); + + dyesub_nputc(v, 0x00, 512 - 64); + + /* Data Plane header */ + stp_putc(0x1b, v); + stp_putc(0x5a, v); + stp_putc(0x54, v); + stp_putc(0x01, v); + stp_putc(0x00, v); + stp_putc(0x09, v); + dyesub_nputc(v, 0x00, 4); + stp_put16_be(pd->w_size, v); /* Columns */ + stp_put16_be(pd->h_size, v); /* Rows */ + dyesub_nputc(v, 0x00, 2); + + dyesub_nputc(v, 0x00, 512 - 16); +} + +static void mitsu_cpd90_job_end(stp_vars_t *v) +{ + int delay; + if (stp_check_int_parameter(v, "ComboWait", STP_PARAMETER_ACTIVE)) + delay = stp_get_int_parameter(v, "ComboWait"); + else + delay = 5; + + /* Wrap it up */ + stp_putc(0x1b, v); + stp_putc(0x42, v); + stp_putc(0x51, v); + stp_putc(0x31, v); + stp_putc(0x00, v); + stp_putc(delay, v); +} + +/* Fujifilm ASK-300 */ +static const dyesub_pagesize_t fuji_ask300_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1076,300), PT1(1568,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1864,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w360h504-div2", "3.5x5*2", PT1(1568,300), PT1(2128,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1864,300), PT1(2422,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1864,300), PT1(2730,300), DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1864,300), PT1(2730,300), 0, 0, PT1(236,300), 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, fuji_ask300_page_list, dyesub_pagesize_t, fuji_ask300_page); + +static const dyesub_printsize_t fuji_ask300_printsize[] = +{ + { "300x300", "B7", 1076, 1568}, + { "300x300", "w288h432", 1228, 1864}, + { "300x300", "w288h432-div2", 1228, 1864}, + { "300x300", "w360h504", 1568, 2128}, + { "300x300", "w360h504-div2", 1568, 2128}, + { "300x300", "w432h576", 1864, 2422}, + { "300x300", "w432h648", 1864, 2730}, + { "300x300", "w432h576-div2", 1864, 2730}, +}; + +LIST(dyesub_printsize_list_t, fuji_ask300_printsize_list, dyesub_printsize_t, fuji_ask300_printsize); + +static void fuji_ask300_printer_init(stp_vars_t *v) +{ + mitsu_cpd70k60_printer_init(v, 0x80); +} + +/* Fujifilm ASK-2000/2500 */ +static const dyesub_pagesize_t fuji_ask2000_page[] = +{ + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1074,300), PT1(1536,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1228,300), PT1(1832,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1568,300), PT1(2130,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1832,300), PT1(2432,300), DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1832,300), PT1(2732,300), 0, 0, PT1(236,300), 0, DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1832,300), PT1(2748,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, fuji_ask2000_page_list, dyesub_pagesize_t, fuji_ask2000_page); + +static const dyesub_printsize_t fuji_ask2000_printsize[] = +{ + { "300x300", "B7", 1074, 1536}, + { "300x300", "w288h432", 1228, 1832}, + { "300x300", "w360h504", 1536, 2130}, + { "300x300", "w432h576", 1864, 2432}, + { "300x300", "w432h576-div2", 1864, 2732}, + { "300x300", "w432h648", 1864, 2748}, +}; + +LIST(dyesub_printsize_list_t, fuji_ask2000_printsize_list, dyesub_printsize_t, fuji_ask2000_printsize); + +static void fuji_ask2000_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x1b\x23\x00\x00\x00\x04\x00\xff\xff\xff\xff", 1, 11, v); + stp_zfwrite("\x1b\x1e\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 1, 19, v); + stp_zfwrite("\x1b\xee\x00\x00\x00\x02\x00", 1, 7, v); + stp_put16_be(pd->copies, v); + stp_zfwrite("\x1b\xe1\x00\x00\x00\x0b\x00\x00\x04\x0c\x00\x00\x00\x00", 1, 14, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\x1b\x15\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00", 1, 16, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\x1b\xea\x00\x00\x00\x00", 1, 6, v); + stp_put32_be(pd->w_size * pd->h_size * 3, v); /* Data length */ + stp_putc(0x00, v); +} + +static void fuji_ask2000_printer_end(stp_vars_t *v) +{ + stp_zfwrite("\x1b\x23\x00\x00\x00\x04\x00\xff\xff\xff\xff", 1, 11, v); + stp_zfwrite("\x1b\x0a\x00\x00\x00\x00\x00", 1, 7, v); + stp_zfwrite("\x1b\x23\x00\x00\x00\x04\x00\xff\xff\xff\xff", 1, 11, v); +} + +/* Fujifilm ASK-4000 */ +static const dyesub_pagesize_t fuji_ask4000_page[] = +{ + DEFINE_PAPER_SIMPLE( "c8x10", "8x10", PT1(2444,300), PT1(3044,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864", "8x12", PT1(2444,300), PT1(3644,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, fuji_ask4000_page_list, dyesub_pagesize_t, fuji_ask4000_page); + +static const dyesub_printsize_t fuji_ask4000_printsize[] = +{ + { "300x300", "c8x10", 2444, 3044}, + { "300x300", "w576h864", 2444, 3644}, +}; + +LIST(dyesub_printsize_list_t, fuji_ask4000_printsize_list, dyesub_printsize_t, fuji_ask4000_printsize); + +static void fuji_ask4000_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_zfwrite("\x1b\x1e\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 1, 19, v); + stp_zfwrite("\x1b\xee\x00\x00\x00\x02\x00", 1, 7, v); + stp_put16_be(pd->copies, v); + stp_zfwrite("\x1b\xe1\x00\x00\x00\x0b\x00\x00\x04\x0c\x00\x00\x00\x00", 1, 14, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + stp_zfwrite("\x1b\xea\x00\x00\x00\x00", 1, 6, v); + stp_put32_be(pd->w_size * pd->h_size * 3, v); /* Data length */ + stp_putc(0x00, v); +} + +static void fuji_ask4000_printer_end(stp_vars_t *v) +{ + stp_zfwrite("\x1b\x0a\x00\x00\x00\x00\x00", 1, 7, v); +} + +/* Shinko CHC-S9045 (experimental) */ +static const dyesub_pagesize_t shinko_chcs9045_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7","3.5x5", PT1(1088,300), PT1(1548,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1844,300), PT1(2740,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w283h425", "Sticker paper", PT1(1092,300), PT1(1726,300), DYESUB_LANDSCAPE), +}; + +LIST(dyesub_pagesize_list_t, shinko_chcs9045_page_list, dyesub_pagesize_t, shinko_chcs9045_page); + +static const dyesub_printsize_t shinko_chcs9045_printsize[] = +{ + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "B7", 1088, 1548}, + { "300x300", "w360h504", 1548, 2140}, + { "300x300", "w432h648", 1844, 2740}, + { "300x300", "w283h425", 1092, 1726}, +}; + +LIST(dyesub_printsize_list_t, shinko_chcs9045_printsize_list, dyesub_printsize_t, shinko_chcs9045_printsize); + +static void shinko_chcs9045_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char pg = '\0'; + char sticker = '\0'; + + stp_zprintf(v, "\033CHC\n"); + stp_put16_be(1, v); + stp_put16_be(1, v); + stp_put16_be(pd->w_size, v); + stp_put16_be(pd->h_size, v); + if (strcmp(pd->pagesize,"B7") == 0) + pg = '\1'; + else if (strcmp(pd->pagesize,"w360h504") == 0) + pg = '\3'; + else if (strcmp(pd->pagesize,"w432h576") == 0) + pg = '\5'; + else if (strcmp(pd->pagesize,"w283h425") == 0) + sticker = '\3'; + stp_putc(pg, v); + stp_putc('\0', v); + stp_putc(sticker, v); + dyesub_nputc(v, '\0', 4338); +} + +/* Shinko CHC-S2145 */ +static const dyesub_pagesize_t shinko_chcs2145_page[] = +{ + DEFINE_PAPER_SIMPLE( "w144h432", "2x6", PT1(634,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "B7", "3.5x5", PT1(1088,300), PT1(1548,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1844,300), PT1(2492,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1844,300), PT1(2740,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, shinko_chcs2145_page_list, dyesub_pagesize_t, shinko_chcs2145_page); + +static const dyesub_printsize_t shinko_chcs2145_printsize[] = +{ + { "300x300", "w144h432", 634, 1844}, + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w288h432-div2", 1240, 1844}, + { "300x300", "B7", 1088, 1548}, + { "300x300", "w360h504", 1548, 2140}, + { "300x300", "w432h576", 1844, 2434}, + { "300x300", "w432h576-div2", 1844, 2492}, + { "300x300", "w432h648", 1844, 2740}, +}; + +LIST(dyesub_printsize_list_t, shinko_chcs2145_printsize_list, dyesub_printsize_t, shinko_chcs2145_printsize); + +static const overcoat_t shinko_chcs2145_overcoat[] = +{ + {"PrinterDefault", N_("Printer Default"), {4, "\x01\0\0\0"}}, + {"Glossy", N_("Glossy"), {4, "\x02\0\0\0"}}, + {"GlossyFine", N_("Glossy Fine"), {4, "\x03\0\0\0"}}, + {"Matte", N_("Matte"), {4, "\x04\0\0\0"}}, + {"MatteFine", N_("Matte Fine"), {4, "\x05\0\0\0"}}, + {"ExtraGlossy", N_("Extra Glossy"), {4, "\x06\0\0\0"}}, + {"ExtraGlossyFine", N_("Extra Glossy Fine"), {4, "\x07\0\0\0"}}, +}; + +LIST(overcoat_list_t, shinko_chcs2145_overcoat_list, overcoat_t, shinko_chcs2145_overcoat); + +static void shinko_chcs2145_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + int media = 0; + + if (strcmp(pd->pagesize,"w288h432") == 0) + media = '\0'; + else if (strcmp(pd->pagesize,"w288h432-div2") == 0) + media = '\0'; + else if (strcmp(pd->pagesize,"B7") == 0) + media = '\1'; + else if (strcmp(pd->pagesize,"w360h504") == 0) + media = '\3'; + else if (strcmp(pd->pagesize,"w432h576") == 0) + media = '\6'; + else if (strcmp(pd->pagesize,"w432h648") == 0) + media = '\5'; + else if (strcmp(pd->pagesize,"w432h576-div2") == 0) + media = '\5'; + else if (strcmp(pd->pagesize,"w144h432") == 0) + media = '\7'; + + stp_put32_le(0x10, v); + stp_put32_le(2145, v); /* Printer Model */ + stp_put32_le(0x00, v); + stp_put32_le(0x01, v); + + stp_put32_le(0x64, v); + stp_put32_le(0x00, v); + stp_put32_le(media, v); /* Media Type */ + stp_put32_le(0x00, v); + + if (strcmp(pd->pagesize,"w432h576-div2") == 0) { + stp_put32_le(0x02, v); + } else if (strcmp(pd->pagesize,"w288h432-div2") == 0) { + stp_put32_le(0x04, v); + } else { + stp_put32_le(0x00, v); /* Print Method */ + } + + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Print Mode */ + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); + stp_put32_le(pd->w_size, v); /* Columns */ + stp_put32_le(pd->h_size, v); /* Rows */ + stp_put32_le(pd->copies, v); /* Copies */ + + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(pd->w_dpi, v); /* Dots Per Inch */ + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); +} + +static void shinko_chcs2145_printer_end(stp_vars_t *v) +{ + stp_putc(0x04, v); + stp_putc(0x03, v); + stp_putc(0x02, v); + stp_putc(0x01, v); +} + +/* Shinko CHC-S1245 */ +static const dyesub_pagesize_t shinko_chcs1245_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h576", "8x4", PT1(1229,300), PT1(2446,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h576", "8x5", PT1(1530,300), PT1(2446,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "8x6", PT1(1831,300), PT1(2446,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w576h576", "8x8", PT1(2436,300), PT1(2446,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w576h576-div2", "8x4*2", PT1(2446,300), PT1(2468,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "c8x10", "8x10", PT1(2446,300), PT1(3036,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "c8x10-w576h432_w576h288", "8x6+8x4", PT1(2446,300), PT1(3070,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "c8x10-div2", "8x5*2", PT1(2446,300), PT1(3070,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864", "8x12", PT1(2446,300), PT1(3636,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864-div2", "8x6*2", PT1(2446,300), PT1(3672,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864-div3", "8x4*3", PT1(2446,300), PT1(3707,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, shinko_chcs1245_page_list, dyesub_pagesize_t, shinko_chcs1245_page); + +static const dyesub_printsize_t shinko_chcs1245_printsize[] = +{ + { "300x300", "w288h576", 1229, 2446}, + { "300x300", "w360h576", 1530, 2446}, + { "300x300", "w432h576", 1831, 2446}, + { "300x300", "w576h576", 2436, 2446}, + { "300x300", "w576h576-div2", 2446, 2468}, + { "300x300", "c8x10", 2446, 3036}, + { "300x300", "c8x10-w576h432_w576h288", 2446, 3070}, + { "300x300", "c8x10-div2", 2446, 3070}, + { "300x300", "w576h864", 2446, 3636}, + { "300x300", "w576h864-div2", 2446, 3672}, + { "300x300", "w576h864-div3", 2446, 3707}, +}; + +LIST(dyesub_printsize_list_t, shinko_chcs1245_printsize_list, dyesub_printsize_t, shinko_chcs1245_printsize); + +static const overcoat_t shinko_chcs1245_overcoat[] = +{ + {"PrinterDefault", N_("Printer Default"), {4, "\x01\x00\x00\x00"}}, + {"Glossy", N_("Glossy"), {4, "\x02\x00\x00\x00"}}, + {"GlossyFine", N_("Glossy Fine"), {4, "\x03\x00\x00\x00"}}, + {"Matte", N_("Matte"), {4, "\x04\x00\x00\x00"}}, + {"MatteFine", N_("Matte Fine"), {4, "\x05\x00\x00\x00"}}, +}; + +LIST(overcoat_list_t, shinko_chcs1245_overcoat_list, overcoat_t, shinko_chcs1245_overcoat); + +static const dyesub_stringitem_t shinko_chcs1245_dusts[] = +{ + { "PrinterDefault", N_ ("Printer Default") }, + { "Off", N_ ("Off") }, + { "On", N_ ("On") } +}; +LIST(dyesub_stringlist_t, shinko_chcs1245_dust_list, dyesub_stringitem_t, shinko_chcs1245_dusts); + +static const stp_parameter_t shinko_chcs1245_parameters[] = +{ + { + "DustRemoval", N_("Dust Removal"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MatteIntensity", N_("Matte Intensity"), "Color=No,Category=Advanced Printer Setup", + N_("Strength of matte lamination pattern (-25 through +25)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define shinko_chcs1245_parameter_count (sizeof(shinko_chcs1245_parameters) / sizeof(const stp_parameter_t)) + +static int +shinko_chcs1245_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "DustRemoval") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &shinko_chcs1245_dust_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "MatteIntensity") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -25; + description->bounds.integer.upper = 25; + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int shinko_chcs1245_parse_parameters(stp_vars_t *v) +{ + const char *dust = stp_get_string_parameter(v, "DustRemoval"); + dyesub_privdata_t *pd = get_privdata(v); + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Parse options */ + + if (strcmp(dust, "PrinterDefault") == 0) { + pd->privdata.s1245.dust_removal = 3; + } else if (strcmp(dust, "Off") == 0) { + pd->privdata.s1245.dust_removal = 1; + } else if (strcmp(dust, "On") == 0) { + pd->privdata.s1245.dust_removal = 2; + } else { + pd->privdata.s1245.dust_removal = 0; + } + + pd->privdata.s1245.matte_intensity = stp_get_int_parameter(v, "MatteIntensity"); + + return 1; +} + +static void shinko_chcs1245_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + int media = 0; + + if (strcmp(pd->pagesize,"w288h576") == 0) + media = 5; + else if (strcmp(pd->pagesize,"w360h576") == 0) + media = 4; + else if (strcmp(pd->pagesize,"w432h576") == 0) + media = 6; + else if (strcmp(pd->pagesize,"w576h576") == 0) + media = 9; + else if (strcmp(pd->pagesize,"w576h576-div2") == 0) + media = 2; + else if (strcmp(pd->pagesize,"c8x10") == 0) + media = 0; + else if (strcmp(pd->pagesize,"c8x10-w576h432_w576h288") == 0) + media = 3; + else if (strcmp(pd->pagesize,"c8x10-div2") == 0) + media = 1; + else if (strcmp(pd->pagesize,"w576h864") == 0) + media = 0; + else if (strcmp(pd->pagesize,"w576h864-div2") == 0) + media = 7; + else if (strcmp(pd->pagesize,"w576h864-div3") == 0) + media = 8; + + stp_put32_le(0x10, v); + stp_put32_le(1245, v); /* Printer Model */ + stp_put32_le(0x00, v); + stp_put32_le(0x01, v); + + stp_put32_le(0x64, v); + stp_put32_le(0x00, v); + stp_put32_le(0x10, v); /* Seems to be fixed */ + stp_put32_le(0x00, v); + + stp_put32_le(media, v); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Print Mode */ + stp_put32_le(0x00, v); + if (((const unsigned char*)(pd->overcoat->seq).data)[0] == 0x02 || + ((const unsigned char*)(pd->overcoat->seq).data)[0] == 0x03) { + stp_put32_le(0x07fffffff, v); /* Glossy */ + } else { + stp_put32_le(pd->privdata.s1245.matte_intensity, v); /* matte intensity */ + } + + stp_put32_le(pd->privdata.s1245.dust_removal, v); /* Dust Removal Mode */ + stp_put32_le(pd->w_size, v); /* Columns */ + stp_put32_le(pd->h_size, v); /* Rows */ + stp_put32_le(pd->copies, v); /* Copies */ + + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(pd->w_dpi, v); /* Dots Per Inch */ + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); +} + +/* Shinko CHC-S6245 */ +static const dyesub_pagesize_t shinko_chcs6245_page[] = +{ + DEFINE_PAPER_SIMPLE( "w288h576", "8x4", PT1(1236,300), PT1(2464,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h576", "8x5", PT1(1536,300), PT1(2464,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "8x6", PT1(1836,300), PT1(2464,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w576h576", "8x8", PT1(2436,300), PT1(2464,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w576h576-div2", "8x4*2", PT1(2464,300), PT1(2494,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "c8x10", "8x10", PT1(2464,300), PT1(3036,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "c8x10-div2", "8x5*2", PT1(2464,300), PT1(3094,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864", "8x12", PT1(2464,300), PT1(3636,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864-div2", "8x6*2", PT1(2464,300), PT1(3694,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w576h864-div3", "8x4*3", PT1(2464,300), PT1(3742,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, shinko_chcs6245_page_list, dyesub_pagesize_t, shinko_chcs6245_page); + +static const dyesub_printsize_t shinko_chcs6245_printsize[] = +{ + { "300x300", "w288h576", 1236, 2464}, + { "300x300", "w360h576", 1536, 2464}, + { "300x300", "w432h576", 1836, 2464}, + { "300x300", "w576h576", 2436, 2464}, + { "300x300", "w576h576-div2", 2464, 2494}, + { "300x300", "c8x10", 2464, 3036}, + { "300x300", "c8x10-div2", 2464, 3094}, + { "300x300", "w576h864", 2464, 3636}, + { "300x300", "w576h864-div2", 2464, 3694}, + { "300x300", "w576h864-div3", 2464, 3742}, +}; + +LIST(dyesub_printsize_list_t, shinko_chcs6245_printsize_list, dyesub_printsize_t, shinko_chcs6245_printsize); + +static const overcoat_t shinko_chcs6245_overcoat[] = +{ + {"Glossy", N_("Glossy"), {4, "\x03\x00\x00\x00"}}, + {"Matte", N_("Matte"), {4, "\x02\x00\x00\x00"}}, + {"None", N_("None"), {4, "\x01\x00\x00\x00"}}, +}; + +LIST(overcoat_list_t, shinko_chcs6245_overcoat_list, overcoat_t, shinko_chcs6245_overcoat); + +static void shinko_chcs6245_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + int media = 0; + + if (strcmp(pd->pagesize,"w288h576") == 0) + media = 0x20; + else if (strcmp(pd->pagesize,"w360h576") == 0) + media = 0x21; + else if (strcmp(pd->pagesize,"w432h576") == 0) + media = 0x22; + else if (strcmp(pd->pagesize,"w576h576") == 0) + media = 0x23; + else if (strcmp(pd->pagesize,"c8x10") == 0) + media = 0x10; + else if (strcmp(pd->pagesize,"w576h864") == 0) + media = 0x11; + else if (strcmp(pd->pagesize,"w576h576-div2") == 0) + media = 0x30; + else if (strcmp(pd->pagesize,"c8x10-div2") == 0) + media = 0x31; + else if (strcmp(pd->pagesize,"w576h864-div2") == 0) + media = 0x32; + else if (strcmp(pd->pagesize,"w576h864-div3") == 0) + media = 0x40; + + stp_put32_le(0x10, v); + stp_put32_le(6245, v); /* Printer Model */ + stp_put32_le(0x01, v); + stp_put32_le(0x01, v); + + stp_put32_le(0x64, v); + stp_put32_le(0x00, v); + stp_put32_le(media, v); + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination */ + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); + stp_put32_le(pd->w_size, v); /* Columns */ + stp_put32_le(pd->h_size, v); /* Rows */ + stp_put32_le(pd->copies, v); /* Copies */ + + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(pd->w_dpi, v); /* Dots Per Inch */ + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); +} + +/* Shinko CHC-S6145 */ +static const dyesub_pagesize_t shinko_chcs6145_page[] = +{ + DEFINE_PAPER_SIMPLE( "w144h432", "2x6", PT1(634,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h360", "5x5", PT1(1536,300), PT1(1548,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h432", "6x6", PT1(1832,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-w432h432_w432h144", "6x6+2x6", PT1(1844,300), PT1(2434,300),DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1844,300), PT1(2492,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h648", "6x9", PT1(1844,300), PT1(2740,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, shinko_chcs6145_page_list, dyesub_pagesize_t, shinko_chcs6145_page); + +static const dyesub_printsize_t shinko_chcs6145_printsize[] = +{ + { "300x300", "w144h432", 634, 1844}, + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w288h432-div2", 1240, 1844}, + { "300x300", "w360h360", 1536, 1548}, + { "300x300", "w360h504", 1548, 2140}, + { "300x300", "w432h432", 1832, 1844}, + { "300x300", "w432h576", 1844, 2434}, + { "300x300", "w432h576-w432h432_w432h144", 1844, 2434}, + { "300x300", "w432h576-div2", 1844, 2492}, + { "300x300", "w432h648", 1844, 2740}, +}; + +LIST(dyesub_printsize_list_t, shinko_chcs6145_printsize_list, dyesub_printsize_t, shinko_chcs6145_printsize); + +static const overcoat_t shinko_chcs6145_overcoat[] = +{ + {"PrinterDefault", N_("Printer Default"), {4, "\0\0\0\0"}}, + {"None", N_("None"), {4, "\x01\0\0\0"}}, + {"Glossy", N_("Glossy"), {4, "\x02\0\0\0"}}, + {"Matte", N_("Matte"), {4, "\x03\0\0\0"}}, +}; + +LIST(overcoat_list_t, shinko_chcs6145_overcoat_list, overcoat_t, shinko_chcs6145_overcoat); + +static void shinko_chcs6145_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + int media = 0; + + if (strcmp(pd->pagesize,"w288h432") == 0) + media = 0x00; + else if (strcmp(pd->pagesize,"w288h432-div2") == 0) + media = 0x00; + else if (strcmp(pd->pagesize,"w360h360") == 0) + media = 0x08; + else if (strcmp(pd->pagesize,"w360h504") == 0) + media = 0x03; + else if (strcmp(pd->pagesize,"w432h432") == 0) + media = 0x06; + else if (strcmp(pd->pagesize,"w432h576") == 0) + media = 0x06; + else if (strcmp(pd->pagesize,"w144h432") == 0) + media = 0x07; + else if (strcmp(pd->pagesize,"w432h576-w432h432_w432h144") == 0) + media = 0x06; + else if (strcmp(pd->pagesize,"w432h576-div2") == 0) + media = 0x06; + else if (strcmp(pd->pagesize,"w432h648") == 0) + media = 0x05; + + stp_put32_le(0x10, v); + stp_put32_le(6145, v); /* Printer Model */ + if (!strcmp(pd->pagesize,"w360h360") || + !strcmp(pd->pagesize,"w360h504")) + stp_put32_le(0x02, v); /* 5" media */ + else + stp_put32_le(0x03, v); /* 6" media */ + stp_put32_le(0x01, v); + + stp_put32_le(0x64, v); + stp_put32_le(0x00, v); + stp_put32_le(media, v); /* Media Type */ + stp_put32_le(0x00, v); + + if (strcmp(pd->pagesize,"w432h576-w432h432_w432h144") == 0) { + stp_put32_le(0x05, v); + } else if (strcmp(pd->pagesize,"w288h432-div2") == 0) { + stp_put32_le(0x04, v); + } else if (strcmp(pd->pagesize,"w432h576-div2") == 0) { + stp_put32_le(0x02, v); + } else { + stp_put32_le(0x00, v); + } + stp_put32_le(0x00, v); /* XXX quality; 00 == default, 0x01 == std */ + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination */ + stp_put32_le(0x00, v); + + stp_put32_le(0x00, v); + stp_put32_le(pd->w_size, v); /* Columns */ + stp_put32_le(pd->h_size, v); /* Rows */ + stp_put32_le(pd->copies, v); /* Copies */ + + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(pd->w_dpi, v); /* Dots Per Inch */ + stp_put32_le(0xffffffce, v); + + stp_put32_le(0x00, v); + stp_put32_le(0xffffffce, v); + stp_put32_le(0x00, v); + stp_put32_le(0x00, v); + +#ifdef S6145_YMC + stp_put32_le(0x01, v); +#else + stp_put32_le(0x00, v); +#endif +} + +/* Ciaat Brava 21 */ +static const dyesub_pagesize_t ciaat_brava21_page[] = +{ + DEFINE_PAPER_SIMPLE( "w144h432", "2x6", PT1(634,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432", "4x6", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1844,300), DYESUB_LANDSCAPE), + DEFINE_PAPER_SIMPLE( "w360h504", "5x7", PT1(1548,300), PT1(2140,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576", "6x8", PT1(1844,300), PT1(2434,300), DYESUB_PORTRAIT), + DEFINE_PAPER_SIMPLE( "w432h576-div2", "4x6*2", PT1(1844,300), PT1(2492,300), DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, ciaat_brava21_page_list, dyesub_pagesize_t, ciaat_brava21_page); + +static const dyesub_printsize_t ciaat_brava21_printsize[] = +{ + { "300x300", "w144h432", 634, 1844}, + { "300x300", "w288h432", 1240, 1844}, + { "300x300", "w288h432-div2", 1240, 1844}, + { "300x300", "w360h504", 1548, 2140}, + { "300x300", "w432h576", 1844, 2434}, + { "300x300", "w432h576-div2", 1844, 2492}, +}; + +LIST(dyesub_printsize_list_t, ciaat_brava21_printsize_list, dyesub_printsize_t, ciaat_brava21_printsize); + +/* Dai Nippon Printing DS40 */ +static const dyesub_resolution_t res_dnpds40_dpi[] = +{ + { "300x300", 300, 300}, + { "300x600", 300, 600}, +}; + +LIST(dyesub_resolution_list_t, res_dnpds40_dpi_list, dyesub_resolution_t, res_dnpds40_dpi); + +/* Imaging area is wider than print size, we always must supply the printer with the full imaging width. */ +static const dyesub_pagesize_t dnpds40_page[] = +{ + DEFINE_PAPER( "B7", "3.5x5", PT1(1088,300), PT1(1920,300), 0, 0, PT(186,300), PT(186,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432", "4x6", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h504", "5x7", PT1(1920,300), PT1(2138,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w360h504-div2", "3.5x5*2", PT1(1920,300), PT1(2176,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h432", "6x6", PT1(1836,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "6x8", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div4", "2x6*4", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1920,300), PT1(2498,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-w432h432_w432h144", "6x6+2x6", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h648", "6x9", PT1(1920,300), PT1(2740,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dnpds40_page_list, dyesub_pagesize_t, dnpds40_page); + +static const dyesub_printsize_t dnpds40_printsize[] = +{ + { "300x300", "B7", 1088, 1920}, + { "300x600", "B7", 2176, 1920}, + { "300x300", "w288h432", 1240, 1920}, + { "300x600", "w288h432", 2480, 1920}, + { "300x300", "w288h432-div2", 1240, 1920}, + { "300x600", "w288h432-div2", 2480, 1920}, + { "300x300", "w360h504", 1920, 2138}, + { "300x600", "w360h504", 1920, 4276}, + { "300x300", "w360h504-div2", 1920, 2176}, + { "300x600", "w360h504-div2", 1920, 4352}, + { "300x300", "w432h432", 1836, 1920}, + { "300x600", "w432h432", 3672, 1920}, + { "300x300", "w432h576", 1920, 2436}, + { "300x600", "w432h576", 1920, 4872}, + { "300x300", "w432h576-div4", 1920, 2436}, + { "300x600", "w432h576-div4", 1920, 4872}, + { "300x300", "w432h576-div2", 1920, 2498}, + { "300x600", "w432h576-div2", 1920, 4996}, + { "300x300", "w432h576-w432h432_w432h144", 1920, 2436}, + { "300x600", "w432h576-w432h432_w432h144", 1920, 4872}, + { "300x300", "w432h648", 1920, 2740}, + { "300x600", "w432h648", 1920, 5480}, +}; + +LIST(dyesub_printsize_list_t, dnpds40_printsize_list, dyesub_printsize_t, dnpds40_printsize); + +static const overcoat_t dnpds40_overcoat[] = +{ + {"Glossy", N_("Glossy"), {3, "000"}}, + {"Matte", N_("Matte"), {3, "001"}}, +}; + +LIST(overcoat_list_t, dnpds40_overcoat_list, overcoat_t, dnpds40_overcoat); + +static const stp_parameter_t ds40_parameters[] = +{ + { + "NoCutWaste", N_("No Cut-Paper Waste"), "Color=No,Category=Advanced Printer Setup", + N_("No Cut-Paper Waste"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, +}; + +#define ds40_parameter_count (sizeof(ds40_parameters) / sizeof(const stp_parameter_t)) + +static int +ds40_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "NoCutWaste") == 0) + { + description->is_active = 1; + description->deflt.boolean = 0; + } + else + { + return 0; + } + + return 1; +} + +static int ds40_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + int nocutwaste = stp_get_boolean_parameter(v, "NoCutWaste"); + + if (pd) { + pd->privdata.dnp.nocutwaste = nocutwaste; + } + + return 1; +} + +static void dnp_printer_start_common(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Configure Lamination */ + stp_zprintf(v, "\033PCNTRL OVERCOAT 0000000800000"); + stp_zfwrite((pd->overcoat->seq).data, 1, + (pd->overcoat->seq).bytes, v); /* Lamination mode */ + + /* Set quantity.. Backend overrides as needed. */ + stp_zprintf(v, "\033PCNTRL QTY 00000008%07d\r", pd->copies); +} + +static void dnpds40_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* Set cutter option to "normal" */ + if (!strcmp(pd->pagesize, "w432h576-w432h432_w432h144")) { + stp_zprintf(v, "\033PCNTRL FULL_CUTTER_SET 00000016"); + stp_zprintf(v, "060020000000000\r"); + } else if (!strcmp(pd->pagesize, "w288h432-div2") || + !strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000120"); + } else if (pd->privdata.dnp.nocutwaste) { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000001"); + } else { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000000"); + } + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008000000"); + + if (!strcmp(pd->pagesize, "B7")) { + stp_zprintf(v, "01"); + } else if (!strcmp(pd->pagesize, "w288h432")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w360h504")) { + stp_zprintf(v, "03"); + } else if (!strcmp(pd->pagesize, "w360h504-div2")) { + stp_zprintf(v, "22"); + } else if (!strcmp(pd->pagesize, "w432h432")) { + stp_zprintf(v, "27"); + } else if (!strcmp(pd->pagesize, "w432h576")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h576-w432h432_w432h144")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h648")) { + stp_zprintf(v, "05"); + } else if (!strcmp(pd->pagesize, "w432h576-div2")) { + stp_zprintf(v, "12"); + } else if (!strcmp(pd->pagesize, "w288h432-div2")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "04"); + } else { + stp_zprintf(v, "00"); /* should be impossible. */ + } +} + +static void dnpds40_printer_end(stp_vars_t *v) +{ + stp_zprintf(v, "\033PCNTRL START"); dyesub_nputc(v, ' ', 19); +} + +static void dnpds40_plane_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + char p = (pd->plane == 3 ? 'Y' : + (pd->plane == 2 ? 'M' : + 'C' )); + + long PadSize = 10; + long FSize = (pd->w_size*pd->h_size) + 1024 + 54 + PadSize; + + /* Printer command plus length of data to follow */ + stp_zprintf(v, "\033PIMAGE %cPLANE %08ld", p, FSize); + + /* Each plane is essentially a tweaked BMP file */ + + /* BMP header */ + stp_zprintf(v, "BM"); + stp_put32_le(FSize, v); + dyesub_nputc(v, '\0', 4); + stp_put32_le(1088, v); /* Offset to pixel data: 1024 + (14+40-10) + 10 */ + + /* DIB header */ + stp_put32_le(40, v); /* DIB header size */ + stp_put32_le(pd->w_size, v); + stp_put32_le(pd->h_size, v); + stp_put16_le(1, v); /* single channel */ + stp_put16_le(8, v); /* 8bpp */ + dyesub_nputc(v, '\0', 8); /* compression + image size are ignored */ + stp_put32_le(11808, v); /* horizontal pixels per meter, fixed at 300dpi */ + if (pd->h_dpi == 600) + stp_put32_le(23615, v); /* vertical pixels per meter @ 600dpi */ + else if (pd->h_dpi == 334) + stp_put32_le(13146, v); /* vertical pixels per meter @ 334dpi */ + else + stp_put32_le(11808, v); /* vertical pixels per meter @ 300dpi */ + stp_put32_le(256, v); /* entries in color table */ + stp_put32_le(0, v); /* no important colors */ + dyesub_nputc(v, '\0', 1024); /* RGB Array, unused by printer */ + dyesub_nputc(v, '\0', PadSize); /* Pading to align plane data */ +} + +/* Dai Nippon Printing DS80 */ + +/* Imaging area is wider than print size, we always must supply the + printer with the full imaging width. */ +static const dyesub_pagesize_t dnpds80_page[] = +{ + DEFINE_PAPER( "w288h576", "8x4", PT1(1236,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h576", "8x5", PT1(1536,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "8x6", PT1(1836,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576", "8x8", PT1(2436,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576-div2", "8x4*2", PT1(2502,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h648-w576h360_w576h288", "8x5+8x4", PT1(2560,300), PT1(2802,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10", "8x10", PT1(2560,300), PT1(3036,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-div2", "8x5*2", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-w576h432_w576h288", "8x6+8x4", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h792-w576h432_w576h360", "8x6+8x5", PT1(2560,300), PT1(3402,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h842", "8x11.7", PT1(2560,300), PT1(3544,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864", "8x12", PT1(2560,300), PT1(3636,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div2", "8x6*2", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-w576h576_w576h288", "8x8+8x4", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div3", "8x4*3", PT1(2560,300), PT1(3768,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dnpds80_page_list, dyesub_pagesize_t, dnpds80_page); + +static const dyesub_printsize_t dnpds80_printsize[] = +{ + { "300x300", "w288h576", 1236, 2560}, + { "300x600", "w288h576", 2472, 2560}, + { "300x300", "w360h576", 1536, 2560}, + { "300x600", "w360h576", 3072, 2560}, + { "300x300", "w432h576", 1836, 2560}, + { "300x600", "w432h576", 3672, 2560}, + { "300x300", "w576h576", 2436, 2560}, + { "300x600", "w576h576", 4872, 2560}, + { "300x300", "w576h576-div2", 2502, 2560}, + { "300x600", "w576h576-div2", 5004, 2560}, + { "300x300", "w576h648-w576h360_w576h288", 2560, 2802}, + { "300x600", "w576h648-w576h360_w576h288", 2560, 5604}, + { "300x300", "c8x10", 2560, 3036}, + { "300x600", "c8x10", 2560, 6072}, + { "300x300", "c8x10-div2", 2560, 3102}, + { "300x600", "c8x10-div2", 2560, 6204}, + { "300x300", "c8x10-w576h432_w576h288", 2560, 3102}, + { "300x600", "c8x10-w576h432_w576h288", 2560, 6204}, + { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, + { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w576h842", 2560, 7088}, + { "300x300", "w576h864", 2560, 3636}, + { "300x600", "w576h864", 2560, 7272}, + { "300x300", "w576h864-div2", 2560, 3702}, + { "300x600", "w576h864-div2", 2560, 7404}, + { "300x300", "w576h864-w576h576_w576h288", 2560, 3702}, + { "300x600", "w576h864-w576h576_w576h288", 2560, 7404}, + { "300x300", "w576h864-div3", 2560, 3768}, + { "300x600", "w576h864-div3", 2560, 7536}, +}; + +LIST(dyesub_printsize_list_t, dnpds80_printsize_list, dyesub_printsize_t, dnpds80_printsize); + +static int dnpds80_parse_parameters(stp_vars_t *v) +{ + const char *pagesize = stp_get_string_parameter(v, "PageSize"); + dyesub_privdata_t *pd = get_privdata(v); + int multicut = 0; + int nocutwaste = stp_get_boolean_parameter(v, "NoCutWaste"); + + if (!strcmp(pagesize, "c8x10")) { + multicut = 6; + } else if (!strcmp(pagesize, "w576h864")) { + multicut = 7; + } else if (!strcmp(pagesize, "w288h576")) { + multicut = 8; + } else if (!strcmp(pagesize, "w360h576")) { + multicut = 9; + } else if (!strcmp(pagesize, "w432h576")) { + multicut = 10; + } else if (!strcmp(pagesize, "w576h576")) { + multicut = 11; + } else if (!strcmp(pagesize, "w576h576-div2")) { + multicut = 13; + } else if (!strcmp(pagesize, "c8x10-div2")) { + multicut = 14; + } else if (!strcmp(pagesize, "w576h864-div2")) { + multicut = 15; + } else if (!strcmp(pagesize, "w576h648-w576h360_w576h288")) { + multicut = 16; + } else if (!strcmp(pagesize, "c8x10-w576h432_w576h288")) { + multicut = 17; + } else if (!strcmp(pagesize, "w576h792-w576h432_w576h360")) { + multicut = 18; + } else if (!strcmp(pagesize, "w576h864-w576h576_w576h288")) { + multicut = 19; + } else if (!strcmp(pagesize, "w576h864-div3")) { + multicut = 20; + } else if (!strcmp(pagesize, "w576h842")) { + multicut = 21; + } else { + stp_eprintf(v, _("Illegal print size selected for roll media!\n")); + return 0; + } + + /* No need to set global params if there's no privdata yet */ + if (pd) { + pd->privdata.dnp.multicut = multicut; + pd->privdata.dnp.nocutwaste = nocutwaste; + } + + return 1; +} + +static void dnpds80_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* Set cutter option to "normal" */ + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + if (pd->privdata.dnp.nocutwaste) + stp_zprintf(v, "00000001"); + else + stp_zprintf(v, "00000000"); + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008%08d", pd->privdata.dnp.multicut); +} + +/* Dai Nippon Printing DS80DX */ +static const dyesub_media_t dnpds80dx_medias[] = +{ + {"Roll", N_("Roll"), {0, ""}}, + {"Sheet", N_("Sheet"), {0, ""}}, +}; + +LIST(dyesub_media_list_t, dnpds80dx_media_list, dyesub_media_t, dnpds80dx_medias); + +static int dnpds80dx_parse_parameters(stp_vars_t *v) +{ + const char *pagesize; + const dyesub_media_t* media = NULL; + const char* duplex_mode; + dyesub_privdata_t *pd = get_privdata(v); + int multicut = 0; + int nocutwaste; + + pagesize = stp_get_string_parameter(v, "PageSize"); + duplex_mode = stp_get_string_parameter(v, "Duplex"); + media = dyesub_get_mediatype(v); + nocutwaste = stp_get_boolean_parameter(v, "NoCutWaste"); + + if (!strcmp(media->name, "Roll")) { + if (strcmp(duplex_mode, "None") && strcmp(duplex_mode, "Standard")) { + stp_eprintf(v, _("Duplex not supported on roll media, switching to sheet media!\n")); + stp_set_string_parameter(v, "MediaType", "Sheet"); + } else { + /* If we're not using duplex and roll media, this is + effectively a DS80 (non-DX) */ + return dnpds80_parse_parameters(v); + } + } + + if (!strcmp(pagesize, "c8x10")) { + multicut = 6; + } else if (!strcmp(pagesize, "w576h864")) { + multicut = 7; + } else if (!strcmp(pagesize, "w288h576")) { + multicut = 8; + } else if (!strcmp(pagesize, "w360h576")) { + multicut = 9; + } else if (!strcmp(pagesize, "w432h576")) { + multicut = 10; + } else if (!strcmp(pagesize, "w576h576")) { + multicut = 11; + } else if (!strcmp(pagesize, "w576h774-w576h756")) { + multicut = 25; + } else if (!strcmp(pagesize, "w576h774")) { + multicut = 26; + } else if (!strcmp(pagesize, "w576h576-div2")) { + multicut = 13; + } else if (!strcmp(pagesize, "c8x10-div2")) { + multicut = 14; + } else if (!strcmp(pagesize, "w576h864-div2")) { + multicut = 15; + } else if (!strcmp(pagesize, "w576h864-div3sheet")) { + multicut = 28; + } else { + stp_eprintf(v, _("Illegal print size selected for sheet media!\n")); + return 0; + } + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + /* Add correct offset to multicut mode based on duplex state */ + if (!strcmp(duplex_mode, "None") || !strcmp(duplex_mode, "Standard")) + multicut += 100; /* Simplex */ + else if (pd->page_number & 1) + multicut += 300; /* Duplex, back */ + else + multicut += 200; /* Duplex, front */ + + pd->privdata.dnp.multicut = multicut; + pd->privdata.dnp.nocutwaste = nocutwaste; + + return 1; +} + +/* This is the same as the DS80, except with 10.5" and 10.75" sizes + only meant for sheet media. Duplex is *only* supported on sheet media. + + Also, 8x4*3 differs depending on if you're using sheet or roll media, + hence the almost-duplicated definition. + +*/ + +static const dyesub_pagesize_t dnpds80dx_page[] = +{ + DEFINE_PAPER( "w288h576", "8x4", PT1(1236,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h576", "8x5", PT1(1536,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "8x6", PT1(1836,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576", "8x8", PT1(2436,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576-div2", "8x4*2", PT1(2502,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h648-w576h360_w576h288", "8x5+8x4", PT1(2560,300), PT1(2802,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10", "8x10", PT1(2560,300), PT1(3036,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-div2", "8x5*2", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-w576h432_w576h288", "8x6+8x4", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h774-w576h756", "8x10.5", PT1(2560,300), PT1(3186,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h774", "8x10.75", PT1(2560,300), PT1(3186,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h792-w576h432_w576h360", "8x6+8x5", PT1(2560,300), PT1(3402,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h842", "8x11.7", PT1(2560,300), PT1(3544,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864", "8x12", PT1(2560,300), PT1(3636,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div2", "8x6*2", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-w576h576_w576h288", "8x8+8x4", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div3", "8x4*3", PT1(2560,300), PT1(3768,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div3sheet", "8x4*3 SHEET", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dnpds80dx_page_list, dyesub_pagesize_t, dnpds80dx_page); + +static const dyesub_printsize_t dnpds80dx_printsize[] = +{ + { "300x300", "w288h576", 1236, 2560}, + { "300x600", "w288h576", 2472, 2560}, + { "300x300", "w360h576", 1536, 2560}, + { "300x600", "w360h576", 3072, 2560}, + { "300x300", "w432h576", 1836, 2560}, + { "300x600", "w432h576", 3672, 2560}, + { "300x300", "w576h576", 2436, 2560}, + { "300x600", "w576h576", 4872, 2560}, + { "300x300", "w576h576-div2", 2502, 2560}, + { "300x600", "w576h576-div2", 5004, 2560}, + { "300x300", "w576h648-w576h360_w576h288", 2560, 2802}, + { "300x600", "w576h648-w576h360_w576h288", 2560, 5604}, + { "300x300", "c8x10", 2560, 3036}, + { "300x600", "c8x10", 2560, 6072}, + { "300x300", "c8x10-div2", 2560, 3102}, + { "300x600", "c8x10-div2", 2560, 6204}, + { "300x300", "c8x10-w576h432_w576h288", 2560, 3102}, + { "300x600", "c8x10-w576h432_w576h288", 2560, 6204}, + { "300x300", "w576h774", 2560, 3186}, + { "300x600", "w576h774", 2560, 6372}, + { "300x300", "w576h774-w576h756", 2560, 3186}, + { "300x600", "w576h774-w576h756", 2560, 6372}, + { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, + { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w567h842", 2560, 7088}, + { "300x300", "w576h864", 2560, 3636}, + { "300x600", "w576h864", 2560, 7272}, + { "300x300", "w576h864-div2", 2560, 3702}, + { "300x600", "w576h864-div2", 2560, 7404}, + { "300x300", "w576h864-w576h576_w576h288", 2560, 3702}, + { "300x600", "w576h864-w576h576_w576h288", 2560, 7404}, + { "300x300", "w576h864-div3", 2560, 3768}, + { "300x600", "w576h864-div3", 2560, 7536}, + { "300x300", "w576h864-div3sheet", 2560, 3702}, + { "300x600", "w576h864-div3sheet", 2560, 7404}, +}; + +LIST(dyesub_printsize_list_t, dnpds80dx_printsize_list, dyesub_printsize_t, dnpds80dx_printsize); + +/* Dai Nippon Printing DS-RX1 */ +/* Imaging area is wider than print size, we always must supply the + printer with the full imaging width. */ +static const dyesub_pagesize_t dnpsrx1_page[] = +{ + DEFINE_PAPER( "B7", "3.5x5", PT1(1088,300), PT1(1920,300), 0, 0, PT(186,300), PT(186,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432", "4x6", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h360","5x5", PT1(1540,300), PT1(1920,300), 0, 0, PT(186,300), PT(186,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h504", "5x7", PT1(1920,300), PT1(2138,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w360h504-div2", "3.5x5*2", PT1(1920,300), PT1(2176,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h432", "6x6", PT1(1836,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "6x8", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div4", "2x6*4", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1920,300), PT1(2498,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + +}; + +LIST(dyesub_pagesize_list_t, dnpsrx1_page_list, dyesub_pagesize_t, dnpsrx1_page); + +static const dyesub_printsize_t dnpsrx1_printsize[] = +{ + { "300x300", "B7", 1088, 1920}, + { "300x600", "B7", 2176, 1920}, + { "300x300", "w288h432", 1240, 1920}, + { "300x600", "w288h432", 2480, 1920}, + { "300x300", "w288h432-div2", 1240, 1920}, + { "300x600", "w288h432-div2", 2480, 1920}, + { "300x300", "w360h360", 1540, 1920}, + { "300x600", "w360h360", 3080, 1920}, + { "300x300", "w360h504", 1920, 2138}, + { "300x600", "w360h504", 1920, 4276}, + { "300x300", "w360h504-div2", 1920, 2176}, + { "300x600", "w360h504-div2", 1920, 4352}, + { "300x300", "w432h432", 1836, 1920}, + { "300x600", "w432h432", 3672, 1920}, + { "300x300", "w432h576", 1920, 2436}, + { "300x600", "w432h576", 1920, 4872}, + { "300x300", "w432h576-div4", 1920, 2436}, + { "300x600", "w432h576-div4", 1920, 4872}, + { "300x300", "w432h576-div2", 1920, 2498}, + { "300x600", "w432h576-div2", 1920, 4996}, +}; + +LIST(dyesub_printsize_list_t, dnpsrx1_printsize_list, dyesub_printsize_t, dnpsrx1_printsize); + +static void dnpdsrx1_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* Set cutter option to "normal" */ + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + if (!strcmp(pd->pagesize, "w288h432-div2")) { + stp_zprintf(v, "00000120"); + } else if (!strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "00000120"); + } else if (pd->privdata.dnp.nocutwaste) { + stp_zprintf(v, "00000001"); + } else { + stp_zprintf(v, "00000000"); + } + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008000000"); + + if (!strcmp(pd->pagesize, "B7")) { + stp_zprintf(v, "01"); + } else if (!strcmp(pd->pagesize, "w288h432")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w360h360")) { + stp_zprintf(v, "29"); + } else if (!strcmp(pd->pagesize, "w360h504")) { + stp_zprintf(v, "03"); + } else if (!strcmp(pd->pagesize, "w360h504-div2")) { + stp_zprintf(v, "22"); + } else if (!strcmp(pd->pagesize, "w432h432")) { + stp_zprintf(v, "27"); + } else if (!strcmp(pd->pagesize, "w432h576")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h576-div2")) { + stp_zprintf(v, "12"); + } else if (!strcmp(pd->pagesize, "w288h432-div2")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "04"); + } else { + stp_zprintf(v, "00"); + } +} + +/* Dai Nippon Printing DS620 */ +static const overcoat_t dnpds620_overcoat[] = +{ + {"Glossy", N_("Glossy"), {3, "000"}}, + {"Matte", N_("Matte"), {3, "001"}}, + {"MatteFine", N_("Matte Fine"), {3, "021"}}, + {"MatteLuster", N_("Matte Luster"), {3, "022"}}, +}; + +LIST(overcoat_list_t, dnpds620_overcoat_list, overcoat_t, dnpds620_overcoat); + +/* Imaging area is wider than print size, we always must supply the + printer with the full imaging width. */ +static const dyesub_pagesize_t dnpds620_page[] = +{ + DEFINE_PAPER( "B7", "3.5x5", PT1(1088,300), PT1(1920,300), 0, 0, PT(186,300), PT(186,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432", "4x6", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432-div2", "2x6*2", PT1(1240,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w324h432", "4.5x6", PT1(1386,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h360", "5x5", PT1(1540,300), PT1(1920,300), 0, 0, PT(186,300), PT(186,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h504", "5x7", PT1(1920,300), PT1(2138,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w360h504-div2", "3.5x5*2", PT1(1920,300), PT1(2176,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w360h504-w360h360_w360h144", "5x5+2x5", PT1(1920,300), PT1(2138,300), PT(186,300), PT(186,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h432", "6x6", PT1(1836,300), PT1(1920,300), 0, 0, PT(38,300), PT(38,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "6x8", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-w432h432_w432h144", "6x6+2x6", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div4", "2x6*4", PT1(1920,300), PT1(2436,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576-div2", "4x6*2", PT1(1920,300), PT1(2498,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h648", "6x9", PT1(1920,300), PT1(2740,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h648-div2", "4.5x6*2", PT1(1920,300), PT1(2802,300), PT(38,300), PT(38,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dnpds620_page_list, dyesub_pagesize_t, dnpds620_page); + +static const dyesub_printsize_t dnpds620_printsize[] = +{ + { "300x300", "B7", 1088, 1920}, + { "300x600", "B7", 2176, 1920}, + { "300x300", "w288h432", 1240, 1920}, + { "300x600", "w288h432", 2480, 1920}, + { "300x300", "w288h432-div2", 1240, 1920}, + { "300x600", "w288h432-div2", 2480, 1920}, + { "300x300", "w324h432", 1386, 1920}, + { "300x600", "w324h432", 2772, 1920}, + { "300x300", "w360h360", 1540, 1920}, + { "300x600", "w360h360", 3080, 1920}, + { "300x300", "w360h504", 1920, 2138}, + { "300x600", "w360h504", 1920, 4276}, + { "300x300", "w360h504-w360h360_w360h144", 1920, 2138}, + { "300x600", "w360h504-w360h360_w360h144", 1920, 4276}, + { "300x300", "w360h504-div2", 1920, 2176}, + { "300x600", "w360h504-div2", 1920, 4352}, + { "300x300", "w432h432", 1836, 1920}, + { "300x600", "w432h432", 3672, 1920}, + { "300x300", "w432h576", 1920, 2436}, + { "300x600", "w432h576", 1920, 4872}, + { "300x300", "w432h576-div4", 1920, 2436}, + { "300x600", "w432h576-div4", 1920, 4872}, + { "300x300", "w432h576-w432h432_w432h144", 1920, 2436}, + { "300x600", "w432h576-w432h432_w432h144", 1920, 4872}, + { "300x300", "w432h576-div2", 1920, 2498}, + { "300x600", "w432h576-div2", 1920, 4996}, + { "300x300", "w432h648", 1920, 2740}, + { "300x600", "w432h648", 1920, 5480}, + { "300x300", "w432h648-div2", 1920, 2802}, + { "300x600", "w432h648-div2", 1920, 5604}, +}; + +LIST(dyesub_printsize_list_t, dnpds620_printsize_list, dyesub_printsize_t, dnpds620_printsize); + +static void dnpds620_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* Multicut when 8x6 media is in use */ + if (!strcmp(pd->pagesize, "w432h576") || + !strcmp(pd->pagesize, "w432h648")) { + stp_zprintf(v, "\033PCNTRL FULL_CUTTER_SET 00000016"); + stp_zprintf(v, "0000000000000000"); + } else if (!strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "\033PCNTRL FULL_CUTTER_SET 00000016"); + stp_zprintf(v, "0200200200200000"); + } else if (!strcmp(pd->pagesize, "w432h576-w432h432_w432h144")) { + stp_zprintf(v, "\033PCNTRL FULL_CUTTER_SET 00000016"); + stp_zprintf(v, "0600200000000000"); + } else if (!strcmp(pd->pagesize, "w360h504-w360h360_w360h144")) { + stp_zprintf(v, "\033PCNTRL FULL_CUTTER_SET 00000016"); + stp_zprintf(v, "050020000000000\r"); + } else if (!strcmp(pd->pagesize, "w288h432-div2")) { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000120"); + } else if (pd->privdata.dnp.nocutwaste) { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000001"); + } else { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000000"); + } + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008000000"); + if (!strcmp(pd->pagesize, "B7")) { + stp_zprintf(v, "01"); + } else if (!strcmp(pd->pagesize, "w288h432")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w288h432-div2")) { + stp_zprintf(v, "02"); + } else if (!strcmp(pd->pagesize, "w324h432")) { + stp_zprintf(v, "30"); + } else if (!strcmp(pd->pagesize, "w360h360")) { + stp_zprintf(v, "29"); + } else if (!strcmp(pd->pagesize, "w360h504")) { + stp_zprintf(v, "03"); + } else if (!strcmp(pd->pagesize, "w360h504-w360h360_w360h144")) { + stp_zprintf(v, "03"); + } else if (!strcmp(pd->pagesize, "w360h504-div2")) { + stp_zprintf(v, "22"); + } else if (!strcmp(pd->pagesize, "w432h432")) { + stp_zprintf(v, "27"); + } else if (!strcmp(pd->pagesize, "w432h576")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h576-w432h432_w432h144")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h576-div4")) { + stp_zprintf(v, "04"); + } else if (!strcmp(pd->pagesize, "w432h576-div2")) { + stp_zprintf(v, "12"); + } else if (!strcmp(pd->pagesize, "w432h648")) { + stp_zprintf(v, "05"); + } else if (!strcmp(pd->pagesize, "w432h648-div2")) { + stp_zprintf(v, "31"); + } else { + stp_zprintf(v, "00"); /* Should be impossible */ + } +} + +/* Dai Nippon Printing DS820 */ + +/* Imaging area is wider than print size, we always must supply the + printer with the full imaging width. */ +static const dyesub_pagesize_t dnpds820_page[] = +{ + DEFINE_PAPER( "w288h576", "8x4", PT1(1236,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w360h576", "8x5", PT1(1536,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w432h576", "8x6", PT1(1836,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w504h576", "8x7", PT1(2136,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576", "8x8", PT1(2436,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h576-div2", "8x4*2", PT1(2502,300), PT1(2560,300), 0, 0, PT(56,300), PT(56,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w576h648", "8x9", PT1(2560,300), PT1(2736,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h648-w576h360_w576h288", "8x5+8x4", PT1(2560,300), PT1(2802,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10", "8x10", PT1(2560,300), PT1(3036,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-div2", "8x5*2", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "c8x10-w576h432_w576h288", "8x6+8x4", PT1(2560,300), PT1(3102,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h792-w576h432_w576h360", "8x6+8x5", PT1(2560,300), PT1(3402,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h842", "8x11.7", PT1(2560,300), PT1(3544,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864", "8x12", PT1(2560,300), PT1(3636,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div2", "8x6*2", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-w576h576_w576h288", "8x8+8x4", PT1(2560,300), PT1(3702,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w576h864-div3", "8x4*3", PT1(2560,300), PT1(3768,300), PT(56,300), PT(56,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "A4x4inch", "A4x4inch", PT1(1236,300), PT1(2560,300), 0, 0, PT(16,300), PT(16,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "A4x5inch", "A4x5inch", PT1(1536,300), PT1(2560,300), 0, 0, PT(16,300), PT(16,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "A5", "A5", PT1(1784,300), PT1(2560,300), 0, 0, PT(16,300), PT(16,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "A4x6inch", "A4x6inch", PT1(1836,300), PT1(2560,300), 0, 0, PT(16,300), PT(16,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "A4x8inch", "A4x8inch", PT1(2436,300), PT1(2560,300), 0, 0, PT(16,300), PT(16,300), DYESUB_LANDSCAPE), + DEFINE_PAPER( "A4x10inch", "A4x10inch", PT1(2560,300), PT1(3036,300), PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "A4x10inch-div2", "A4x5inch*2", PT1(2560,300), PT1(3102,300), PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "A4", "A4", PT1(2560,300), PT1(3544,300), PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "A4-div2", "A5*2", PT1(2560,300), PT1(3598,300), PT(16,300), PT(16,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, dnpds820_page_list, dyesub_pagesize_t, dnpds820_page); + +static const dyesub_printsize_t dnpds820_printsize[] = +{ + { "300x300", "w288h576", 1236, 2560}, + { "300x600", "w288h576", 2472, 2560}, + { "300x300", "w360h576", 1536, 2560}, + { "300x600", "w360h576", 3072, 2560}, + { "300x300", "w432h576", 1836, 2560}, + { "300x600", "w432h576", 3672, 2560}, + { "300x300", "w504h576", 2136, 2560}, + { "300x600", "w504h576", 4272, 2560}, + { "300x300", "w576h576", 2436, 2560}, + { "300x600", "w576h576", 4872, 2560}, + { "300x300", "w576h576-div2", 2502, 2560}, + { "300x600", "w576h576-div2", 5004, 2560}, + { "300x300", "w576h648", 2560, 2736}, + { "300x600", "w576h648", 2560, 5472}, + { "300x300", "w576h648-w576h360_w576h288", 2560, 2802}, + { "300x600", "w576h648-w576h360_w576h288", 2560, 5604}, + { "300x300", "c8x10", 2560, 3036}, + { "300x600", "c8x10", 2560, 6072}, + { "300x300", "c8x10-div2", 2560, 3102}, + { "300x600", "c8x10-div2", 2560, 6204}, + { "300x300", "c8x10-w576h432_w576h288", 2560, 3102}, + { "300x600", "c8x10-w576h432_w576h288", 2560, 6204}, + { "300x300", "w576h792-w576h432_w576h360", 2560, 3402}, + { "300x600", "w576h792-w576h432_w576h360", 2560, 6804}, + { "300x300", "w576h842", 2560, 3544}, + { "300x600", "w576h842", 2560, 7088}, + { "300x300", "w576h864", 2560, 3636}, + { "300x600", "w576h864", 2560, 7272}, + { "300x300", "w576h864-div2", 2560, 3702}, + { "300x600", "w576h864-div2", 2560, 7404}, + { "300x300", "w576h864-w576h576_w576h288", 2560, 3702}, + { "300x600", "w576h864-w576h576_w576h288", 2560, 7404}, + { "300x300", "w576h864-div3", 2560, 3768}, + { "300x600", "w576h864-div3", 2560, 7536}, + { "300x300", "A4x4inch", 1236, 2560}, + { "300x600", "A4x4inch", 2472, 2560}, + { "300x300", "A4x5inch", 1536, 2560}, + { "300x600", "A4x5inch", 3072, 2560}, + { "300x300", "A5", 1784, 2560}, + { "300x600", "A5", 3568, 2560}, + { "300x300", "A4x6inch", 1836, 2560}, + { "300x600", "A4x6inch", 3672, 2560}, + { "300x300", "A4x8inch", 2436, 2560}, + { "300x600", "A4x8inch", 4872, 2560}, + { "300x300", "A4x10inch", 2560, 3036}, + { "300x600", "A4x10inch", 2560, 6072}, + { "300x300", "A4x10inch-div2", 2560, 3102}, + { "300x600", "A4x10inch-div2", 2560, 6204}, + { "300x300", "A4", 2560, 3544}, + { "300x600", "A4", 2560, 7088}, + { "300x300", "A4-div2", 2560, 3598}, + { "300x600", "A4-div2", 2560, 7196}, +}; + +LIST(dyesub_printsize_list_t, dnpds820_printsize_list, dyesub_printsize_t, dnpds820_printsize); + +static void dnpds820_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + /* Common code */ + dnp_printer_start_common(v); + + /* No-cut waste */ + if (pd->privdata.dnp.nocutwaste) { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000001"); + } else { + stp_zprintf(v, "\033PCNTRL CUTTER 00000008"); + stp_zprintf(v, "00000000"); + } + + /* Configure multi-cut/page size */ + stp_zprintf(v, "\033PIMAGE MULTICUT 00000008000000"); + + if (!strcmp(pd->pagesize, "c8x10")) { + stp_zprintf(v, "06"); + } else if (!strcmp(pd->pagesize, "w576h864")) { + stp_zprintf(v, "07"); + } else if (!strcmp(pd->pagesize, "w288h576")) { + stp_zprintf(v, "08"); + } else if (!strcmp(pd->pagesize, "w360h576")) { + stp_zprintf(v, "09"); + } else if (!strcmp(pd->pagesize, "w432h576")) { + stp_zprintf(v, "10"); + } else if (!strcmp(pd->pagesize, "w576h576")) { + stp_zprintf(v, "11"); + } else if (!strcmp(pd->pagesize, "w576h576-div2")) { + stp_zprintf(v, "13"); + } else if (!strcmp(pd->pagesize, "c8x10-div2")) { + stp_zprintf(v, "14"); + } else if (!strcmp(pd->pagesize, "w576h864-div2")) { + stp_zprintf(v, "15"); + } else if (!strcmp(pd->pagesize, "w576h648-w576h360_w576h288")) { + stp_zprintf(v, "16"); + } else if (!strcmp(pd->pagesize, "c8x10-w576h432_w576h288")) { + stp_zprintf(v, "17"); + } else if (!strcmp(pd->pagesize, "w576h792-w576h432_w576h360")) { + stp_zprintf(v, "18"); + } else if (!strcmp(pd->pagesize, "w576h864-w576h576_w576h288")) { + stp_zprintf(v, "19"); + } else if (!strcmp(pd->pagesize, "w576h864-div3")) { + stp_zprintf(v, "20"); + } else if (!strcmp(pd->pagesize, "w576h842")) { + stp_zprintf(v, "21"); + } else if (!strcmp(pd->pagesize, "w504h576")) { + stp_zprintf(v, "32"); + } else if (!strcmp(pd->pagesize, "w576h648")) { + stp_zprintf(v, "33"); + } else if (!strcmp(pd->pagesize, "A5")) { + stp_zprintf(v, "34"); + } else if (!strcmp(pd->pagesize, "A4x4inch")) { + stp_zprintf(v, "36"); + } else if (!strcmp(pd->pagesize, "A4x5inch")) { + stp_zprintf(v, "37"); + } else if (!strcmp(pd->pagesize, "A4x6inch")) { + stp_zprintf(v, "38"); + } else if (!strcmp(pd->pagesize, "A4x8inch")) { + stp_zprintf(v, "39"); + } else if (!strcmp(pd->pagesize, "A4x10inch")) { + stp_zprintf(v, "40"); + } else if (!strcmp(pd->pagesize, "A4x10inch-div2")) { + stp_zprintf(v, "43"); + } else if (!strcmp(pd->pagesize, "A4")) { + stp_zprintf(v, "41"); + } else if (!strcmp(pd->pagesize, "A4-div2")) { + stp_zprintf(v, "35"); + } else { + stp_zprintf(v, "00"); /* should not be possible */ + } + + if (!strcmp(pd->privdata.dnp.print_speed, "LowSpeed")) { + stp_zprintf(v, "\033PCNTRL PRINTSPEED 0000000800000020"); + } else if (!strcmp(pd->privdata.dnp.print_speed, "HighDensity")) { + stp_zprintf(v, "\033PCNTRL PRINTSPEED 0000000800000030"); + } +} + +static const dyesub_stringitem_t dnpds820_print_speeds[] = +{ + { "Normal", N_ ("Normal") }, + { "LowSpeed", N_ ("Low Speed") }, + { "HighDensity", N_ ("High Density") } +}; +LIST(dyesub_stringlist_t, dnpds820_printspeeds_list, dyesub_stringitem_t, dnpds820_print_speeds); + +static const stp_parameter_t ds820_parameters[] = +{ + { + "PrintSpeed", N_("Print Speed"), "Color=No,Category=Advanced Printer Setup", + N_("Print Speed"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "NoCutWaste", N_("No Cut-Paper Waste"), "Color=No,Category=Advanced Printer Setup", + N_("No Cut-Paper Waste"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define ds820_parameter_count (sizeof(ds820_parameters) / sizeof(const stp_parameter_t)) + +static int +ds820_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "PrintSpeed") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &dnpds820_printspeeds_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "NoCutWaste") == 0) + { + description->is_active = 1; + description->deflt.boolean = 0; + } + else + { + return 0; + } + return 1; +} + +static int ds820_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + const char *print_speed = stp_get_string_parameter(v, "PrintSpeed"); + int nocutwaste = stp_get_boolean_parameter(v, "NoCutWaste"); + + if (pd) { + pd->privdata.dnp.print_speed = print_speed; + pd->privdata.dnp.nocutwaste = nocutwaste; + } + + return 1; +} + +/* Citizen CW-01 */ +static const dyesub_resolution_t res_citizen_cw01_dpi[] = +{ + { "334x334", 334, 334}, + { "334x600", 334, 600}, +}; + +LIST(dyesub_resolution_list_t, res_citizen_cw01_dpi_list, dyesub_resolution_t,res_citizen_cw01_dpi); + +static const dyesub_pagesize_t citizen_cw01_page[] = +{ + DEFINE_PAPER( "w252h338", "3.5x4.7", PT1(1210,334), PT1(2048,334), 0, 0, PT(225,334), PT(225,334), DYESUB_LANDSCAPE), + DEFINE_PAPER( "B7", "3.5x5", PT1(1210,334), PT1(2048,334), 0, 0, PT(169,334), PT(169,334), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w288h432", "4x6", PT1(1380,334), PT1(2048,334), 0, 0, PT(5,334), PT(5,334), DYESUB_LANDSCAPE), + DEFINE_PAPER( "w338h504", "4.7x7", PT1(2048,334), PT1(2380,334), PT(225,334), PT(225,334), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w360h504", "5x7", PT1(2048,334), PT1(2380,334), PT(169,334), PT(169,334), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h576", "6x8", PT1(2048,334), PT1(2710,300), PT(5,334), PT(5,334), 0, 0, DYESUB_PORTRAIT), + DEFINE_PAPER( "w432h648", "6x9", PT1(2048,334), PT1(3050,334), PT(5,334), PT(5,334), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, citizen_cw01_page_list, dyesub_pagesize_t, citizen_cw01_page); + +static const dyesub_printsize_t citizen_cw01_printsize[] = +{ + { "334x334", "w252h338", 1210, 2048}, + { "334x600", "w252h338", 2176, 2048}, + { "334x334", "B7", 1210, 2048}, + { "334x600", "B7", 2176, 2048}, + { "334x334", "w288h432", 1380, 2048}, + { "334x600", "w288h432", 2480, 2048}, + { "334x334", "w338h504", 2048, 2380}, + { "334x600", "w338h504", 2048, 4276}, + { "334x334", "w360h504", 2048, 2380}, + { "334x600", "w360h504", 2048, 4276}, + { "334x334", "w432h576", 2048, 2710}, + { "334x600", "w432h576", 2048, 4870}, + { "334x334", "w432h648", 2048, 3050}, + { "334x600", "w432h648", 2048, 5480}, +}; + +LIST(dyesub_printsize_list_t, citizen_cw01_printsize_list, dyesub_printsize_t, citizen_cw01_printsize); + +static void citizen_cw01_printer_start(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + /* Set quantity.. Backend overrides as needed. */ + stp_zprintf(v, "\033PCNTRL QTY 00000008%07d\r", pd->copies); + /* Set cutter, nothing fancy */ + stp_zprintf(v, "\033PCNTRL CUTTER 0000000800000000"); + + /* CW-01 has no other smarts. No multicut, no matte. */ +} + +/* Magicard Series */ +static const dyesub_pagesize_t magicard_page[] = +{ + DEFINE_PAPER( "w155h244", "ID-1/CR80", PT1(672,300), PT1(1016,300), PT1(15, 300), PT1(15,300), 0, 0, DYESUB_PORTRAIT), +}; + +LIST(dyesub_pagesize_list_t, magicard_page_list, dyesub_pagesize_t, magicard_page); + +static const dyesub_printsize_t magicard_printsize[] = +{ + { "300x300", "w155h244", 672, 1016}, +}; + +LIST(dyesub_printsize_list_t, magicard_printsize_list, dyesub_printsize_t, magicard_printsize); + +static const overcoat_t magicard_overcoat[] = +{ + {"Off", N_("Off"), {3, "OFF"}}, + {"On", N_("On"), {2, "ON"}}, +}; + +LIST(overcoat_list_t, magicard_overcoat_list, overcoat_t, magicard_overcoat); + +static void magicard_printer_init(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + dyesub_nputc(v, 0x05, 64); /* ATTN/Clear */ + stp_putc(0x01, v); /* Start command sequence */ + stp_zprintf(v, ",NOC1"); + stp_zprintf(v, ",VER%d.%d.%d", STP_MAJOR_VERSION, STP_MINOR_VERSION, STP_MICRO_VERSION); // XXX include "pre" or other tag. + stp_zprintf(v, ",LANENG"); // Dunno about other options. + stp_zprintf(v, ",TDT%08X", (unsigned int)stpi_time(NULL)); /* Some sort of timestamp. Unknown epoch. */ +// stp_zprintf(v, ",LC%d", 1); // Force media type. LC1/LC3/LC6/LC8 for YMCKO/MONO/KO/YMCKOK + stp_zprintf(v, ",REJ%s", pd->privdata.magicard.reject ? "ON" : "OFF"); /* Faulty card rejection. */ + stp_zprintf(v, ",ESS%d", pd->copies); /* Number of copies */ + stp_zprintf(v, ",KEE,RT2"); + if (pd->duplex_mode && + strcmp(pd->duplex_mode, "None") && + strcmp(pd->duplex_mode, "Standard")) /* Duplex enabled? */ + { + stp_zprintf(v, ",DPXON,PAG%d", 1 + (pd->page_number & 1)); + if (!(pd->page_number & 1)) + { + /* Color format of BACk side -- eg CKO or KO or C or CO or K. We don't support K/KO-only! */ + stp_zprintf(v, ",BAC%s%s", + pd->privdata.magicard.resin_k ? "CK" : "C", + pd->privdata.magicard.overcoat ? "O" : ""); + } + } + else + { + stp_zprintf(v, ",DPXOFF,PAG1"); + } + stp_zprintf(v, ",SLW%s", pd->privdata.magicard.colorsure ? "ON" : "OFF"); /* "Colorsure printing" */ + stp_zprintf(v, ",IMF%s", "BGR"); /* Image format -- as opposed to K, BGRK and others. */ + stp_zprintf(v, ",XCO0,YCO0"); // ?? + stp_zprintf(v, ",WID%u,HGT%u", (unsigned int)pd->h_size, (unsigned int)pd->w_size - 30); /* Width & Height */ + + /* Overcoat options are unique per-side */ + if (!(pd->page_number & 1)) + { + stp_zprintf(v, ",OVR%s", pd->privdata.magicard.overcoat ? "ON" : "OFF" ); + if (pd->privdata.magicard.overcoat && pd->privdata.magicard.overcoat_hole) + { + if (!strcmp("SmartCard", pd->privdata.magicard.overcoat_hole)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 90, 295, 260, 450); + else if (!strcmp("SmartCardLarge", pd->privdata.magicard.overcoat_hole)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 75, 275, 280, 470); + else if (!strcmp("MagStripe", pd->privdata.magicard.overcoat_hole)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 0, 420, 1025, 590); + else if (!strcmp("MagStripeLarge", pd->privdata.magicard.overcoat_hole)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 0, 400, 1025, 610); + /* XXX TODO: Add ability to specify custom hole sizes */ + } + } else { + stp_zprintf(v, ",OVR%s", pd->privdata.magicard.overcoat_dpx ? "ON" : "OFF" ); + if (pd->privdata.magicard.overcoat_dpx && pd->privdata.magicard.overcoat_hole_dpx) + { + if (!strcmp("SmartCard", pd->privdata.magicard.overcoat_hole_dpx)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 90, 295, 260, 450); + else if (!strcmp("SmartCardLarge", pd->privdata.magicard.overcoat_hole_dpx)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 75, 275, 280, 470); + else if (!strcmp("MagStripe", pd->privdata.magicard.overcoat_hole_dpx)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 0, 420, 1025, 590); + else if (!strcmp("MagStripeLarge", pd->privdata.magicard.overcoat_hole_dpx)) + stp_zprintf(v, ",NCT%d,%d,%d,%d", 0, 400, 1025, 610); + /* XXX TODO: Add ability to specify custom hole sizes */ + } + } + stp_zprintf(v, ",NNNOFF"); // ?? + if (!(pd->page_number & 1)) + { + stp_zprintf(v, ",USF%s", pd->privdata.magicard.holokote ? "ON" : "OFF"); /* Disable Holokote. */ + if (pd->privdata.magicard.holokote) + { + stp_zprintf(v, ",HKT%d", pd->privdata.magicard.holokote); + stp_zprintf(v, ",CKI%s", pd->privdata.magicard.holokote_custom? "ON" : "OFF"); + stp_zprintf(v, ",HKMFFFFFF,TRO0"); // HKM == area. each bit is a separate area, 1-24. Not sure about TRO + } + + if (pd->privdata.magicard.holopatch) + { + stp_zprintf(v, ",HPHON,PAT%d", pd->privdata.magicard.holopatch); + } + } else { + stp_zprintf(v, ",USFOFF"); /* Disable Holokote on duplex side. */ + } + + /* Magnetic stripe. Only program on the FRONT side. */ + if (!(pd->page_number & 1)) + { + if (pd->privdata.magicard.mag1[0]) { + stp_zprintf(v, ",MAG1,BPI210,MPC7,COE%c,%s", + pd->privdata.magicard.mag_coer ? 'H': 'L', + pd->privdata.magicard.mag1); + } + if (pd->privdata.magicard.mag2[0]) { + stp_zprintf(v, ",MAG2,BPI75,MPC5,COE%c,%s", + pd->privdata.magicard.mag_coer ? 'H': 'L', + pd->privdata.magicard.mag2); + } + if (pd->privdata.magicard.mag3[0]) { + stp_zprintf(v, ",MAG3,BPI210,MPC7,COE%c,%s", + pd->privdata.magicard.mag_coer ? 'H': 'L', + pd->privdata.magicard.mag3); + } + } + + stp_zprintf(v, ",PCT%d,%d,%d,%d", 0, 0, 1025, 641); // print area? (seen 1025/1015/999,641) + stp_zprintf(v, ",ICC%d", pd->privdata.magicard.gamma); /* Gamma curve. 0-2 */ + if (pd->privdata.magicard.power_color != 50) + stp_zprintf(v, ",CPW%d", pd->privdata.magicard.power_color); /* RGB/Color power. 0-100 */ + if (pd->privdata.magicard.power_overcoat != 50) + stp_zprintf(v, ",OPW%d", pd->privdata.magicard.power_overcoat); /* Overcoat power. 0-100 */ + if (pd->privdata.magicard.power_resin != 50) + stp_zprintf(v, ",KPW%d", pd->privdata.magicard.power_resin); /* Black/Resin power. 0-100 */ + if (pd->privdata.magicard.align_start != 50) + stp_zprintf(v, ",SOI%d", pd->privdata.magicard.align_start); /* Card Start alignment, 0-100 */ + if (pd->privdata.magicard.align_end != 50) + stp_zprintf(v, ",EOI%d", pd->privdata.magicard.align_end); /* Card End alignment, 0-100 */ + stp_zprintf(v, ",DDD50"); // ?? + stp_zprintf(v, ",X-GP-8"); /* GP extension, tells backend data is 8bpp */ + if (pd->privdata.magicard.resin_k) + stp_zprintf(v, ",X-GP-RK"); /* GP extension, tells backend to extract resin-K layer */ + stp_zprintf(v, ",SZB%d", (int)(pd->w_size * pd->h_size)); /* 8bpp, needs to be 6bpp */ + stp_zprintf(v, ",SZG%d", (int)(pd->w_size * pd->h_size)); + stp_zprintf(v, ",SZR%d", (int)(pd->w_size * pd->h_size)); +// stp_zprintf(v, ",SZK%d", (int)(pd->w_size * pd->h_size)); /* 8bpp, needs to be 1bpp */ + stp_putc(0x1c, v); /* Terminate command data */ +} + +static void magicard_printer_end(stp_vars_t *v) +{ + stp_putc(0x03, v); /* Terminate the command sequence */ +} + +static void magicard_plane_end(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + stp_putc(0x1c, v); /* Terminate the image data */ + switch (pd->plane) + { + case 3: + stp_putc(0x42, v); /* Blue */ + break; + case 2: + stp_putc(0x47, v); /* Green */ + break; + case 1: + stp_putc(0x52, v); /* Red */ + break; + default: +// stp_putc(0x4b, v); /* Black/Resin */ + break; + } + stp_putc(0x3a, v); +} + +static const dyesub_stringitem_t magicard_black_types[] = +{ + { "Composite", N_ ("Composite (CMY)") }, + { "Resin", N_ ("Resin Black") }, +}; +LIST(dyesub_stringlist_t, magicard_black_types_list, dyesub_stringitem_t, magicard_black_types); + +static const dyesub_stringitem_t magicard_mag_coer[] = +{ + { "Low", N_ ("Low") }, + { "High", N_ ("High") }, +}; +LIST(dyesub_stringlist_t, magicard_mag_coer_list, dyesub_stringitem_t, magicard_mag_coer); + +static const stp_parameter_t magicard_parameters[] = +{ + { + "BlackType", N_("Black Type"), "Color=No,Category=Advanced Printer Setup", + N_("Black Type"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "RejectBad", N_("Reject Bad Cards"), "Color=No,Category=Advanced Printer Setup", + N_("Reject Bad Cards"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "ColorSure", N_("Enable Colorsure"), "Color=No,Category=Advanced Printer Setup", + N_("Enable Colorsure"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "GammaCurve", N_("Printer Gamma Curve"), "Color=No,Category=Advanced Printer Setup", + N_("Internal Gamma Curve to apply (0 is none)"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "PowerColor", N_("Color Power Level"), "Color=No,Category=Advanced Printer Setup", + N_("Power level for color passes"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "PowerBlack", N_("Black Power Level"), "Color=No,Category=Advanced Printer Setup", + N_("Power level for black pass"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "PowerOC", N_("Overcoat Power Level"), "Color=No,Category=Advanced Printer Setup", + N_("Power level for overcoat pass"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "AlignStart", N_("Card Start Alignment"), "Color=No,Category=Advanced Printer Setup", + N_("Fine-tune card start position"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "AlignEnd", N_("Card End Alignment"), "Color=No,Category=Advanced Printer Setup", + N_("Fine-tune card end position"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "CardOffset", N_("Horizontal Card offset"), "Color=No,Category=Advanced Printer Setup", + N_("Fine-tune card horizontal centering"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Holokote", N_("Holokote"), "Color=No,Category=Advanced Printer Setup", + N_("Holokote option"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "HolokoteCustom", N_("Custom Holokote Key"), "Color=No,Category=Advanced Printer Setup", + N_("Use an optional custom Holokote key"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Holopatch", N_("HoloPatch"), "Color=No,Category=Advanced Printer Setup", + N_("Position of the HoloPatch"), + STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "OvercoatHole", N_("Overcoat Hole"), "Color=No,Category=Advanced Printer Setup", + N_("Area to not cover with an overcoat layer"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "OvercoatHoleDuplex", N_("Overcoat Hole Duplex"), "Color=No,Category=Advanced Printer Setup", + N_("Area to not cover with an overcoat layer"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { /* Note this is called "LaminateDuplex" rather than "OvercoatDuplex" + to align with the mis-named "Laminate" option. + */ + "LaminateDuplex", N_("Overcoat Pattern Duplex"), "Color=No,Category=Advanced Printer Setup", + N_("Overcoat Pattern Duplex"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "MagCoer", N_("Magnetic Stripe Coercivity"), "Color=No,Category=Advanced Printer Setup", + N_("Magnetic Stripe Coercivity Type"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MagStripe1", N_("Magnetic Stripe Row 1"), "Color=No,Category=Advanced Printer Setup", + N_("ISO 7811 alphanumeric data to be encoded in the first magnetic stripe row (0-79 characters)"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MagStripe2", N_("Magnetic Stripe Row 2"), "Color=No,Category=Advanced Printer Setup", + N_("ISO 7811 alphanumeric data to be encoded in the second magnetic stripe row (0-40 digits)"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "MagStripe3", N_("Magnetic Stripe Row 3"), "Color=No,Category=Advanced Printer Setup", + N_("ISO 7811 alphanumeric data to be encoded in the third magnetic stripe row (0-107 digits)"), + STP_PARAMETER_TYPE_RAW, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_ADVANCED, 0, 1, STP_CHANNEL_NONE, 1, 0 + }, +}; +#define magicard_parameter_count (sizeof(magicard_parameters) / sizeof(const stp_parameter_t)) + +static const dyesub_stringitem_t magicard_holokotes[] = +{ + { "Off", N_ ("Off") }, + { "UltraSecure", N_ ("Ultra Secure") }, + { "Rings", N_ ("Interlocking Rings") }, + { "Flex", N_ ("Flex") }, +}; +LIST(dyesub_stringlist_t, magicard_holokotes_list, dyesub_stringitem_t, magicard_holokotes); + +static const dyesub_stringitem_t magicard_overcoat_holes[] = +{ + { "None", N_ ("None") }, + { "SmartCard", N_ ("Smart Card Chip") }, + { "SmartCardLarge", N_ ("Smart Card Chip (Large)") }, + { "MagStripe", N_ ("Magnetic Stripe") }, + { "MagStripeLarge", N_ ("Magnetic Stripe (Large)") }, +}; +LIST(dyesub_stringlist_t, magicard_overcoat_holes_list, dyesub_stringitem_t, magicard_overcoat_holes); + +static int +magicard_load_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + if (caps->parameter_count && caps->parameters) + { + for (i = 0; i < caps->parameter_count; i++) + if (strcmp(name, caps->parameters[i].name) == 0) + { + stp_fill_parameter_settings(description, &(caps->parameters[i])); + break; + } + } + + if (strcmp(name, "BlackType") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &magicard_black_types_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "RejectBad") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "ColorSure") == 0) + { + description->deflt.boolean = 1; + description->is_active = 1; + } + else if (strcmp(name, "GammaCurve") == 0) + { + description->deflt.integer = 1; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 2; + description->is_active = 1; + } + else if (strcmp(name, "PowerColor") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -50; + description->bounds.integer.upper = 50; + description->is_active = 1; + } + else if (strcmp(name, "PowerBlack") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -50; + description->bounds.integer.upper = 50; + description->is_active = 1; + } + else if (strcmp(name, "PowerOC") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -50; + description->bounds.integer.upper = 50; + description->is_active = 1; + } + else if (strcmp(name, "AlignStart") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -50; + description->bounds.integer.upper = 50; + description->is_active = 1; + } + else if (strcmp(name, "AlignEnd") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -50; + description->bounds.integer.upper = 50; + description->is_active = 1; + } + else if (strcmp(name, "CardOffset") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = -15; + description->bounds.integer.upper = 15; + description->is_active = 1; + } + else if (strcmp(name, "Holokote") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &magicard_holokotes_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "HolokoteCustom") == 0) + { + description->deflt.boolean = 0; + description->is_active = 1; + } + else if (strcmp(name, "Holopatch") == 0) + { + description->deflt.integer = 0; + description->bounds.integer.lower = 0; + description->bounds.integer.upper = 24; + description->is_active = 1; + } + else if (strcmp(name, "OvercoatHole") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &magicard_overcoat_holes_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "OvercoatHoleDuplex") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &magicard_overcoat_holes_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + /* This feature only applies if the printer is duplexing! */ + if (dyesub_feature(caps, DYESUB_FEATURE_DUPLEX)) + description->is_active = 1; + } + else if (strcmp(name, "OvercoatDuplex") == 0) + { + description->bounds.str = stp_string_list_create(); + if (caps->overcoat) + { + const overcoat_list_t *llist = caps->overcoat; + + for (i = 0; i < llist->n_items; i++) + { + const overcoat_t *l = &(llist->item[i]); + stp_string_list_add_string(description->bounds.str, + l->name, gettext(l->text)); + } + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + /* This feature only applies if the printer is duplexing! */ + if (dyesub_feature(caps, DYESUB_FEATURE_DUPLEX)) + description->is_active = 1; + } else { + description->is_active = 0; + } + } + else if (strcmp(name, "MagCoer") == 0) + { + description->bounds.str = stp_string_list_create(); + + const dyesub_stringlist_t *mlist = &magicard_mag_coer_list; + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_stringitem_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, m->text); /* Do *not* want this translated, otherwise use gettext(m->text) */ + } + description->deflt.str = stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } + else if (strcmp(name, "MagStripe1") == 0) + { + description->is_active = 1; + } + else if (strcmp(name, "MagStripe2") == 0) + { + description->is_active = 1; + } + else if (strcmp(name, "MagStripe3") == 0) + { + description->is_active = 1; + } + else + { + return 0; + } + return 1; +} + +static int magicard_parse_parameters(stp_vars_t *v) +{ + dyesub_privdata_t *pd = get_privdata(v); + + const char *lpar = stp_get_string_parameter(v, "Laminate"); + const char *lpar_dpx = stp_get_string_parameter(v, "LaminateDuplex"); + const char *mag_coer = stp_get_string_parameter(v, "MagCoer"); + const char *holokote = stp_get_string_parameter(v, "Holokote"); + int holopatch = stp_get_int_parameter(v, "Holopatch"); + const char *overcoat_hole = stp_get_string_parameter(v, "OvercoatHole"); + const char *overcoat_hole_dpx = stp_get_string_parameter(v, "OvercoatHoleDuplex"); + int holokote_custom = stp_get_boolean_parameter(v, "HolokoteCustom"); + const char *blacktype = stp_get_string_parameter(v, "BlackType"); + const stp_raw_t *magstripe1 = NULL; + const stp_raw_t *magstripe2 = NULL; + const stp_raw_t *magstripe3 = NULL; + + if (overcoat_hole && !strcmp("None", overcoat_hole)) + overcoat_hole = NULL; + + /* If overcoat is off, we can't use holokote or holopatch */ + if (lpar && strcmp("On", lpar)) { + if ((holokote && strcmp(holokote, "Off")) || holopatch || overcoat_hole || holokote_custom) { + stp_eprintf(v, _("Holokote, Holopatch, and Overcoat hole features require Overcoat to be enabled!\n")); + return 0; + } + } + + /* Sanity check magstripe */ + if (stp_check_raw_parameter(v, "MagStripe1", STP_PARAMETER_ACTIVE)) { + magstripe1 = stp_get_raw_parameter(v, "MagStripe1"); + if (magstripe1->bytes >= 79) { + stp_eprintf(v, _("StpMagStripe1 must be between 0 and 78 bytes!\n")); + return 0; + } + } + if (stp_check_raw_parameter(v, "MagStripe2", STP_PARAMETER_ACTIVE)) { + magstripe2 = stp_get_raw_parameter(v, "MagStripe2"); + if (magstripe2->bytes >= 40) { + stp_eprintf(v, _("StpMagStripe2 must be between 0 and 39 bytes!\n")); + return 0; + } + } + if (stp_check_raw_parameter(v, "MagStripe3", STP_PARAMETER_ACTIVE)) { + magstripe1 = stp_get_raw_parameter(v, "MagStripe3"); + if (magstripe1->bytes >= 107) { + stp_eprintf(v, _("StpMagStripe3 must be between 0 and 106 bytes!\n")); + return 0; + } + } + + /* No need to set global params if there's no privdata yet */ + if (!pd) + return 1; + + pd->privdata.magicard.overcoat = lpar && !strcmp("On", lpar); + pd->privdata.magicard.overcoat_dpx = lpar_dpx && !strcmp("On", lpar_dpx); + pd->privdata.magicard.resin_k = blacktype && !strcmp("Resin",blacktype); + pd->privdata.magicard.reject = stp_get_boolean_parameter(v, "RejectBad"); + pd->privdata.magicard.colorsure = stp_get_boolean_parameter(v, "ColorSure"); + pd->privdata.magicard.gamma = stp_get_int_parameter(v, "GammaCurve"); + pd->privdata.magicard.power_color = stp_get_int_parameter(v, "PowerColor") + 50; + pd->privdata.magicard.power_resin = stp_get_int_parameter(v, "PowerBlack") + 50; + pd->privdata.magicard.power_overcoat = stp_get_int_parameter(v, "PowerOC") + 50; + pd->privdata.magicard.align_start = stp_get_int_parameter(v, "AlignStart") + 50; + pd->privdata.magicard.align_end = stp_get_int_parameter(v, "AlignEnd") + 50; + pd->privdata.magicard.holopatch = holopatch; + pd->privdata.magicard.overcoat_hole = overcoat_hole; + pd->privdata.magicard.overcoat_hole_dpx = overcoat_hole_dpx; + + pd->horiz_offset = stp_get_int_parameter(v, "CardOffset"); + + pd->privdata.magicard.holokote = 0; + if (holokote) { + if (!strcmp(holokote, "UltraSecure")) { + pd->privdata.magicard.holokote = 1; + } else if (!strcmp(holokote, "InterlockingRings")) { + pd->privdata.magicard.holokote = 2; + } else if (!strcmp(holokote, "Flex")) { + pd->privdata.magicard.holokote = 3; + } + } + pd->privdata.magicard.holokote_custom = holokote_custom; + + pd->privdata.magicard.mag_coer = mag_coer && !strcmp("High", mag_coer); + + if (magstripe1 && magstripe1->bytes) { + int i; + memcpy(pd->privdata.magicard.mag1, magstripe1->data, magstripe1->bytes); + pd->privdata.magicard.mag1[magstripe1->bytes] = 0; + for (i = 0 ; i < magstripe1->bytes ; i++) { + if (pd->privdata.magicard.mag1[i] < 0x20 || + pd->privdata.magicard.mag1[i] > 0x5f) { + stp_eprintf(v, _("Illegal Alphanumeric in Magstripe, 0x20->0x5F ASCII only\n")); + return 0; + } + } + if (pd->privdata.magicard.mag1[0] != '%') { + stp_eprintf(v, _("Magstripe alphanumeric data must start with '%%'\n")); + return 0; + } + if (pd->privdata.magicard.mag1[magstripe1->bytes - 1] != '?') { + stp_eprintf(v, _("Magstripe string must end with '?'\n")); + return 0; + } + } + if (magstripe2 && magstripe2->bytes) { + int i; + memcpy(pd->privdata.magicard.mag2, magstripe2->data, magstripe2->bytes); + pd->privdata.magicard.mag2[magstripe2->bytes] = 0; + for (i = 0 ; i < magstripe2->bytes ; i++) { + if (pd->privdata.magicard.mag2[i] < 0x30 || + pd->privdata.magicard.mag2[i] > 0x3f) { + stp_eprintf(v, _("Illegal Numeric in Magstripe, 0x30->0x3F ASCII only\n")); + return 0; + } + } + if (pd->privdata.magicard.mag2[0] != ';') { + stp_eprintf(v, _("Magstripe numeric data must start with ';'\n")); + return 0; + } + if (pd->privdata.magicard.mag2[magstripe2->bytes - 1] != '?') { + stp_eprintf(v, _("Magstripe data must end with '?'\n")); + return 0; + } + } + if (magstripe3 && magstripe3->bytes) { + int i; + memcpy(pd->privdata.magicard.mag3, magstripe3->data, magstripe3->bytes); + pd->privdata.magicard.mag3[magstripe3->bytes] = 0; + for (i = 0 ; i < magstripe3->bytes ; i++) { + if (pd->privdata.magicard.mag3[i] < 0x30 || + pd->privdata.magicard.mag3[i] > 0x3f) { + stp_eprintf(v, _("Illegal Numeric in Magstripe, 0x30->0x3F ASCII only\n")); + return 0; + } + } + if (pd->privdata.magicard.mag3[0] != ';') { + stp_eprintf(v, _("Magstripe numeric data must start with ';'\n")); + return 0; + } + if (pd->privdata.magicard.mag3[magstripe3->bytes - 1] != '?') { + stp_eprintf(v, _("Magstripe data must end with '?'\n")); + return 0; + } + } + return 1; +} + +/* Model capabilities */ + +static const dyesub_cap_t dyesub_model_capabilities[] = +{ + { /* Olympus P-10, P-11 */ + 2, + &rgb_ink_list, + &res_310dpi_list, + &p10_page_list, + &p10_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE, + &p10_printer_init_func, &p10_printer_end_func, + NULL, NULL, + &p10_block_init_func, NULL, + NULL, + &p10_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Olympus P-200 */ + 4, + &ymc_ink_list, + &res_320dpi_list, + &p200_page_list, + &p200_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_BLOCK_ALIGN + | DYESUB_FEATURE_PLANE_INTERLACE, + &p200_printer_init_func, &p200_printer_end_func, + &p200_plane_init_func, NULL, + NULL, NULL, + &p200_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Olympus P-300 */ + 0, + &ymc_ink_list, + &p300_res_list, + &p300_page_list, + &p300_printsize_list, + 16, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_BLOCK_ALIGN + | DYESUB_FEATURE_PLANE_INTERLACE, + &p300_printer_init_func, NULL, + NULL, &p300_plane_end_func, + &p300_block_init_func, NULL, + &p300_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Olympus P-400 */ + 1, + &ymc_ink_list, + &res_314dpi_list, + &p400_page_list, + &p400_printsize_list, + 180, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE, + &p400_printer_init_func, NULL, + &p400_plane_init_func, &p400_plane_end_func, + &p400_block_init_func, NULL, + &p400_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Olympus P-440 */ + 3, + &bgr_ink_list, + &res_314dpi_list, + &p440_page_list, + &p440_printsize_list, + 128, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT, + &p440_printer_init_func, &p440_printer_end_func, + NULL, NULL, + &p440_block_init_func, &p440_block_end_func, + NULL, + &p10_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Olympus P-S100 */ + 20, + &bgr_ink_list, + &res_306dpi_list, + &ps100_page_list, + &ps100_printsize_list, + 1808, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &ps100_printer_init_func, &ps100_printer_end_func, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon CP-10 */ + 1002, + &ymc_ink_list, + &res_300dpi_list, + &cp10_page_list, + &cp10_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cp10_printer_init_func, NULL, + &cpx00_plane_init_func, NULL, + NULL, NULL, + &cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon CP-100, CP-200, CP-300 */ + 1000, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cpx00_printer_init_func, NULL, + &cpx00_plane_init_func, NULL, + NULL, NULL, + &cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon CP-220, CP-330, SELPHY CP400, SELPHY CP500, SELPHY CP510, + SELPHY CP520, SELPHY CP530, SELPHY CP600, SELPHY CP710, + SELPHY CP720, SELPHY CP730, SELPHY CP740, SELPHY CP750, + SELPHY CP760, SELPHY CP770, SELPHY CP780 */ + 1001, + &ymc_ink_list, + &res_300dpi_list, + &cp220_page_list, + &cp220_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cpx00_printer_init_func, NULL, + &cpx00_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY ES1 */ + 1003, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &es1_printer_init_func, NULL, + &es1_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY ES2, SELPHY ES20 */ + 1005, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &es2_printer_init_func, NULL, + &es2_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY ES3, SELPHY ES30 */ + 1006, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &es3_printer_init_func, &es3_printer_end_func, + &es2_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY ES40 */ + 1007, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &es40_printer_init_func, &es3_printer_end_func, + &es2_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY CP790 */ + 1008, + &ymc_ink_list, + &res_300dpi_list, + &cp220_page_list, + &cp220_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cp790_printer_init_func, &es3_printer_end_func, + &es2_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY CP800 */ + 1009, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cpx00_printer_init_func, NULL, + &cpx00_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon SELPHY CP900 */ + 1010, + &ymc_ink_list, + &res_300dpi_list, + &cpx00_page_list, + &cpx00_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cpx00_printer_init_func, &cp900_printer_end_func, + &cpx00_plane_init_func, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Canon CP820, CP910, CP1000, CP1200 */ + 1011, + &cmy_ink_list, + &res_300dpi_list, + &cp910_page_list, + &cp910_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &cp910_printer_init_func, NULL, + NULL, NULL, + NULL, NULL, + cpx00_adjust_curves, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony UP-DP10 */ + 2000, + &cmy_ink_list, + &res_300dpi_list, + &updp10_page_list, + &updp10_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS, + &updp10_printer_init_func, &updp10_printer_end_func, + NULL, NULL, + NULL, NULL, + updp10_adjust_curves, + &updp10_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony UP-DR150 */ + 2001, + &rgb_ink_list, + &res_334dpi_list, + &updr150_page_list, + &updr150_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &updr150_printer_init_func, &updr150_printer_end_func, + NULL, NULL, + NULL, NULL, + NULL, + &updp10_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony DPP-EX5, DPP-EX7 */ + 2002, + &rgb_ink_list, + &res_403dpi_list, + &dppex5_page_list, + &dppex5_printsize_list, + 100, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS, + &dppex5_printer_init, &dppex5_printer_end, + NULL, NULL, + &dppex5_block_init, NULL, + NULL, + &dppex5_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony UP-DR100 */ + 2003, + &rgb_ink_list, + &res_334dpi_list, + &updr100_page_list, + &updr100_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT, + &updr100_printer_init_func, &updr100_printer_end_func, + NULL, NULL, + NULL, NULL, + NULL, + &updr100_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony UP-DR200 */ + 2004, + &rgb_ink_list, + &res_334dpi_list, + &updr200_page_list, + &updr200_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &updr200_printer_init_func, &updr150_printer_end_func, + NULL, NULL, + NULL, NULL, + NULL, + &updr200_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Sony UP-CR10L / DNP SL10 */ + 2005, + &rgb_ink_list, + &res_300dpi_list, + &upcr10_page_list, + &upcr10_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &upcr10_printer_init_func, &upcr10_printer_end_func, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Fujifilm Printpix CX-400 */ + 3000, + &rgb_ink_list, + &res_310dpi_list, + &cx400_page_list, + &cx400_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS, + &cx400_printer_init_func, NULL, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Fujifilm Printpix CX-550 */ + 3001, + &rgb_ink_list, + &res_310dpi_list, + &cx400_page_list, + &cx400_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_BORDERLESS, + &cx400_printer_init_func, NULL, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Fujifilm FinePix NX-500 */ + 3002, + &rgb_ink_list, + &res_306dpi_list, + &nx500_page_list, + &nx500_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT, + &nx500_printer_init_func, NULL, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Easyshare Dock family */ + 4000, + &ymc_ink_list, + &res_300dpi_list, + &kodak_dock_page_list, + &kodak_dock_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE, + &kodak_dock_printer_init, NULL, + &kodak_dock_plane_init, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Photo Printer 6800 */ + 4001, + &rgb_ink_list, + &res_300dpi_list, + &kodak_6800_page_list, + &kodak_6800_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &kodak_68xx_printer_init, NULL, + NULL, NULL, /* No plane funcs */ + NULL, NULL, /* No block funcs */ + NULL, + &kodak_6800_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Photo Printer 6850 */ + 4002, + &rgb_ink_list, + &res_300dpi_list, + &kodak_6850_page_list, + &kodak_6850_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &kodak_68xx_printer_init, NULL, + NULL, NULL, /* No plane funcs */ + NULL, NULL, /* No block funcs */ + NULL, + &kodak_6800_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Photo Printer 605 */ + 4003, + &rgb_ink_list, + &res_300dpi_list, + &kodak_605_page_list, + &kodak_605_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &kodak_605_printer_init, NULL, + NULL, NULL, /* No plane funcs */ + NULL, NULL, /* No block funcs */ + NULL, + &kodak_605_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Professional 1400 */ + 4004, + &bgr_ink_list, + &res_301dpi_list, + &kodak_1400_page_list, + &kodak_1400_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH + | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_ROW_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_1400_printer_init, NULL, + NULL, NULL, + NULL, NULL, + NULL, + &kodak_6800_overcoat_list, &kodak_1400_media_list, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Photo Printer 805 */ + 4005, + &bgr_ink_list, + &res_301dpi_list, + &kodak_805_page_list, + &kodak_805_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH + | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_ROW_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_805_printer_init, NULL, + NULL, NULL, /* No plane funcs */ + NULL, NULL, /* No block funcs */ + NULL, + &kodak_6800_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Professional 9810 (and 8800) */ + 4006, + &ymc_ink_list, + &res_300dpi_list, + &kodak_9810_page_list, + &kodak_9810_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_9810_printer_init, &kodak_9810_printer_end, + &kodak_9810_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &kodak_9810_overcoat_list, NULL, + NULL, NULL, + kodak_9810_parameters, + kodak_9810_parameter_count, + kodak_9810_load_parameters, + kodak_9810_parse_parameters, + }, + { /* Kodak 8810 */ + 4007, + &bgr_ink_list, + &res_300dpi_list, + &kodak_8810_page_list, + &kodak_8810_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_8810_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &kodak_8810_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak 7000/7010 */ + 4008, + &bgr_ink_list, + &res_300dpi_list, + &kodak_7000_page_list, + &kodak_7000_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_70xx_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &kodak_7000_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak 7015 */ + 4009, + &bgr_ink_list, + &res_300dpi_list, + &kodak_7015_page_list, + &kodak_7015_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &kodak_70xx_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &kodak_7000_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Kodak Professional 8500 */ + 4100, + &bgr_ink_list, + &res_314dpi_list, + &kodak_8500_page_list, + &kodak_8500_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &kodak_8500_printer_init, &kodak_8500_printer_end, + NULL, NULL, /* No plane funcs */ + NULL, NULL, /* No block funcs */ + NULL, + &kodak_8500_overcoat_list, &kodak_8500_media_list, + NULL, NULL, + kodak_8500_parameters, + kodak_8500_parameter_count, + kodak_8500_load_parameters, + kodak_8500_parse_parameters, + }, + { /* Mitsubishi CP3020D/DU/DE */ + 4101, + &ymc_ink_list, + &res_314dpi_list, + &mitsu_cp3020d_page_list, + &mitsu_cp3020d_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp3020d_printer_init, &mitsu_cp3020d_printer_end, + &mitsu_cp3020d_plane_init, &mitsu_cp3020d_plane_end, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Mitsubishi CP3020DA/DAE */ + 4102, + &bgr_ink_list, + &res_314dpi_list, + &mitsu_cp3020d_page_list, + &mitsu_cp3020d_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp3020da_printer_init, &mitsu_cp3020da_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Mitsubishi CP9550D */ + 4103, + &rgb_ink_list, + &res_346dpi_list, + &mitsu_cp9550_page_list, + &mitsu_cp9550_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9550_printer_init, &mitsu_cp9550_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + mitsu9550_parameters, + mitsu9550_parameter_count, + mitsu9550_load_parameters, + mitsu9550_parse_parameters, + }, + { /* Mitsubishi CP9810D */ + 4104, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cp9810_page_list, + &mitsu_cp9810_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9810_printer_init, &mitsu_cp9810_printer_end, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cp9810_overcoat_list, NULL, + NULL, NULL, + mitsu98xx_parameters, + mitsu98xx_parameter_count, + mitsu98xx_load_parameters, + mitsu98xx_parse_parameters, + }, + { /* Mitsubishi CPD70D */ + 4105, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cpd70x_page_list, + &mitsu_cpd70x_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_WHITE_BORDER | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cpd70x_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu70x_parameters, + mitsu70x_parameter_count, + mitsu70x_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Mitsubishi CPK60D */ + 4106, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cpk60_page_list, + &mitsu_cpk60_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cpk60_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu70x_parameters, + mitsu70x_parameter_count, + mitsu_k60_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Mitsubishi CPD80D */ + 4107, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cpd80_page_list, + &mitsu_cpd80_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_WHITE_BORDER | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cpd70x_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu70x_parameters, + mitsu70x_parameter_count, + mitsu70x_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Kodak 305 */ + 4108, + &bgr_ink_list, + &res_300dpi_list, + &kodak305_page_list, + &kodak305_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &kodak305_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu70x_parameters, + mitsu70x_parameter_count, + mitsu_k60_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Mitsubishi CPD90D */ + 4109, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cpd90_page_list, + &mitsu_cpd90_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cpd90_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + NULL, mitsu_cpd90_job_end, + mitsu_d90_parameters, + mitsu_d90_parameter_count, + mitsu_d90_load_parameters, + mitsu_d90_parse_parameters, + }, + { /* Mitsubishi CP9600D */ + 4110, + &rgb_ink_list, + &res_mitsu9600_dpi_list, + &mitsu_cp9600_page_list, + &mitsu_cp9600_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9600_printer_init, &mitsu_cp9600_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Mitsubishi CP9550DW-S */ + 4111, + &rgb_ink_list, + &res_346dpi_list, + &mitsu_cp9550s_page_list, + &mitsu_cp9550s_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9550_printer_init, &mitsu_cp9550s_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + mitsu9550_parameters, + mitsu9550_parameter_count, + mitsu9550_load_parameters, + mitsu9550_parse_parameters, + }, + { /* Fujifilm ASK-300 */ + 4112, + &bgr_ink_list, + &res_300dpi_list, + &fuji_ask300_page_list, + &fuji_ask300_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_WHITE_BORDER | DYESUB_FEATURE_NATIVECOPIES, + &fuji_ask300_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu70x_parameters, + mitsu70x_parameter_count, + mitsu_k60_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Mitsubishi CP9800D */ + 4113, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cp9810_page_list, + &mitsu_cp9810_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9800_printer_init, &mitsu_cp9810_printer_end, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + mitsu98xx_parameters, + mitsu98xx_parameter_count, + mitsu98xx_load_parameters, + mitsu98xx_parse_parameters, + }, + { /* Mitsubishi P95D/DW */ + 4114, + &w_ink_list, + &res_325dpi_list, + &mitsu_p95d_page_list, + &mitsu_p95d_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_MONOCHROME | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_p95d_printer_init, &mitsu_p95d_printer_end, + &mitsu_p95d_plane_start, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, &mitsu_p95d_media_list, + NULL, NULL, + mitsu_p95d_parameters, + mitsu_p95d_parameter_count, + mitsu_p95d_load_parameters, + mitsu_p95d_parse_parameters, + }, + { /* Mitsubishi CP9500D */ + 4115, + &rgb_ink_list, + &res_m9500_list, + &mitsu_cp9500_page_list, + &mitsu_cp9500_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cp9500_printer_init, &mitsu_cp9500_printer_end, + &mitsu_cp3020da_plane_init, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + mitsu9500_parameters, + mitsu9500_parameter_count, + mitsu9500_load_parameters, + mitsu9500_parse_parameters, + }, + { /* Mitsubishi P93D/DW */ + 4116, + &w_ink_list, + &res_325dpi_list, + &mitsu_p95d_page_list, + &mitsu_p95d_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT + | DYESUB_FEATURE_MONOCHROME | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_p93d_printer_init, &mitsu_p95d_printer_end, + &mitsu_p95d_plane_start, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, &mitsu_p93d_media_list, + NULL, NULL, + mitsu_p93d_parameters, + mitsu_p93d_parameter_count, + mitsu_p93d_load_parameters, + mitsu_p93d_parse_parameters, + }, + { /* Mitsubishi CPD707D */ + 4117, + &bgr_ink_list, + &res_300dpi_list, + &mitsu_cpd70x_page_list, + &mitsu_cpd70x_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_WHITE_BORDER | DYESUB_FEATURE_NATIVECOPIES, + &mitsu_cpd70x_printer_init, NULL, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + &mitsu_cpd70x_overcoat_list, NULL, + mitsu_cpd70k60_job_start, NULL, + mitsu707_parameters, + mitsu707_parameter_count, + mitsu707_load_parameters, + mitsu70x_parse_parameters, + }, + { /* Fujifilm ASK-2000/2500 */ + 4200, + &bgr_ink_list, + &res_300dpi_list, + &fuji_ask2000_page_list, + &fuji_ask2000_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &fuji_ask2000_printer_init, &fuji_ask2000_printer_end, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Fujifilm ASK-4000 */ + 4201, + &bgr_ink_list, + &res_300dpi_list, + &fuji_ask4000_page_list, + &fuji_ask4000_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &fuji_ask4000_printer_init, &fuji_ask4000_printer_end, + NULL, NULL, + NULL, NULL, /* No block funcs */ + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Shinko CHC-S9045 (experimental) */ + 5000, + &rgb_ink_list, + &res_300dpi_list, + &shinko_chcs9045_page_list, + &shinko_chcs9045_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT, + &shinko_chcs9045_printer_init, NULL, + NULL, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Shinko/Sinfonia CHC-S2145 */ + 5001, + &rgb_ink_list, + &res_300dpi_list, + &shinko_chcs2145_page_list, + &shinko_chcs2145_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &shinko_chcs2145_printer_init, &shinko_chcs2145_printer_end, + NULL, NULL, /* No planes */ + NULL, NULL, /* No blocks */ + NULL, + &shinko_chcs2145_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Shinko/Sinfonia CHC-S1245 */ + 5002, + &rgb_ink_list, + &res_300dpi_list, + &shinko_chcs1245_page_list, + &shinko_chcs1245_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &shinko_chcs1245_printer_init, &shinko_chcs2145_printer_end, + NULL, NULL, /* No planes */ + NULL, NULL, /* No blocks */ + NULL, + &shinko_chcs1245_overcoat_list, NULL, + NULL, NULL, + shinko_chcs1245_parameters, + shinko_chcs1245_parameter_count, + shinko_chcs1245_load_parameters, + shinko_chcs1245_parse_parameters, + }, + { /* Shinko/Sinfonia CHC-S6245 */ + 5003, + &rgb_ink_list, + &res_300dpi_list, + &shinko_chcs6245_page_list, + &shinko_chcs6245_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &shinko_chcs6245_printer_init, &shinko_chcs2145_printer_end, + NULL, NULL, /* No planes */ + NULL, NULL, /* No blocks */ + NULL, + &shinko_chcs6245_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Shinko/Sinfonia CHC-S6145 */ + 5004, +#ifdef S6145_YMC + &ymc_ink_list, +#else + &rgb_ink_list, +#endif + &res_300dpi_list, + &shinko_chcs6145_page_list, + &shinko_chcs6145_printsize_list, + SHRT_MAX, +#ifdef S6145_YMC + DYESUB_FEATURE_PLANE_INTERLACE | +#endif + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &shinko_chcs6145_printer_init, &shinko_chcs2145_printer_end, + NULL, NULL, /* No planes */ + NULL, NULL, /* No blocks */ + NULL, + &shinko_chcs6145_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* CIAAT Brava 21 (aka CHC-S6145D) */ + 5005, +#ifdef S6145_YMC + &ymc_ink_list, +#else + &rgb_ink_list, +#endif + &res_300dpi_list, + &ciaat_brava21_page_list, + &ciaat_brava21_printsize_list, + SHRT_MAX, +#ifdef S6145_YMC + DYESUB_FEATURE_PLANE_INTERLACE | +#endif + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_NATIVECOPIES, + &shinko_chcs6145_printer_init, &shinko_chcs2145_printer_end, + NULL, NULL, /* No planes */ + NULL, NULL, /* No blocks */ + NULL, + &shinko_chcs6145_overcoat_list, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Dai Nippon Printing DS40 */ + 6000, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds40_page_list, + &dnpds40_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &dnpds40_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds40_overcoat_list, NULL, + NULL, NULL, + ds40_parameters, + ds40_parameter_count, + ds40_load_parameters, + ds40_parse_parameters, + }, + { /* Dai Nippon Printing DS80 */ + 6001, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds80_page_list, + &dnpds80_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &dnpds80_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds40_overcoat_list, NULL, + NULL, NULL, + ds40_parameters, + ds40_parameter_count, + ds40_load_parameters, + dnpds80_parse_parameters, + }, + { /* Dai Nippon Printing DSRX1 */ + 6002, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpsrx1_page_list, + &dnpsrx1_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &dnpdsrx1_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds40_overcoat_list, NULL, + NULL, NULL, + ds40_parameters, + ds40_parameter_count, + ds40_load_parameters, + ds40_parse_parameters, + }, + { /* Dai Nippon Printing DS620 */ + 6003, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds620_page_list, + &dnpds620_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &dnpds620_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds620_overcoat_list, NULL, + NULL, NULL, + ds40_parameters, + ds40_parameter_count, + ds40_load_parameters, + ds40_parse_parameters, + }, + { /* Citizen CW-01 */ + 6005, + &bgr_ink_list, + &res_citizen_cw01_dpi_list, + &citizen_cw01_page_list, + &citizen_cw01_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES, + &citizen_cw01_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + NULL, NULL, + NULL, NULL, + NULL, 0, NULL, NULL, + }, + { /* Dai Nippon Printing DS80DX */ + 6006, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds80dx_page_list, + &dnpds80dx_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_DUPLEX | DYESUB_FEATURE_NATIVECOPIES, + &dnpds80_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds40_overcoat_list, &dnpds80dx_media_list, + NULL, NULL, + ds40_parameters, + ds40_parameter_count, + ds40_load_parameters, + dnpds80dx_parse_parameters, + }, + { /* Dai Nippon Printing DS820 */ + 6007, + &bgr_ink_list, + &res_dnpds40_dpi_list, + &dnpds820_page_list, + &dnpds820_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_PLANE_LEFTTORIGHT | DYESUB_FEATURE_NATIVECOPIES , + &dnpds820_printer_start, &dnpds40_printer_end, + &dnpds40_plane_init, NULL, + NULL, NULL, + NULL, + &dnpds620_overcoat_list, NULL, + NULL, NULL, + ds820_parameters, + ds820_parameter_count, + ds820_load_parameters, + ds820_parse_parameters, + }, + { /* Magicard Series w/ Duplex */ + 7000, + &ymc_ink_list, + &res_300dpi_list, + &magicard_page_list, + &magicard_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_DUPLEX | DYESUB_FEATURE_NATIVECOPIES, + &magicard_printer_init, &magicard_printer_end, + NULL, magicard_plane_end, + NULL, NULL, + NULL, + &magicard_overcoat_list, NULL, + NULL, NULL, + magicard_parameters, + magicard_parameter_count, + magicard_load_parameters, + magicard_parse_parameters, + }, + { /* Magicard Series w/o Duplex */ + 7001, + &ymc_ink_list, + &res_300dpi_list, + &magicard_page_list, + &magicard_printsize_list, + SHRT_MAX, + DYESUB_FEATURE_FULL_WIDTH | DYESUB_FEATURE_FULL_HEIGHT | DYESUB_FEATURE_WHITE_BORDER + | DYESUB_FEATURE_PLANE_INTERLACE | DYESUB_FEATURE_NATIVECOPIES, + &magicard_printer_init, &magicard_printer_end, + NULL, magicard_plane_end, + NULL, NULL, + NULL, + &magicard_overcoat_list, NULL, + NULL, NULL, + magicard_parameters, + magicard_parameter_count, + magicard_load_parameters, + magicard_parse_parameters, + }, +}; + +static const stp_parameter_t the_parameters[] = +{ + { + "PageSize", N_("Page Size"), "Color=No,Category=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, STP_CHANNEL_NONE, 1, 0 + }, + { + "MediaType", N_("Media Type"), "Color=Yes,Category=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, STP_CHANNEL_NONE, 1, 0 + }, + { + "InputSlot", N_("Media Source"), "Color=No,Category=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, STP_CHANNEL_NONE, 1, 0 + }, + { + "Resolution", N_("Resolution"), "Color=Yes,Category=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, STP_CHANNEL_NONE, 1, 0 + }, + { + "InkType", N_("Ink Type"), "Color=Yes,Category=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, STP_CHANNEL_NONE, 1, 0 + }, + { /* TRANSLATORS: Some dye sublimation printers are able to achieve + better durability of output by covering it with transparent + overcoat surface. This surface can be of different patterns: + common are matte, glossy or texture. + + This is called "Laminate" instead of "Overcoat" for backwards + compatibility reasons. + */ + "Laminate", N_("Overcoat Pattern"), "Color=No,Category=Advanced Printer Setup", + N_("Overcoat Pattern"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "Borderless", N_("Borderless"), "Color=No,Category=Advanced Printer Setup", + N_("Print without borders"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 0, STP_CHANNEL_NONE, 1, 0 + }, + { + "PrintingMode", N_("Printing Mode"), "Color=Yes,Category=Core Parameter", + N_("Printing Output Mode"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "Duplex", N_("Double-Sided Printing"), "Color=No,Category=Basic Printer Setup", + N_("Duplex/Tumble Setting"), + STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 + }, + { + "NativeCopies", N_("Printer Generates Copies Natively"), "Color=No,Category=Job Mode", + N_("Printer Generates Copies"), + STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_FEATURE, + STP_PARAMETER_LEVEL_INTERNAL, 1, 0, STP_CHANNEL_NONE, 0, 1 + }, +}; + +static 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 + }, +}; + +static const int float_parameter_count = +sizeof(float_parameters) / sizeof(const float_param_t); + +/* + * Duplex support - modes available + * Note that the internal names MUST match those in cups/genppd.c else the + * PPD files will not be generated correctly + */ + +static const stp_param_string_t duplex_types[] = +{ + { "None", N_ ("Off") }, + { "DuplexNoTumble", N_ ("Long Edge (Standard)") }, + { "DuplexTumble", N_ ("Short Edge (Flip)") } +}; +#define NUM_DUPLEX (sizeof (duplex_types) / sizeof (stp_param_string_t)) + +static const dyesub_cap_t* dyesub_get_model_capabilities(const stp_vars_t *v, int model) +{ + int i; + int models = sizeof(dyesub_model_capabilities) / sizeof(dyesub_cap_t); + + for (i=0; i<models; i++) + { + if (dyesub_model_capabilities[i].model == model) + return &(dyesub_model_capabilities[i]); + } + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub: model %d not found in capabilities list.\n", model); + return &(dyesub_model_capabilities[0]); +} + +static const overcoat_t* dyesub_get_overcoat_pattern(stp_vars_t *v) +{ + const char *lpar = stp_get_string_parameter(v, "Laminate"); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const overcoat_list_t *llist = caps->overcoat; + const overcoat_t *l = NULL; + int i; + + for (i = 0; i < llist->n_items; i++) + { + l = &(llist->item[i]); + if (strcmp(l->name, lpar) == 0) + break; + } + return l; +} + +static const dyesub_media_t* dyesub_get_mediatype(stp_vars_t *v) +{ + const char *mpar = stp_get_string_parameter(v, "MediaType"); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const dyesub_media_list_t *mlist = caps->media; + const dyesub_media_t *m = NULL; + int i; + + for (i = 0; i < mlist->n_items; i++) + { + m = &(mlist->item[i]); + if (strcmp(m->name, mpar) == 0) + break; + } + return m; +} + +static void +dyesub_printsize(const stp_vars_t *v, + int *width, + int *height) +{ + int i; + const char *page = stp_get_string_parameter(v, "PageSize"); + const char *resolution = stp_get_string_parameter(v, "Resolution"); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const dyesub_printsize_list_t *p = caps->printsize; + + for (i = 0; i < p->n_items; i++) + { + if (strcmp(p->item[i].res_name,resolution) == 0 && + strcmp(p->item[i].pagesize_name,page) == 0) + { + *width = p->item[i].width_px; + *height = p->item[i].height_px; + return; + } + } + stp_eprintf(v, "dyesub_printsize: printsize not found (%s, %s)\n", + page, resolution); +} + +static int +dyesub_feature(const dyesub_cap_t *caps, int feature) +{ + return ((caps->features & feature) == feature); +} + +static stp_parameter_list_t +dyesub_list_parameters(const stp_vars_t *v) +{ + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, stp_get_model_id(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)); + if (caps->parameter_count && caps->parameters) + for (i = 0; i < caps->parameter_count ; i++) + stp_parameter_list_add_param(ret, &(caps->parameters[i])); + + return ret; +} + +static void +dyesub_parameters(const stp_vars_t *v, const char *name, + stp_parameter_t *description) +{ + int i; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + description->p_type = STP_PARAMETER_TYPE_INVALID; + if (name == NULL) + return; + + description->deflt.str = NULL; + 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; + } + + 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 (caps->load_parameters) /* do *NOT* use dyesub_exec() here */ + { + if (caps->load_parameters(v, name, description)) + return; /* Ie parameter handled */ + } + + if (strcmp(name, "PageSize") == 0) + { + int default_specified = 0; + const dyesub_pagesize_list_t *p = caps->pages; + + description->bounds.str = stp_string_list_create(); + + /* Walk the list of pagesizes for the printer */ + for (i = 0; i < p->n_items; i++) + { + stp_string_list_add_string(description->bounds.str, + p->item[i].psize.name, + gettext(p->item[i].psize.text)); + if (! default_specified && + p->item[i].psize.width > 0 && p->item[i].psize.height > 0) + { + description->deflt.str = p->item[i].psize.name; + default_specified = 1; + } + } + if (!default_specified) + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + } + else if (strcmp(name, "MediaType") == 0) + { + description->bounds.str = stp_string_list_create(); + if (caps->media) { + const dyesub_media_list_t *mlist = caps->media; + + for (i = 0; i < mlist->n_items; i++) + { + const dyesub_media_t *m = &(mlist->item[i]); + stp_string_list_add_string(description->bounds.str, + m->name, gettext(m->text)); + } + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else { + description->is_active = 0; + } + } + else if (strcmp(name, "Resolution") == 0) + { + char res_text[24]; + const dyesub_resolution_list_t *r = caps->resolution; + + description->bounds.str = stp_string_list_create(); + for (i = 0; i < r->n_items; i++) + { + sprintf(res_text, "%s DPI", r->item[i].name); + stp_string_list_add_string(description->bounds.str, + r->item[i].name, gettext(res_text)); + } + if (r->n_items < 1) + description->is_active = 0; + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + } + else if (strcmp(name, "InkType") == 0) + { + description->bounds.str = stp_string_list_create(); + for (i = 0; i < caps->inks->n_items; i++) + stp_string_list_add_string(description->bounds.str, + caps->inks->item[i].name, gettext(caps->inks->item[i].name)); + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + if (caps->inks->n_items < 2) + description->is_active = 0; + } + else if (strcmp(name, "Laminate") == 0) + { + description->bounds.str = stp_string_list_create(); + if (caps->overcoat) + { + const overcoat_list_t *llist = caps->overcoat; + + for (i = 0; i < llist->n_items; i++) + { + const overcoat_t *l = &(llist->item[i]); + stp_string_list_add_string(description->bounds.str, + l->name, gettext(l->text)); + } + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + description->is_active = 1; + } else { + description->is_active = 0; + } + } + else if (strcmp(name, "Borderless") == 0) + { + if (dyesub_feature(caps, DYESUB_FEATURE_BORDERLESS)) + description->is_active = 1; + } + else if (strcmp(name, "PrintingMode") == 0) + { + description->bounds.str = stp_string_list_create(); + if (dyesub_feature(caps, DYESUB_FEATURE_MONOCHROME)) + stp_string_list_add_string(description->bounds.str, + "BW", _("Black and White")); + else + stp_string_list_add_string(description->bounds.str, + "Color", _("Color")); + description->deflt.str = + stp_string_list_param(description->bounds.str, 0)->name; + } + else if (strcmp(name, "Duplex") == 0) + { + int offer_duplex=0; + + description->bounds.str = stp_string_list_create(); + + /* + * Don't offer the Duplex/Tumble options if the JobMode parameter is + * set to "Page" Mode. + * "Page" mode is set by the Gimp Plugin, which only outputs one page at a + * time, so Duplex/Tumble is meaningless. + */ + + if (stp_get_string_parameter(v, "JobMode")) + offer_duplex = strcmp(stp_get_string_parameter(v, "JobMode"), "Page"); + else + offer_duplex=1; + + if (offer_duplex && dyesub_feature(caps, DYESUB_FEATURE_DUPLEX)) + { + description->deflt.str = duplex_types[0].name; + for (i=0; i < NUM_DUPLEX; i++) + { + stp_string_list_add_string(description->bounds.str, + duplex_types[i].name,gettext(duplex_types[i].text)); + } + } + else + description->is_active = 0; + } + else if (strcmp(name, "NativeCopies") == 0) + { + description->deflt.boolean = dyesub_feature(caps, DYESUB_FEATURE_NATIVECOPIES); + description->is_active = 1; + } + else + description->is_active = 0; +} + + +static const dyesub_pagesize_t* +dyesub_get_pagesize(const stp_vars_t *v, const char *page) +{ + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const dyesub_pagesize_list_t *p = caps->pages; + int i; + if (page == NULL) + return NULL; + + for (i = 0; i < p->n_items; i++) + { + if (strcmp(p->item[i].psize.name,page) == 0) + return &(p->item[i]); + } + return NULL; +} + +static const dyesub_pagesize_t* +dyesub_current_pagesize(const stp_vars_t *v) +{ + const char *page = stp_get_string_parameter(v, "PageSize"); + return dyesub_get_pagesize(v, page); +} + +static const stp_papersize_t * +dyesub_describe_papersize(const stp_vars_t *v, const char *name) +{ + const dyesub_pagesize_t *pagesize = dyesub_get_pagesize(v, name); + if (pagesize) + return &(pagesize->psize); + else + return NULL; +} + +static void +dyesub_media_size(const stp_vars_t *v, + stp_dimension_t *width, + stp_dimension_t *height) +{ + const dyesub_pagesize_t *pt = dyesub_current_pagesize(v); + stp_default_media_size(v, width, height); + + if (pt && pt->psize.width > 0) + *width = pt->psize.width; + if (pt && pt->psize.height > 0) + *height = pt->psize.height; +} + +static void +dyesub_imageable_area_internal(const stp_vars_t *v, + int use_maximum_area, + stp_dimension_t *left, + stp_dimension_t *right, + stp_dimension_t *bottom, + stp_dimension_t *top, + int *print_mode) +{ + stp_dimension_t width, height; + const dyesub_pagesize_t *pt = dyesub_current_pagesize(v); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + + dyesub_media_size(v, &width, &height); + if (use_maximum_area + || (dyesub_feature(caps, DYESUB_FEATURE_BORDERLESS) && + stp_get_boolean_parameter(v, "Borderless")) + || !pt) + { + *left = 0; + *top = 0; + *right = width; + *bottom = height; + } + else + { + *left = pt->psize.left; + *top = pt->psize.top; + *right = width - pt->psize.right; + *bottom = height - pt->psize.bottom; + } + if (pt) + *print_mode = pt->print_mode; + else + *print_mode = DYESUB_PORTRAIT; +} + +static void +dyesub_imageable_area(const stp_vars_t *v, + stp_dimension_t *left, + stp_dimension_t *right, + stp_dimension_t *bottom, + stp_dimension_t *top) +{ + int not_used; + dyesub_imageable_area_internal(v, 0, left, right, bottom, top, ¬_used); +} + +static void +dyesub_maximum_imageable_area(const stp_vars_t *v, + stp_dimension_t *left, + stp_dimension_t *right, + stp_dimension_t *bottom, + stp_dimension_t *top) +{ + int not_used; + const int model = stp_get_model_id(v); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, model); + + /* For printers that report FEATURE_WHITE_BORDER, we need to + respect the margins they define as that's the printable area. + The SELPHY models support FEATURE_BORDERLESS as well, so handle + that special case. */ + + dyesub_imageable_area_internal(v, + (!(dyesub_feature(caps, DYESUB_FEATURE_WHITE_BORDER) && + !dyesub_feature(caps, DYESUB_FEATURE_BORDERLESS))), + left, right, bottom, top, ¬_used); +} + +static void +dyesub_limit(const stp_vars_t *v, /* I */ + stp_dimension_t *width, stp_dimension_t *height, + stp_dimension_t *min_width, stp_dimension_t *min_height) +{ + *width = SHRT_MAX; + *height = SHRT_MAX; + *min_width = 1; + *min_height = 1; +} + +static void +dyesub_describe_resolution(const stp_vars_t *v, + stp_resolution_t *x, stp_resolution_t *y) +{ + const char *resolution = stp_get_string_parameter(v, "Resolution"); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const dyesub_resolution_list_t *r = caps->resolution; + int i; + + *x = -1; + *y = -1; + if (resolution) + { + for (i = 0; i < r->n_items; i++) + { + if (strcmp(resolution, r->item[i].name) == 0) + { + *x = r->item[i].w_dpi; + *y = r->item[i].h_dpi; + break; + } + } + } + return; +} + +static const char * +dyesub_describe_output_internal(const stp_vars_t *v, dyesub_print_vars_t *pv) +{ + const char *ink_type = stp_get_string_parameter(v, "InkType"); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, + stp_get_model_id(v)); + const char *output_type; + int i; + + pv->ink_channels = 1; + pv->ink_order = "\1"; + output_type = "CMY"; + + if (ink_type) + { + for (i = 0; i < caps->inks->n_items; i++) + if (strcmp(ink_type, caps->inks->item[i].name) == 0) + { + output_type = caps->inks->item[i].output_type; + pv->ink_channels = caps->inks->item[i].output_channels; + pv->ink_order = caps->inks->item[i].channel_order; + break; + } + } + + return output_type; +} + +static const char * +dyesub_describe_output(const stp_vars_t *v) +{ + dyesub_print_vars_t ipv; + return dyesub_describe_output_internal(v, &ipv); +} + +#define NPUTC_BUFSIZE (512) + +static void +dyesub_nputc(stp_vars_t *v, char byte, int count) +{ + char buf[NPUTC_BUFSIZE]; + + if (count == 1) + stp_putc(byte, v); + else + { + int i; + int size = count; + int blocks = size / NPUTC_BUFSIZE; + int leftover = size % NPUTC_BUFSIZE; + if (size > NPUTC_BUFSIZE) + size = NPUTC_BUFSIZE; + (void) memset(buf, byte, size); + if (blocks) + for (i = 0; i < blocks; i++) + stp_zfwrite(buf, size, 1, v); + if (leftover) + stp_zfwrite(buf, leftover, 1, v); + } +} + +static void +dyesub_swap_ints(int *a, int *b) +{ + int t = *a; + *a = *b; + *b = t; +} + +static void +dyesub_adjust_curve(stp_vars_t *v, + const char *color_adj, + const char *color_curve) +{ + stp_curve_t *adjustment = NULL; + + if (color_adj && + !stp_check_curve_parameter(v, color_curve, STP_PARAMETER_ACTIVE)) + { + adjustment = stp_curve_create_from_string(color_adj); + stp_set_curve_parameter(v, color_curve, adjustment); + stp_set_curve_parameter_active(v, color_curve, STP_PARAMETER_ACTIVE); + stp_curve_destroy(adjustment); + } +} + +static void +dyesub_exec(stp_vars_t *v, + void (*func)(stp_vars_t *), + const char *debug_string) +{ + if (func) + { + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: %s\n", debug_string); + (*func)(v); + } +} + +static int +dyesub_exec_check(stp_vars_t *v, + int (*func)(stp_vars_t *), + const char *debug_string) +{ + if (func) + { + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: %s\n", debug_string); + return (*func)(v); + } + return 1; +} + +/* XXX FIXME: This is "point" interpolation. Be smarter! + eg: Average (average all pixels that touch this one) + BiLinear (scale based on linear interpolation) + BiCubic (scale based on weighted average, based on proximity) + Lanczos (awesome!! but slow) +*/ +static int +dyesub_interpolate(int point, int olddim, int newdim) +{ +#if 0 + /* Perform arithematic rounding. Is there a point? */ + int result = ((point * 2 * newdim / olddim) + 1) / 2; + if (result >= newdim) + result--; +#else + int result = (point * newdim / olddim); +#endif + + return result; +} + +static void +dyesub_free_image(dyesub_print_vars_t *pv, stp_image_t *image) +{ + unsigned short** image_data = pv->image_data; + int image_px_height = pv->image_rows; + int i; + + for (i = 0; i< image_px_height; i++) + if (image_data[i]) + stp_free(image_data[i]); + if (image_data) + stp_free(image_data); +} + +static unsigned short ** +dyesub_read_image(stp_vars_t *v, + dyesub_print_vars_t *pv, + stp_image_t *image) +{ + int image_px_width = stp_image_width(image); + int image_px_height = stp_image_height(image); + int row_size = image_px_width * pv->ink_channels * sizeof(short); + unsigned short **image_data; + unsigned int zero_mask; + int i; + + image_data = stp_zalloc(image_px_height * sizeof(unsigned short *)); + pv->image_rows = 0; + if (!image_data) + return NULL; /* ? out of memory ? */ + + for (i = 0; i < image_px_height; i++) + { + if (stp_color_get_row(v, image, i, &zero_mask)) + { + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub_read_image: " + "stp_color_get_row(..., %d, ...) == 0\n", i); + dyesub_free_image(pv, image); + return NULL; + } + image_data[i] = stp_malloc(row_size); + pv->image_rows = i+1; + if (!image_data[i]) + { + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub_read_image: " + "(image_data[%d] = stp_malloc()) == NULL\n", i); + dyesub_free_image(pv, image); + return NULL; + } + memcpy(image_data[i], stp_channel_get_output(v), row_size); + } + return image_data; +} + +static void +dyesub_render_pixel_u8(unsigned short *src, char *dest, + dyesub_print_vars_t *pv, + int plane) +{ + /* Scale down to output bit depth */ +#if 0 + *dest = src[plane] >> 8; // XXX does this make more sense than division? +#else + *dest = src[plane] / 257; +#endif +} + +static void +dyesub_render_pixel_packed_u8(unsigned short *src, char *dest, + dyesub_print_vars_t *pv) +{ + int i; + + /* copy out_channel (image) to equiv ink_channel (printer) */ + for (i = 0; i < pv->ink_channels; i++) + { + dyesub_render_pixel_u8(src, dest + i, pv, pv->ink_order[i]-1); + } +} + +static void +dyesub_render_row_packed_u8(stp_vars_t *v, + dyesub_print_vars_t *pv, + const dyesub_cap_t *caps, + int in_row, + char *dest, + int bytes_per_pixel) +{ + int w; + unsigned short *src; + + for (w = 0; w < pv->outw_px; w++) + { + int row = in_row; + int col = dyesub_interpolate(w, pv->outw_px, pv->imgw_px); + if (pv->plane_lefttoright) + col = pv->imgw_px - col - 1; + if (pv->print_mode == DYESUB_LANDSCAPE) + { /* "rotate" image */ + dyesub_swap_ints(&col, &row); + row = (pv->imgw_px - 1) - row; + } + src = &(pv->image_data[row][col * pv->out_channels]); + + dyesub_render_pixel_packed_u8(src, dest + w*bytes_per_pixel, pv); + } +} + +static void +dyesub_render_row_interlaced_u8(stp_vars_t *v, + dyesub_print_vars_t *pv, + const dyesub_cap_t *caps, + int in_row, + char *dest, + int plane) +{ + int w; + unsigned short *src; + + for (w = 0; w < pv->outw_px; w++) + { + int row = in_row; + int col = dyesub_interpolate(w, pv->outw_px, pv->imgw_px); + if (pv->plane_lefttoright) + col = pv->imgw_px - col - 1; + if (pv->print_mode == DYESUB_LANDSCAPE) + { /* "rotate" image */ + dyesub_swap_ints(&col, &row); + row = (pv->imgw_px - 1) - row; + } + src = &(pv->image_data[row][col * pv->out_channels]); + + dyesub_render_pixel_u8(src, dest + w, pv, plane); + } +} + +static int +dyesub_print_plane(stp_vars_t *v, + dyesub_print_vars_t *pv, + dyesub_privdata_t *pd, + const dyesub_cap_t *caps, + int plane) +{ + int h; + int bpp = ((pv->plane_interlacing || pv->row_interlacing) ? 1 : pv->ink_channels); + size_t rowlen = pv->prnw_px * bpp; + char *destrow = stp_malloc(rowlen); /* Allocate a buffer for the rendered rows */ + if (!destrow) + return 0; /* ? out of memory ? */ + + /* Pre-Fill in the blank bits of the row. */ + if (dyesub_feature(caps, DYESUB_FEATURE_FULL_WIDTH)) + { + /* empty part left of image area */ + if (pv->outl_px > 0) + { + memset(destrow, pv->empty_byte[plane], bpp * pv->outl_px); + } + /* empty part right of image area */ + if (pv->outr_px < pv->prnw_px) + { + memset(destrow + rowlen - bpp * (pv->prnw_px - pv->outr_px), + pv->empty_byte[plane], + bpp * (pv->prnw_px - pv->outr_px)); + } + } + + for (h = 0; h <= pv->prnb_px - pv->prnt_px; h++) + { + int p = pv->row_interlacing ? 0 : plane; + + do { + + if (h % caps->block_size == 0) + { /* block init */ + pd->block_min_h = h + pv->prnt_px; + pd->block_min_w = pv->prnl_px; + pd->block_max_h = MIN(h + pv->prnt_px + caps->block_size - 1, + pv->prnb_px); + pd->block_max_w = pv->prnr_px; + + dyesub_exec(v, caps->block_init_func, "caps->block_init"); + } + + /* Generate a single row */ + if (h + pv->prnt_px < pv->outt_px || h + pv->prnt_px >= pv->outb_px) + { /* empty part above or below image area */ + memset(destrow, pv->empty_byte[plane], rowlen); + /* FIXME: This is inefficient; it won't change once generated.. */ + } + else + { + int srcrow = dyesub_interpolate(h + pv->prnt_px - pv->outt_px, + pv->outh_px, pv->imgh_px); + + stp_dprintf(STP_DBG_DYESUB, v, + "dyesub_print_plane: h = %d, row = %d\n", h, srcrow); + + if (pv->plane_interlacing || pv->row_interlacing) + { + dyesub_render_row_interlaced_u8(v, pv, caps, srcrow, + destrow + bpp * pv->outl_px, p); + } + else + dyesub_render_row_packed_u8(v, pv, caps, srcrow, + destrow + bpp * pv->outl_px, bpp); + } + /* And send it out */ + stp_zfwrite(destrow, rowlen, 1, v); + + if (h + pv->prnt_px == pd->block_max_h) + { /* block end */ + dyesub_exec(v, caps->block_end_func, "caps->block_end"); + } + + } while (pv->row_interlacing && ++p < pv->ink_channels); + } + + stp_free(destrow); + return 1; +} + +/* + * dyesub_print() + */ +static int +dyesub_do_print(stp_vars_t *v, stp_image_t *image, int print_op) +{ + int i; + dyesub_print_vars_t pv; + int status = 1; + + const int model = stp_get_model_id(v); + const char *ink_type; + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, model); + int max_print_px_width = 0; + int max_print_px_height = 0; + int w_dpi, h_dpi; + stp_resolution_t wr_dpi, hr_dpi; /* Resolution */ + + /* output in 1/72" */ + stp_dimension_t out_pt_width = stp_get_width(v); + stp_dimension_t out_pt_height = stp_get_height(v); + stp_dimension_t out_pt_left = stp_get_left(v); + stp_dimension_t out_pt_top = stp_get_top(v); + + /* page in 1/72" */ + stp_dimension_t page_pt_width = stp_get_page_width(v); + stp_dimension_t page_pt_height = stp_get_page_height(v); + stp_dimension_t page_pt_left = 0; + stp_dimension_t page_pt_right = 0; + stp_dimension_t page_pt_top = 0; + stp_dimension_t page_pt_bottom = 0; + int page_mode; + + int pl; + + dyesub_privdata_t *pd; + + if (!stp_verify(v)) + { + stp_eprintf(v, _("Print options not verified; cannot print.\n")); + return 0; + } + + /* Clean up private state */ + (void) memset(&pv, 0, sizeof(pv)); + + /* Allocate privdata structure */ + pd = stp_zalloc(sizeof(dyesub_privdata_t)); + stp_allocate_component_data(v, "Driver", NULL, NULL, pd); + + /* Parse any per-printer parameters *before* the generic ones */ + dyesub_exec_check(v, caps->parse_parameters, "caps->parse_parameters"); + + stp_image_init(image); + pv.imgw_px = stp_image_width(image); + pv.imgh_px = stp_image_height(image); + + stp_describe_resolution(v, &wr_dpi, &hr_dpi); + w_dpi = (int) wr_dpi; + h_dpi = (int) hr_dpi; + dyesub_printsize(v, &max_print_px_width, &max_print_px_height); + + /* Duplex processing -- Rotate even pages for DuplexNoTumble */ + pd->duplex_mode = stp_get_string_parameter(v, "Duplex"); + pd->page_number = stp_get_int_parameter(v, "PageNumber"); + if((pd->page_number & 1) && pd->duplex_mode && !strcmp(pd->duplex_mode,"DuplexNoTumble")) + image = stpi_buffer_image(image,BUFFER_FLAG_FLIP_X | BUFFER_FLAG_FLIP_Y); + + /* Check to see if we're to generate more than one copy */ + if (stp_check_boolean_parameter(v, "NativeCopies", STP_PARAMETER_ACTIVE) && + stp_get_boolean_parameter(v, "NativeCopies") && + stp_check_int_parameter(v, "NumCopies", STP_PARAMETER_ACTIVE)) + pd->copies = stp_get_int_parameter(v, "NumCopies"); + else + pd->copies = 1; + /* FIXME: What about Collation? Any special handling here? */ + + pd->pagesize = stp_get_string_parameter(v, "PageSize"); + if (caps->overcoat) + pd->overcoat = dyesub_get_overcoat_pattern(v); + if (caps->media) + pd->media = dyesub_get_mediatype(v); + + dyesub_imageable_area_internal(v, + (dyesub_feature(caps, DYESUB_FEATURE_WHITE_BORDER) ? 1 : 0), + &page_pt_left, &page_pt_right, &page_pt_bottom, &page_pt_top, + &page_mode); + + /* Swap DPI so these computations will work out properly */ + if (page_mode == DYESUB_LANDSCAPE) + dyesub_swap_ints(&w_dpi, &h_dpi); + + pv.prnw_px = MIN(max_print_px_width, + PX(page_pt_right - page_pt_left, w_dpi)); + pv.prnh_px = MIN(max_print_px_height, + PX(page_pt_bottom - page_pt_top, h_dpi)); + pv.outw_px = PX(out_pt_width, w_dpi); + pv.outh_px = PX(out_pt_height, h_dpi); + + /* if image size is close enough to output size send out original size */ + if (abs(pv.outw_px - pv.imgw_px) < SIZE_THRESHOLD) + pv.outw_px = pv.imgw_px; + if (abs(pv.outh_px - pv.imgh_px) < SIZE_THRESHOLD) + pv.outh_px = pv.imgh_px; + + pv.outw_px = MIN(pv.outw_px, pv.prnw_px); + pv.outh_px = MIN(pv.outh_px, pv.prnh_px); + pv.outl_px = MIN(PX(out_pt_left - page_pt_left, w_dpi), + pv.prnw_px - pv.outw_px); + pv.outt_px = MIN(PX(out_pt_top - page_pt_top, h_dpi), + pv.prnh_px - pv.outh_px); + pv.outr_px = pv.outl_px + pv.outw_px; + pv.outb_px = pv.outt_px + pv.outh_px; + + /* Swap back so that everything that follows will work. */ + if (page_mode == DYESUB_LANDSCAPE) + dyesub_swap_ints(&w_dpi, &h_dpi); + + stp_dprintf(STP_DBG_DYESUB, v, + "paper (pt) %f x %f\n" + "image (px) %d x %d\n" + "image (pt) %f x %f\n" + "* out (pt) %f x %f\n" + "* out (px) %d x %d\n" + "* left x top (pt) %f x %f\n" + "* left x top (px) %d x %d\n" + "border (pt) (%f - %f) = %f x (%f - %f) = %f\n" + "printable pixels (px) %d x %d\n" + "res (dpi) %d x %d\n", + page_pt_width, page_pt_height, + pv.imgw_px, pv.imgh_px, + PT(pv.imgw_px, w_dpi), PT(pv.imgh_px, h_dpi), + out_pt_width, out_pt_height, + pv.outw_px, pv.outh_px, + out_pt_left, out_pt_top, + pv.outl_px, pv.outt_px, + page_pt_right, page_pt_left, page_pt_right - page_pt_left, + page_pt_bottom, page_pt_top, page_pt_bottom - page_pt_top, + pv.prnw_px, pv.prnh_px, + w_dpi, h_dpi + ); + + ink_type = dyesub_describe_output_internal(v, &pv); + stp_set_string_parameter(v, "STPIOutputType", ink_type); + stp_channel_reset(v); + for (i = 0; i < pv.ink_channels; i++) + stp_channel_add(v, i, 0, 1.0); + + pv.out_channels = stp_color_init(v, image, 256); + stp_set_float_parameter(v, "AppGammaScale", 1.0); + + /* If there's a mismatch in channels, that is ALWAYS a problem */ + if (pv.out_channels != pv.ink_channels) + { + stp_dprintf(STP_DBG_DYESUB, v, + "Input and output channel count mismatch! (%d vs %d)\n", pv.out_channels, pv.ink_channels); + stp_image_conclude(image); + stp_free(pd); + return 2; + } + + pv.image_data = dyesub_read_image(v, &pv, image); + if (ink_type) + { + if (strcmp(ink_type, "RGB") == 0 || + strcmp(ink_type, "BGR") == 0 || + strcmp(ink_type, "Whitescale") == 0) + { + pv.empty_byte[0] = 0xff; + pv.empty_byte[1] = 0xff; + pv.empty_byte[2] = 0xff; + } + else + { + pv.empty_byte[0] = 0x0; + pv.empty_byte[1] = 0x0; + pv.empty_byte[2] = 0x0; + } + } + else + { + pv.empty_byte[0] = 0x0; + pv.empty_byte[1] = 0x0; + pv.empty_byte[2] = 0x0; + } + + pv.plane_interlacing = dyesub_feature(caps, DYESUB_FEATURE_PLANE_INTERLACE); + pv.row_interlacing = dyesub_feature(caps, DYESUB_FEATURE_ROW_INTERLACE); + pv.plane_lefttoright = dyesub_feature(caps, DYESUB_FEATURE_PLANE_LEFTTORIGHT); + pv.print_mode = page_mode; + if (!pv.image_data) + { + stp_image_conclude(image); + stp_free(pd); + return 2; + } + + if (dyesub_feature(caps, DYESUB_FEATURE_FULL_HEIGHT)) + { + pv.prnt_px = 0; + pv.prnb_px = pv.prnh_px - 1; + } + else if (dyesub_feature(caps, DYESUB_FEATURE_BLOCK_ALIGN)) + { + pv.prnt_px = pv.outt_px - (pv.outt_px % caps->block_size); + /* floor to multiple of block_size */ + pv.prnb_px = (pv.outb_px - 1) + (caps->block_size - 1) + - ((pv.outb_px - 1) % caps->block_size); + /* ceil to multiple of block_size */ + } + else + { + pv.prnt_px = pv.outt_px; + pv.prnb_px = pv.outb_px - 1; + } + + if (dyesub_feature(caps, DYESUB_FEATURE_FULL_WIDTH)) + { + pv.prnl_px = 0; + pv.prnr_px = pv.prnw_px - 1; + } + else + { + pv.prnl_px = pv.outl_px; + pv.prnr_px = pv.outr_px; + } + + if (pv.print_mode == DYESUB_LANDSCAPE) + { + dyesub_swap_ints(&pv.outh_px, &pv.outw_px); + dyesub_swap_ints(&pv.outt_px, &pv.outl_px); + dyesub_swap_ints(&pv.outb_px, &pv.outr_px); + + dyesub_swap_ints(&pv.prnh_px, &pv.prnw_px); + dyesub_swap_ints(&pv.prnt_px, &pv.prnl_px); + dyesub_swap_ints(&pv.prnb_px, &pv.prnr_px); + + dyesub_swap_ints(&pv.imgh_px, &pv.imgw_px); + } + + /* Adjust margins if the driver asks, to fine-tune horizontal position. */ + pv.outl_px += pd->horiz_offset; + pv.outr_px += pd->horiz_offset; + /* Make sure we're still legal */ + if (pv.outl_px < 0) + pv.outl_px = 0; + if (pv.outr_px > pv.prnw_px) + pv.outr_px = pv.prnw_px; + + /* By this point, we're finally DONE mangling the pv structure, + and can start calling into the bulk of the driver code. */ + + /* assign private data *after* swaping image dimensions */ + pd->w_dpi = w_dpi; + pd->h_dpi = h_dpi; + pd->w_size = pv.prnw_px; + pd->h_size = pv.prnh_px; + pd->print_mode = pv.print_mode; + + /* FIXME: Provide a way of disabling/altering these curves */ + /* XXX reuse 'UseLUT' from mitsu70x? or 'SimpleGamma' ? */ + dyesub_exec(v, caps->adjust_curves, "caps->adjust_curves"); + + /* Send out job init if we're in page mode */ + if (print_op & OP_JOB_START) + dyesub_exec(v, caps->job_start_func, "caps->job_start"); + + /* printer init */ + dyesub_exec(v, caps->printer_init_func, "caps->printer_init"); + + for (pl = 0; pl < (pv.plane_interlacing ? pv.ink_channels : 1); pl++) + { + pd->plane = pv.ink_order[pl]; + stp_dprintf(STP_DBG_DYESUB, v, "dyesub: plane %d\n", pd->plane); + + /* plane init */ + dyesub_exec(v, caps->plane_init_func, "caps->plane_init"); + + dyesub_print_plane(v, &pv, pd, caps, (int) pv.ink_order[pl] - 1); + + /* plane end */ + dyesub_exec(v, caps->plane_end_func, "caps->plane_end"); + } + + /* printer end */ + dyesub_exec(v, caps->printer_end_func, "caps->printer_end"); + + /* Job end, if we're in page mode */ + if (print_op & OP_JOB_END) + dyesub_exec(v, caps->job_end_func, "caps->job_end"); + + if (pv.image_data) { + dyesub_free_image(&pv, image); + } + + stp_image_conclude(image); + stp_free(pd); + + return status; +} + +static int +dyesub_print(const stp_vars_t *v, stp_image_t *image) +{ + int status; + int op = OP_JOB_PRINT; + + stp_vars_t *nv = stp_vars_create_copy(v); + + if (!stp_get_string_parameter(v, "JobMode") || + strcmp(stp_get_string_parameter(v, "JobMode"), "Page") == 0) + op = OP_JOB_START | OP_JOB_PRINT | OP_JOB_END; + + status = dyesub_do_print(nv, image, op); + stp_vars_destroy(nv); + return status; +} + +static int +dyesub_job_start(const stp_vars_t *v, stp_image_t *image) +{ + const dyesub_cap_t *caps; + stp_vars_t *nv = stp_vars_create_copy(v); + + caps = dyesub_get_model_capabilities(v, stp_get_model_id(nv)); + + if (caps->job_start_func) + caps->job_start_func(nv); + stp_vars_destroy(nv); + + return 1; +} + +static int +dyesub_job_end(const stp_vars_t *v, stp_image_t *image) +{ + const dyesub_cap_t *caps; + stp_vars_t *nv = stp_vars_create_copy(v); + + caps = dyesub_get_model_capabilities(v, stp_get_model_id(nv)); + + if (caps->job_end_func) + caps->job_end_func(nv); + stp_vars_destroy(nv); + + return 1; +} + +static int dyesub_verify_printer_params(stp_vars_t *v) +{ + const int model = stp_get_model_id(v); + const dyesub_cap_t *caps = dyesub_get_model_capabilities(v, model); + int result; + result = stp_verify_printer_params(v); + if (result != 1) + return result; + + /* Sanity-check printer-specific parameters if a function exists */ + result = dyesub_exec_check(v, caps->parse_parameters, "caps->parse_parameters"); + return result; +} + +static const stp_printfuncs_t print_dyesub_printfuncs = +{ + dyesub_list_parameters, + dyesub_parameters, + dyesub_media_size, + dyesub_imageable_area, + dyesub_maximum_imageable_area, + dyesub_limit, + dyesub_print, + dyesub_describe_resolution, + dyesub_describe_output, + dyesub_verify_printer_params, + dyesub_job_start, + dyesub_job_end, + NULL, + dyesub_describe_papersize +}; + +static stp_family_t print_dyesub_module_data = + { + &print_dyesub_printfuncs, + NULL + }; + +static int +print_dyesub_module_init(void) +{ + return stpi_family_register(print_dyesub_module_data.printer_list); +} + + +static int +print_dyesub_module_exit(void) +{ + return stpi_family_unregister(print_dyesub_module_data.printer_list); +} + + +/* Module header */ +#define stp_module_version print_dyesub_LTX_stp_module_version +#define stp_module_data print_dyesub_LTX_stp_module_data + +stp_module_version_t stp_module_version = {0, 0}; + +stp_module_t stp_module_data = + { + "dyesub", + VERSION, + "DyeSub family driver", + STP_MODULE_CLASS_FAMILY, + NULL, + print_dyesub_module_init, + print_dyesub_module_exit, + (void *) &print_dyesub_module_data + }; |