Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/print-pcl.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-pcl.c,v 1.132 2004/05/07 19:20:33 rleigh Exp $"
00003  *
00004  *   Print plug-in HP PCL driver for the GIMP.
00005  *
00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com),
00007  *      Robert Krawitz (rlk@alum.mit.edu) and
00008  *      Dave Hill (dave@minnie.demon.co.uk)
00009  *
00010  *   This program is free software; you can redistribute it and/or modify it
00011  *   under the terms of the GNU General Public License as published by the Free
00012  *   Software Foundation; either version 2 of the License, or (at your option)
00013  *   any later version.
00014  *
00015  *   This program is distributed in the hope that it will be useful, but
00016  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00017  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00018  *   for more details.
00019  *
00020  *   You should have received a copy of the GNU General Public License
00021  *   along with this program; if not, write to the Free Software
00022  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 
00025 /*
00026  * This file must include only standard C header files.  The core code must
00027  * compile on generic platforms that don't support glib, gimp, gtk, etc.
00028  */
00029 
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033 #include <gimp-print/gimp-print.h>
00034 #include <gimp-print/gimp-print-intl-internal.h>
00035 #include "gimp-print-internal.h"
00036 #include <stdio.h>
00037 #include <string.h>
00038 
00039 /* #define DEBUG */
00040 /* #define PCL_DEBUG_DISABLE_COMPRESSION */
00041 /* #define PCL_DEBUG_DISABLE_BLANKLINE_REMOVAL */
00042 
00043 /*
00044  * Local functions...
00045  */
00046 static void     pcl_mode0(stp_vars_t *, unsigned char *, int, int);
00047 static void     pcl_mode2(stp_vars_t *, unsigned char *, int, int);
00048 #define MAX(a, b) ((a) > (b) ? (a) : (b))
00049 
00050 typedef struct
00051 {
00052   int do_blank;
00053   int blank_lines;
00054   unsigned char *comp_buf;
00055   void (*writefunc)(stp_vars_t *, unsigned char *, int, int);   /* PCL output function */
00056   int do_cret;
00057   int do_cretb;
00058   int do_6color;
00059   int height;
00060 } pcl_privdata_t;
00061 
00062 /*
00063  * Generic define for a name/value set
00064  */
00065 
00066 typedef struct
00067 {
00068   const char    *pcl_name;
00069   const char    *pcl_text;
00070   int           pcl_code;
00071   int           p0;
00072   int           p1;
00073 } pcl_t;
00074 
00075 static const stp_dotsize_t single_dotsize[] =
00076 {
00077   { 0x1, 1.0 }
00078 };
00079 
00080 static const stp_shade_t photo_dither_shades[] =
00081 {
00082   { 1.0000, 1, single_dotsize },
00083   { 0.3333, 1, single_dotsize },
00084 };
00085 
00086 /*
00087  * Media size to PCL media size code table
00088  *
00089  * Note, you can force the list of papersizes given in the GUI to be only those
00090  * supported by defining PCL_NO_CUSTOM_PAPERSIZES
00091  */
00092 
00093 /* #define PCL_NO_CUSTOM_PAPERSIZES */
00094 
00095 #define PCL_PAPERSIZE_EXECUTIVE         1
00096 #define PCL_PAPERSIZE_LETTER            2
00097 #define PCL_PAPERSIZE_LEGAL             3
00098 #define PCL_PAPERSIZE_TABLOID           6       /* "Ledger" */
00099 #define PCL_PAPERSIZE_STATEMENT         15      /* Called "Manual" in print-util */
00100 #define PCL_PAPERSIZE_SUPER_B           16      /* Called "13x19" in print-util */
00101 #define PCL_PAPERSIZE_A5                25
00102 #define PCL_PAPERSIZE_A4                26
00103 #define PCL_PAPERSIZE_A3                27
00104 #define PCL_PAPERSIZE_JIS_B5            45
00105 #define PCL_PAPERSIZE_JIS_B4            46
00106 #define PCL_PAPERSIZE_HAGAKI_CARD       71
00107 #define PCL_PAPERSIZE_OUFUKU_CARD       72
00108 #define PCL_PAPERSIZE_A6_CARD           73
00109 #define PCL_PAPERSIZE_4x6               74
00110 #define PCL_PAPERSIZE_5x8               75
00111 #define PCL_PAPERSIZE_3x5               78
00112 #define PCL_PAPERSIZE_MONARCH_ENV       80
00113 #define PCL_PAPERSIZE_COMMERCIAL10_ENV  81
00114 #define PCL_PAPERSIZE_DL_ENV            90
00115 #define PCL_PAPERSIZE_C5_ENV            91
00116 #define PCL_PAPERSIZE_C6_ENV            92
00117 #define PCL_PAPERSIZE_CUSTOM            101     /* Custom size */
00118 #define PCL_PAPERSIZE_INVITATION_ENV    109
00119 #define PCL_PAPERSIZE_JAPANESE_3_ENV    110
00120 #define PCL_PAPERSIZE_JAPANESE_4_ENV    111
00121 #define PCL_PAPERSIZE_KAKU_ENV          113
00122 #define PCL_PAPERSIZE_HP_CARD           114     /* HP Greeting card!?? */
00123 
00124 /*
00125  * This data comes from the HP documentation "Deskjet 1220C and 1120C
00126  * PCL reference guide 2.0, Nov 1999". NOTE: The first name *must* match
00127  * those in print-util.c for the lookups to work properly!
00128  * The long names are not used so they have been removed, the ones in
00129  * print-util.c are used in the interface.
00130  */
00131 
00132 static const pcl_t pcl_media_sizes[] =
00133 {
00134     { "Executive", "notused", PCL_PAPERSIZE_EXECUTIVE},                 /* US Exec (7.25 x 10.5 in) */
00135     { "Letter", "notused", PCL_PAPERSIZE_LETTER},                       /* US Letter (8.5 x 11 in) */
00136     { "Legal", "notused", PCL_PAPERSIZE_LEGAL},                         /* US Legal (8.5 x 14 in) */
00137     { "Tabloid", "notused", PCL_PAPERSIZE_TABLOID},                     /* US Tabloid (11 x 17 in) */
00138     { "Statement", "notused", PCL_PAPERSIZE_STATEMENT},                 /* US Manual/Statement (5.5 x 8.5 in) */
00139     { "SuperB", "notused", PCL_PAPERSIZE_SUPER_B},                      /* US 13x19/Super B (13 x 19 in) */
00140     { "A5", "notused", PCL_PAPERSIZE_A5},                               /* ISO/JIS A5 (148 x 210 mm) */
00141     { "A4", "notused", PCL_PAPERSIZE_A4},                               /* ISO/JIS A4 (210 x 297 mm) */
00142     { "A3", "notused", PCL_PAPERSIZE_A3},                               /* ISO/JIS A3 (297 x 420 mm) */
00143     { "B5", "notused", PCL_PAPERSIZE_JIS_B5},                           /* JIS B5 (182 x 257 mm). */
00144     { "B4", "notused", PCL_PAPERSIZE_JIS_B4},                           /* JIS B4 (257 x 364 mm). */
00145     { "w283h420", "notused", PCL_PAPERSIZE_HAGAKI_CARD},                /* Japanese Hagaki Card (100 x 148 mm) */
00146     { "w420h567", "notused", PCL_PAPERSIZE_OUFUKU_CARD},                /* Japanese Oufuku Card (148 x 200 mm) */
00147     { "A6", "notused", PCL_PAPERSIZE_A6_CARD},                          /* ISO/JIS A6 card */
00148     { "w288h432", "notused", PCL_PAPERSIZE_4x6},                        /* US Index card (4 x 6 in) */
00149     { "w360h576", "notused", PCL_PAPERSIZE_5x8},                        /* US Index card (5 x 8 in) */
00150     { "w216h360", "notused", PCL_PAPERSIZE_3x5},                        /* US Index card (3 x 5 in) */
00151     { "Monarch", "notused", PCL_PAPERSIZE_MONARCH_ENV},                 /* Monarch Envelope (3 7/8 x 7 1/2 in) */
00152     { "COM10", "notused", PCL_PAPERSIZE_COMMERCIAL10_ENV},              /* US Commercial 10 Envelope (4.125 x 9.5 in) Portrait */
00153     { "DL", "notused", PCL_PAPERSIZE_DL_ENV},                           /* DL envelope (110 x 220 mm) Portrait */
00154     { "C5", "notused", PCL_PAPERSIZE_C5_ENV},                           /* C5 envelope (162 x 229 mm) */
00155     { "C6", "notused", PCL_PAPERSIZE_C6_ENV},                           /* C6 envelope (114 x 162 mm) */
00156     { "w315h414", "notused", PCL_PAPERSIZE_INVITATION_ENV},             /* US A2 Invitation envelope (4 3/8 x 5 3/4 in) */
00157     { "w340h666", "notused", PCL_PAPERSIZE_JAPANESE_3_ENV},             /* Japanese Long Envelope #3 (120 x 235 mm) */
00158     { "w255h581", "notused", PCL_PAPERSIZE_JAPANESE_4_ENV},             /* Japanese Long Envelope #4 (90 x 205 mm) */
00159     { "w680h941", "notused", PCL_PAPERSIZE_KAKU_ENV},                   /* Japanese Kaku Envelope (240 x 332.1 mm) */
00160 /**** MRS: this size not supported by print-util funcs! ****/
00161     { "w612h792", "notused", PCL_PAPERSIZE_HP_CARD},                    /* Hp greeting card */
00162 };
00163 #define NUM_PRINTER_PAPER_SIZES (sizeof(pcl_media_sizes) / sizeof(pcl_t))
00164 
00165 /*
00166  * Media type to code table
00167  */
00168 
00169 #define PCL_PAPERTYPE_PLAIN     0
00170 #define PCL_PAPERTYPE_BOND      1
00171 #define PCL_PAPERTYPE_PREMIUM   2
00172 #define PCL_PAPERTYPE_GLOSSY    3       /* or photo */
00173 #define PCL_PAPERTYPE_TRANS     4
00174 #define PCL_PAPERTYPE_QPHOTO    5       /* Quick dry photo (2000 only) */
00175 #define PCL_PAPERTYPE_QTRANS    6       /* Quick dry transparency (2000 only) */
00176 
00177 static const pcl_t pcl_media_types[] =
00178 {
00179     { "Plain", N_ ("Plain"), PCL_PAPERTYPE_PLAIN},
00180     { "Bond", N_ ("Bond"), PCL_PAPERTYPE_BOND},
00181     { "Premium", N_ ("Premium"), PCL_PAPERTYPE_PREMIUM},
00182     { "Glossy", N_ ("Glossy Photo"), PCL_PAPERTYPE_GLOSSY},
00183     { "Transparency", N_ ("Transparency"), PCL_PAPERTYPE_TRANS},
00184     { "GlossyQD", N_ ("Quick-dry Photo"), PCL_PAPERTYPE_QPHOTO},
00185     { "TransparencyQD", N_ ("Quick-dry Transparency"), PCL_PAPERTYPE_QTRANS},
00186 };
00187 #define NUM_PRINTER_PAPER_TYPES (sizeof(pcl_media_types) / sizeof(pcl_t))
00188 
00189 /*
00190  * Media feed to code table. There are different names for the same code,
00191  * so we encode them by adding "lumps" of "PAPERSOURCE_MOD".
00192  * This is removed later to get back to the main codes.
00193  */
00194 
00195 #define PAPERSOURCE_MOD                 16
00196 
00197 #define PCL_PAPERSOURCE_STANDARD        0       /* Don't output code */
00198 #define PCL_PAPERSOURCE_MANUAL          2
00199 #define PCL_PAPERSOURCE_ENVELOPE        3       /* Not used */
00200 
00201 /* LaserJet types */
00202 #define PCL_PAPERSOURCE_LJ_TRAY2        1
00203 #define PCL_PAPERSOURCE_LJ_TRAY3        4
00204 #define PCL_PAPERSOURCE_LJ_TRAY4        5
00205 #define PCL_PAPERSOURCE_LJ_TRAY1        8
00206 
00207 /* Deskjet 340 types */
00208 #define PCL_PAPERSOURCE_340_PCSF        1 + PAPERSOURCE_MOD
00209                                                 /* Portable sheet feeder for 340 */
00210 #define PCL_PAPERSOURCE_340_DCSF        4 + PAPERSOURCE_MOD
00211                                                 /* Desktop sheet feeder for 340 */
00212 
00213 /* Other Deskjet types */
00214 #define PCL_PAPERSOURCE_DJ_TRAY         1 + PAPERSOURCE_MOD + PAPERSOURCE_MOD
00215 #define PCL_PAPERSOURCE_DJ_TRAY2        4 + PAPERSOURCE_MOD + PAPERSOURCE_MOD
00216                                                 /* Tray 2 for 2500 */
00217 #define PCL_PAPERSOURCE_DJ_OPTIONAL     5 + PAPERSOURCE_MOD + PAPERSOURCE_MOD
00218                                                 /* Optional source for 2500 */
00219 #define PCL_PAPERSOURCE_DJ_AUTO         7 + PAPERSOURCE_MOD + PAPERSOURCE_MOD
00220                                                 /* Autoselect for 2500 */
00221 
00222 static const pcl_t pcl_media_sources[] =
00223 {
00224     { "Standard", N_ ("Standard"), PCL_PAPERSOURCE_STANDARD},
00225     { "Manual", N_ ("Manual"), PCL_PAPERSOURCE_MANUAL},
00226 /*  {"Envelope", PCL_PAPERSOURCE_ENVELOPE}, */
00227     { "MultiPurpose", N_ ("Tray 1"), PCL_PAPERSOURCE_LJ_TRAY1},
00228     { "Upper", N_ ("Tray 2"), PCL_PAPERSOURCE_LJ_TRAY2},
00229     { "Lower", N_ ("Tray 3"), PCL_PAPERSOURCE_LJ_TRAY3},
00230     { "LargeCapacity", N_ ("Tray 4"), PCL_PAPERSOURCE_LJ_TRAY4},
00231     { "Portable", N_ ("Portable Sheet Feeder"), PCL_PAPERSOURCE_340_PCSF},
00232     { "Desktop", N_ ("Desktop Sheet Feeder"), PCL_PAPERSOURCE_340_DCSF},
00233     { "Tray", N_ ("Tray"), PCL_PAPERSOURCE_DJ_TRAY},
00234     { "Tray2", N_ ("Tray 2"), PCL_PAPERSOURCE_DJ_TRAY2},
00235     { "Optional", N_ ("Optional Source"), PCL_PAPERSOURCE_DJ_OPTIONAL},
00236     { "Auto", N_ ("Autoselect"), PCL_PAPERSOURCE_DJ_AUTO},
00237 };
00238 #define NUM_PRINTER_PAPER_SOURCES       (sizeof(pcl_media_sources) / sizeof(pcl_t))
00239 
00240 #define PCL_RES_150_150         1
00241 #define PCL_RES_300_300         2
00242 #define PCL_RES_600_300         4       /* DJ 600 series */
00243 #define PCL_RES_600_600_MONO    8       /* DJ 600/800/1100/2000 b/w only */
00244 #define PCL_RES_600_600         16      /* DJ 9xx/1220C/PhotoSmart */
00245 #define PCL_RES_1200_600        32      /* DJ 9xx/1220C/PhotoSmart */
00246 #define PCL_RES_2400_600        64      /* DJ 9xx/1220C/PhotoSmart */
00247 
00248 static const pcl_t pcl_resolutions[] =
00249 {
00250     { "150dpi", N_("150x150 DPI"), PCL_RES_150_150, 150, 150},
00251     { "300dpi", N_("300x300 DPI"), PCL_RES_300_300, 300, 300},
00252     { "600x300dpi", N_("600x300 DPI"), PCL_RES_600_300, 600, 300},
00253     { "600mono", N_("600x600 DPI monochrome"), PCL_RES_600_600_MONO, 600, 600},
00254     { "600dpi", N_("600x600 DPI"), PCL_RES_600_600, 600, 600},
00255     { "1200x600dpi", N_("1200x600 DPI"), PCL_RES_1200_600, 1200, 600},
00256     { "2400x600dpi", N_("2400x600 DPI"), PCL_RES_2400_600, 2400, 600},
00257 };
00258 #define NUM_RESOLUTIONS         (sizeof(pcl_resolutions) / sizeof (pcl_t))
00259 
00260 static void
00261 pcl_describe_resolution(const stp_vars_t *v, int *x, int *y)
00262 {
00263   int i;
00264   const char *resolution = stp_get_string_parameter(v, "Resolution");
00265   if (resolution)
00266     {
00267       for (i = 0; i < NUM_RESOLUTIONS; i++)
00268         {
00269           if (!strcmp(resolution, pcl_resolutions[i].pcl_name))
00270             {
00271               *x = pcl_resolutions[i].p0;
00272               *y = pcl_resolutions[i].p1;
00273               return;
00274             }
00275         }
00276     }
00277   *x = -1;
00278   *y = -1;
00279 }
00280 
00281 typedef struct {
00282   int top_margin;
00283   int bottom_margin;
00284   int left_margin;
00285   int right_margin;
00286 } margins_t;
00287 
00288 /*
00289  * Printer capability data
00290  */
00291 
00292 typedef struct {
00293   int model;
00294   int custom_max_width;
00295   int custom_max_height;
00296   int custom_min_width;
00297   int custom_min_height;
00298   int resolutions;
00299   margins_t normal_margins;
00300   margins_t a4_margins;
00301   int color_type;               /* 2 print head or one, 2 level or 4 */
00302   int stp_printer_type;         /* Deskjet/Laserjet and quirks */
00303 /* The paper size, paper type and paper source codes cannot be combined */
00304   const short *paper_sizes;     /* Paper sizes */
00305   const short *paper_types;     /* Paper types */
00306   const short *paper_sources;   /* Paper sources */
00307   } pcl_cap_t;
00308 
00309 #define PCL_COLOR_NONE          0
00310 #define PCL_COLOR_CMY           1       /* One print head */
00311 #define PCL_COLOR_CMYK          2       /* Two print heads */
00312 #define PCL_COLOR_CMYK4         4       /* CRet printing */
00313 #define PCL_COLOR_CMYKcm        8       /* CMY + Photo Cart */
00314 #define PCL_COLOR_CMYK4b        16      /* CRet for HP840c */
00315 
00316 #define PCL_PRINTER_LJ          1
00317 #define PCL_PRINTER_DJ          2
00318 #define PCL_PRINTER_NEW_ERG     4       /* use "\033*rC" to end raster graphics,
00319                                            instead of "\033*rB" */
00320 #define PCL_PRINTER_TIFF        8       /* Use TIFF compression */
00321 #define PCL_PRINTER_MEDIATYPE   16      /* Use media type & print quality */
00322 #define PCL_PRINTER_CUSTOM_SIZE 32      /* Custom sizes supported */
00323 #define PCL_PRINTER_BLANKLINE   64      /* Blank line removal supported */
00324 
00325 /*
00326  * FIXME - the 520 shouldn't be lumped in with the 500 as it supports
00327  * more paper sizes.
00328  *
00329  * The following models use depletion, raster quality and shingling:-
00330  * 500, 500c, 510, 520, 550c, 560c.
00331  * The rest use Media Type and Print Quality.
00332  *
00333  * This data comes from the HP documentation "Deskjet 1220C and 1120C
00334  * PCL reference guide 2.0, Nov 1999".
00335  */
00336 
00337 static const short emptylist[] =
00338 {
00339   -1
00340 };
00341 
00342 static const short standard_papersizes[] =
00343 {
00344   PCL_PAPERSIZE_EXECUTIVE,
00345   PCL_PAPERSIZE_STATEMENT,
00346   PCL_PAPERSIZE_LETTER,
00347   PCL_PAPERSIZE_LEGAL,
00348   PCL_PAPERSIZE_A4,
00349   -1,
00350 };
00351 
00352 static const short letter_only_papersizes[] =
00353 {
00354   PCL_PAPERSIZE_LETTER,
00355   -1
00356 };
00357 
00358 static const short dj340_papersizes[] =
00359 {
00360   PCL_PAPERSIZE_EXECUTIVE,
00361   PCL_PAPERSIZE_LETTER,
00362   PCL_PAPERSIZE_LEGAL,
00363   PCL_PAPERSIZE_A4,
00364   -1,
00365 };
00366 
00367 static const short dj400_papersizes[] =
00368 {
00369   PCL_PAPERSIZE_EXECUTIVE,
00370   PCL_PAPERSIZE_LETTER,
00371   PCL_PAPERSIZE_LEGAL,
00372   PCL_PAPERSIZE_A4,
00373   PCL_PAPERSIZE_JIS_B5,
00374   -1,
00375 };
00376 
00377 static const short dj500_papersizes[] =
00378 {
00379 /*    PCL_PAPERSIZE_EXECUTIVE, The 500 doesn't support this, the 520 does */
00380   PCL_PAPERSIZE_LETTER,
00381   PCL_PAPERSIZE_LEGAL,
00382   PCL_PAPERSIZE_A4,
00383   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00384 /*    PCL_PAPERSIZE_DL_ENV,    The 500 doesn't support this, the 520 does */
00385   -1,
00386 };
00387 
00388 static const short dj540_papersizes[] =
00389 {
00390   PCL_PAPERSIZE_EXECUTIVE,
00391   PCL_PAPERSIZE_LETTER,
00392   PCL_PAPERSIZE_LEGAL,
00393   PCL_PAPERSIZE_A4,
00394   PCL_PAPERSIZE_A5,
00395   PCL_PAPERSIZE_JIS_B5,
00396   PCL_PAPERSIZE_HAGAKI_CARD,
00397   PCL_PAPERSIZE_A6_CARD,
00398   PCL_PAPERSIZE_4x6,
00399   PCL_PAPERSIZE_5x8,
00400   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00401   PCL_PAPERSIZE_DL_ENV,
00402   PCL_PAPERSIZE_C6_ENV,
00403   -1,
00404 };
00405 
00406 static const short dj600_papersizes[] =
00407 {
00408   PCL_PAPERSIZE_EXECUTIVE,
00409   PCL_PAPERSIZE_LETTER,
00410   PCL_PAPERSIZE_LEGAL,
00411   PCL_PAPERSIZE_A4,
00412   PCL_PAPERSIZE_A5,
00413   PCL_PAPERSIZE_HAGAKI_CARD,
00414   PCL_PAPERSIZE_A6_CARD,
00415   PCL_PAPERSIZE_4x6,
00416   PCL_PAPERSIZE_5x8,
00417   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00418   PCL_PAPERSIZE_DL_ENV,
00419   PCL_PAPERSIZE_C6_ENV,
00420   PCL_PAPERSIZE_INVITATION_ENV,
00421   -1,
00422 };
00423 
00424 static const short dj1220_papersizes[] =
00425 {
00426   PCL_PAPERSIZE_EXECUTIVE,
00427   PCL_PAPERSIZE_LETTER,
00428   PCL_PAPERSIZE_LEGAL,
00429   PCL_PAPERSIZE_TABLOID,
00430   PCL_PAPERSIZE_STATEMENT,
00431   PCL_PAPERSIZE_SUPER_B,
00432   PCL_PAPERSIZE_A5,
00433   PCL_PAPERSIZE_A4,
00434   PCL_PAPERSIZE_A3,
00435   PCL_PAPERSIZE_JIS_B5,
00436   PCL_PAPERSIZE_JIS_B4,
00437   PCL_PAPERSIZE_HAGAKI_CARD,
00438   PCL_PAPERSIZE_OUFUKU_CARD,
00439   PCL_PAPERSIZE_A6_CARD,
00440   PCL_PAPERSIZE_4x6,
00441   PCL_PAPERSIZE_5x8,
00442   PCL_PAPERSIZE_3x5,
00443   PCL_PAPERSIZE_HP_CARD,
00444   PCL_PAPERSIZE_MONARCH_ENV,
00445   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00446   PCL_PAPERSIZE_DL_ENV,
00447   PCL_PAPERSIZE_C5_ENV,
00448   PCL_PAPERSIZE_C6_ENV,
00449   PCL_PAPERSIZE_INVITATION_ENV,
00450   PCL_PAPERSIZE_JAPANESE_3_ENV,
00451   PCL_PAPERSIZE_JAPANESE_4_ENV,
00452   PCL_PAPERSIZE_KAKU_ENV,
00453   -1,
00454 };
00455 
00456 static const short dj1100_papersizes[] =
00457 {
00458   PCL_PAPERSIZE_EXECUTIVE,
00459   PCL_PAPERSIZE_LETTER,
00460   PCL_PAPERSIZE_LEGAL,
00461   PCL_PAPERSIZE_TABLOID,
00462   PCL_PAPERSIZE_STATEMENT,
00463   PCL_PAPERSIZE_SUPER_B,
00464   PCL_PAPERSIZE_A5,
00465   PCL_PAPERSIZE_A4,
00466   PCL_PAPERSIZE_A3,
00467   PCL_PAPERSIZE_JIS_B5,
00468   PCL_PAPERSIZE_JIS_B4,
00469   PCL_PAPERSIZE_HAGAKI_CARD,
00470   PCL_PAPERSIZE_A6_CARD,
00471   PCL_PAPERSIZE_4x6,
00472   PCL_PAPERSIZE_5x8,
00473   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00474   PCL_PAPERSIZE_DL_ENV,
00475   PCL_PAPERSIZE_C6_ENV,
00476   PCL_PAPERSIZE_INVITATION_ENV,
00477   PCL_PAPERSIZE_JAPANESE_3_ENV,
00478   PCL_PAPERSIZE_JAPANESE_4_ENV,
00479   PCL_PAPERSIZE_KAKU_ENV,
00480   -1,
00481 };
00482 
00483 static const short dj1200_papersizes[] =
00484 {
00485   /* This printer is not mentioned in the Comparison tables,
00486      so I'll just pick some likely sizes... */
00487   PCL_PAPERSIZE_EXECUTIVE,
00488   PCL_PAPERSIZE_LETTER,
00489   PCL_PAPERSIZE_LEGAL,
00490   PCL_PAPERSIZE_A5,
00491   PCL_PAPERSIZE_A4,
00492   PCL_PAPERSIZE_4x6,
00493   PCL_PAPERSIZE_5x8,
00494   -1,
00495 };
00496 
00497 static const short dj2000_papersizes[] =
00498 {
00499   PCL_PAPERSIZE_EXECUTIVE,
00500   PCL_PAPERSIZE_LETTER,
00501   PCL_PAPERSIZE_LEGAL,
00502   PCL_PAPERSIZE_A5,
00503   PCL_PAPERSIZE_A4,
00504   PCL_PAPERSIZE_HAGAKI_CARD,
00505   PCL_PAPERSIZE_A6_CARD,
00506   PCL_PAPERSIZE_4x6,
00507   PCL_PAPERSIZE_5x8,
00508   PCL_PAPERSIZE_3x5,
00509   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00510   PCL_PAPERSIZE_DL_ENV,
00511   PCL_PAPERSIZE_C6_ENV,
00512   PCL_PAPERSIZE_INVITATION_ENV,
00513   -1,
00514 };
00515 
00516 static const short dj2500_papersizes[] =
00517 {
00518   PCL_PAPERSIZE_EXECUTIVE,
00519   PCL_PAPERSIZE_LETTER,
00520   PCL_PAPERSIZE_LEGAL,
00521   PCL_PAPERSIZE_TABLOID,
00522   PCL_PAPERSIZE_STATEMENT,
00523   PCL_PAPERSIZE_A5,
00524   PCL_PAPERSIZE_A4,
00525   PCL_PAPERSIZE_A3,
00526   PCL_PAPERSIZE_JIS_B5,
00527   PCL_PAPERSIZE_JIS_B4,
00528   PCL_PAPERSIZE_HAGAKI_CARD,
00529   PCL_PAPERSIZE_A6_CARD,
00530   PCL_PAPERSIZE_4x6,
00531   PCL_PAPERSIZE_5x8,
00532   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00533   PCL_PAPERSIZE_DL_ENV,
00534   -1,
00535 };
00536 
00537 static const short ljsmall_papersizes[] =
00538 {
00539   PCL_PAPERSIZE_EXECUTIVE,
00540   PCL_PAPERSIZE_STATEMENT,
00541   PCL_PAPERSIZE_LETTER,
00542   PCL_PAPERSIZE_LEGAL,
00543   PCL_PAPERSIZE_A4,
00544   PCL_PAPERSIZE_MONARCH_ENV,
00545   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00546   PCL_PAPERSIZE_DL_ENV,
00547   PCL_PAPERSIZE_C5_ENV,
00548   PCL_PAPERSIZE_C6_ENV,
00549   -1,
00550 };
00551 
00552 static const short ljbig_papersizes[] =
00553 {
00554   PCL_PAPERSIZE_EXECUTIVE,
00555   PCL_PAPERSIZE_STATEMENT,
00556   PCL_PAPERSIZE_LETTER,
00557   PCL_PAPERSIZE_LEGAL,
00558   PCL_PAPERSIZE_TABLOID,
00559   PCL_PAPERSIZE_A5,
00560   PCL_PAPERSIZE_A4,
00561   PCL_PAPERSIZE_A3,
00562   PCL_PAPERSIZE_JIS_B5,
00563   PCL_PAPERSIZE_JIS_B4,                /* Guess */
00564   PCL_PAPERSIZE_4x6,
00565   PCL_PAPERSIZE_5x8,
00566   PCL_PAPERSIZE_MONARCH_ENV,
00567   PCL_PAPERSIZE_COMMERCIAL10_ENV,
00568   PCL_PAPERSIZE_DL_ENV,
00569   PCL_PAPERSIZE_C5_ENV,
00570   PCL_PAPERSIZE_C6_ENV,
00571   -1,
00572 };
00573 
00574 static const short basic_papertypes[] =
00575 {
00576   PCL_PAPERTYPE_PLAIN,
00577   PCL_PAPERTYPE_BOND,
00578   PCL_PAPERTYPE_PREMIUM,
00579   PCL_PAPERTYPE_GLOSSY,
00580   PCL_PAPERTYPE_TRANS,
00581   -1,
00582 };
00583 
00584 static const short new_papertypes[] =
00585 {
00586   PCL_PAPERTYPE_PLAIN,
00587   PCL_PAPERTYPE_BOND,
00588   PCL_PAPERTYPE_PREMIUM,
00589   PCL_PAPERTYPE_GLOSSY,
00590   PCL_PAPERTYPE_TRANS,
00591   PCL_PAPERTYPE_QPHOTO,
00592   PCL_PAPERTYPE_QTRANS,
00593   -1,
00594 };
00595 
00596 static const short laserjet_papersources[] =
00597 {
00598   PCL_PAPERSOURCE_STANDARD,
00599   PCL_PAPERSOURCE_MANUAL,
00600   PCL_PAPERSOURCE_LJ_TRAY1,
00601   PCL_PAPERSOURCE_LJ_TRAY2,
00602   PCL_PAPERSOURCE_LJ_TRAY3,
00603   PCL_PAPERSOURCE_LJ_TRAY4,
00604   -1,
00605 };
00606 
00607 static const short dj340_papersources[] =
00608 {
00609   PCL_PAPERSOURCE_STANDARD,
00610   PCL_PAPERSOURCE_MANUAL,
00611   PCL_PAPERSOURCE_340_PCSF,
00612   PCL_PAPERSOURCE_340_DCSF,
00613   -1,
00614 };
00615 
00616 static const short dj_papersources[] =
00617 {
00618   PCL_PAPERSOURCE_STANDARD,
00619   PCL_PAPERSOURCE_MANUAL,
00620   PCL_PAPERSOURCE_DJ_TRAY,
00621   -1,
00622 };
00623 
00624 static const short dj2500_papersources[] =
00625 {
00626   PCL_PAPERSOURCE_STANDARD,
00627   PCL_PAPERSOURCE_MANUAL,
00628   PCL_PAPERSOURCE_DJ_AUTO,
00629   PCL_PAPERSOURCE_DJ_TRAY,
00630   PCL_PAPERSOURCE_DJ_TRAY2,
00631   PCL_PAPERSOURCE_DJ_OPTIONAL,
00632   -1,
00633 };
00634 
00635 static const short standard_papersources[] =
00636 {
00637   PCL_PAPERSOURCE_STANDARD,
00638   -1
00639 };
00640 
00641 static const pcl_cap_t pcl_model_capabilities[] =
00642 {
00643   /* Default/unknown printer - assume laserjet */
00644   { 0,
00645     17 * 72 / 2, 14 * 72,               /* Max paper size */
00646     1, 1,                               /* Min paper size */
00647     PCL_RES_150_150 | PCL_RES_300_300,  /* Resolutions */
00648     {12, 12, 18, 18},                   /* non-A4 Margins */
00649     {12, 12, 10, 10},                   /* A4 Margins */
00650     PCL_COLOR_NONE,
00651     PCL_PRINTER_LJ,
00652     standard_papersizes,
00653     emptylist,
00654     emptylist,
00655   },
00656   /* DesignJet 230/430 (monochrome ) */
00657   { 10230,
00658     36 * 72, 150 * 12 * 72,             /* 150ft in roll mode, 64" in sheet */
00659     830 * 72 / 100, 583 * 72 / 100,     /* 8.3" wide min in sheet mode */
00660     PCL_RES_300_300 | PCL_RES_600_600,
00661     {49, 49, 15, 15},
00662     {49, 49, 15, 15},
00663     PCL_COLOR_NONE,
00664     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG,
00665     letter_only_papersizes,
00666     basic_papertypes,
00667     standard_papersources,
00668   },
00669   /* DesignJet 250C/450C/455CA/488CA */
00670   /* The "CA" versions have a "software RIP" but are the same hardware */
00671   { 10250,
00672     36 * 72, 150 * 12 * 72,             /* 150ft in roll mode, 64" in sheet */
00673     830 * 72 / 100, 583 * 72 / 100,     /* 8.3" wide min in sheet mode */
00674     PCL_RES_300_300 | PCL_RES_600_600_MONO,
00675     {49, 49, 15, 15},
00676     {49, 49, 15, 15},
00677     PCL_COLOR_CMYK,
00678     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG,
00679     letter_only_papersizes,
00680     basic_papertypes,
00681     standard_papersources,
00682   },
00683   /* DesignJet 700 (monochrome) */
00684   { 10700,
00685     36 * 72, 150 * 12 * 72,             /* 150ft in roll mode, 64" in sheet */
00686     830 * 72 / 100, 583 * 72 / 100,     /* 8.3" wide min in sheet mode */
00687     PCL_RES_300_300 | PCL_RES_600_600,
00688     {30, 30, 15, 15},           /* These margins are for sheet mode FIX */
00689     {30, 30, 15, 15},
00690     PCL_COLOR_NONE,
00691     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG,
00692     letter_only_papersizes,
00693     basic_papertypes,
00694     standard_papersources,
00695   },
00696   /* DesignJet 750C */
00697   { 10750,
00698     36 * 72, 150 * 12 * 72,             /* 150ft in roll mode, 64" in sheet */
00699     830 * 72 / 100, 583 * 72 / 100,     /* 8.3" wide min in sheet mode */
00700     PCL_RES_300_300 | PCL_RES_600_600_MONO,
00701     {30, 30, 15, 15},   /* These margins are for roll mode FIX */
00702     {30, 30, 15, 15},
00703     PCL_COLOR_CMYK,
00704     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG,
00705     letter_only_papersizes,
00706     basic_papertypes,
00707     standard_papersources,
00708   },
00709   /* DesignJet 2500C/3500C (44" wide) */
00710   { 12500,      /* Deskjet 2500 already has "2500" */
00711     44 * 72, 150 * 12 * 72,             /* 150ft in roll mode, 64" in sheet */
00712     830 * 72 / 100, 583 * 72 / 100,     /* 8.3" wide min in sheet mode */
00713     PCL_RES_300_300 | PCL_RES_600_600_MONO,
00714     {49, 49, 15, 15},           /* Check/Fix */
00715     {49, 49, 15, 15},
00716     PCL_COLOR_CMYK,
00717     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG,
00718     letter_only_papersizes,
00719     basic_papertypes,
00720     standard_papersources,
00721   },
00722   /* Deskjet 340 */
00723   { 340,
00724     17 * 72 / 2, 14 * 72,
00725     1, 1,                               /* Min paper size */
00726     PCL_RES_150_150 | PCL_RES_300_300,
00727     {6, 48, 18, 18},    /* from bpd07933.pdf */
00728     {6, 48, 10, 11},    /* from bpd07933.pdf */
00729     PCL_COLOR_CMY,
00730     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
00731     dj340_papersizes,
00732     basic_papertypes,
00733     dj340_papersources,
00734   },
00735   /* Deskjet 400 */
00736   { 400,
00737     17 * 72 / 2, 14 * 72,
00738     1, 1,                               /* Min paper size */
00739     PCL_RES_150_150 | PCL_RES_300_300,
00740     {7, 41, 18, 18},
00741     {7, 41, 10, 10},    /* Check/Fix */
00742     PCL_COLOR_CMY,
00743     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
00744     dj400_papersizes,
00745     basic_papertypes,
00746     emptylist,
00747   },
00748   /* Deskjet 500, 520. Lexmark 4076 */
00749   { 500,
00750     17 * 72 / 2, 14 * 72,
00751     1, 1,                               /* Min paper size */
00752     PCL_RES_150_150 | PCL_RES_300_300,
00753     {7, 41, 18, 18},
00754     {7, 41, 10, 10},    /* Check/Fix */
00755     PCL_COLOR_NONE,
00756     PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
00757     dj500_papersizes,
00758     basic_papertypes,
00759     dj_papersources,
00760   },
00761   /* Deskjet 500C */
00762   { 501,
00763     17 * 72 / 2, 14 * 72,
00764     1, 1,                               /* Min paper size */
00765     PCL_RES_150_150 | PCL_RES_300_300,
00766     {7, 33, 18, 18},
00767     {7, 33, 10, 10},    /* Check/Fix */
00768     PCL_COLOR_CMY,
00769     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
00770     dj500_papersizes,
00771     basic_papertypes,
00772     dj_papersources,
00773   },
00774   /* Deskjet 540C */
00775   { 540,
00776     17 * 72 / 2, 14 * 72,
00777     1, 1,                               /* Min paper size */
00778     PCL_RES_150_150 | PCL_RES_300_300,
00779     {7, 33, 18, 18},
00780     {7, 33, 10, 10},    /* Check/Fix */
00781     PCL_COLOR_CMY,
00782     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00783       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00784     dj540_papersizes,
00785     basic_papertypes,
00786     dj_papersources,
00787   },
00788   /* Deskjet 550C, 560C */
00789   { 550,
00790     17 * 72 / 2, 14 * 72,
00791     1, 1,                               /* Min paper size */
00792     PCL_RES_150_150 | PCL_RES_300_300,
00793     {3, 33, 18, 18},
00794     {5, 33, 10, 10},
00795     PCL_COLOR_CMYK,
00796     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
00797 /* The 550/560 support COM10 and DL envelope, but the control codes
00798    are negative, indicating landscape mode. This needs thinking about! */
00799     dj340_papersizes,
00800     basic_papertypes,
00801     dj_papersources,
00802   },
00803   /* Deskjet 600/600C */
00804   { 600,
00805     17 * 72 / 2, 14 * 72,
00806     5 * 72, 583 * 72 / 100,             /* Min paper size */
00807     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600_MONO,
00808     {0, 33, 18, 18},
00809     {0, 33, 10, 10},    /* Check/Fix */
00810     PCL_COLOR_CMY,
00811     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00812       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00813     dj600_papersizes,
00814     basic_papertypes,
00815     emptylist,
00816   },
00817   /* Deskjet 6xx series */
00818   { 601,
00819     17 * 72 / 2, 14 * 72,
00820     1, 1,                               /* Min paper size */
00821     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600_MONO,
00822     {0, 33, 18, 18},
00823     {0, 33, 10, 10},    /* Check/Fix */
00824     PCL_COLOR_CMYK,
00825     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00826       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00827     dj600_papersizes,
00828     basic_papertypes,
00829     emptylist,
00830   },
00831   /* Deskjet 69x series (Photo Capable) */
00832   { 690,
00833     17 * 72 / 2, 14 * 72,
00834     1, 1,                               /* Min paper size */
00835     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600,
00836     {0, 33, 18, 18},
00837     {0, 33, 10, 10},    /* Check/Fix */
00838     PCL_COLOR_CMYK | PCL_COLOR_CMYKcm,
00839     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00840       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00841     dj600_papersizes,
00842     basic_papertypes,
00843     emptylist,
00844   },
00845   /* Deskjet 850/855/870/890 (C-RET) */
00846   { 800,
00847     17 * 72 / 2, 14 * 72,
00848     1, 1,                               /* Min paper size */
00849     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600_MONO,
00850     {3, 33, 18, 18},
00851     {5, 33, 10, 10},
00852     PCL_COLOR_CMYK | PCL_COLOR_CMYK4,
00853     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00854       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00855     dj600_papersizes,
00856     basic_papertypes,
00857     emptylist,
00858   },
00859   /* Deskjet 810C, 812C, 840C, 842C, 845C, 895C (C-RET) */
00860   { 840,
00861     17 * 72 / 2, 14 * 72,
00862     1, 1,                               /* Min paper size */
00863     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600,
00864     {0, 33, 18, 18},
00865     {0, 33, 10, 10},    /* Check/Fix */
00866     PCL_COLOR_CMYK | PCL_COLOR_CMYK4b,
00867     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00868       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00869     dj600_papersizes,
00870     basic_papertypes,
00871     emptylist,
00872   },
00873   /* Deskjet 900 series, 1220C, PhotoSmart P1000/P1100 */
00874   { 900,
00875     17 * 72 / 2, 14 * 72,
00876     1, 1,                               /* Min paper size */
00877     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600 /* | PCL_RES_1200_600 | PCL_RES_2400_600 */,
00878     {3, 33, 18, 18},
00879     {5, 33, 10, 10},    /* Oliver Vecernik */
00880     PCL_COLOR_CMYK,
00881     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00882       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00883     dj600_papersizes,
00884     basic_papertypes,
00885     emptylist,
00886   },
00887   /* Deskjet 1220C (or other large format 900) */
00888   { 901,
00889     13 * 72, 19 * 72,
00890     1, 1,                               /* Min paper size */
00891     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600 /* | PCL_RES_1200_600 | PCL_RES_2400_600 */,
00892     {3, 33, 18, 18},
00893     {5, 33, 10, 10},
00894     PCL_COLOR_CMYK,
00895     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00896       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00897     dj1220_papersizes,
00898     basic_papertypes,
00899     emptylist,
00900   },
00901   /* Deskjet 1100C, 1120C */
00902   { 1100,
00903     13 * 72, 19 * 72,
00904     1, 1,                               /* Min paper size */
00905     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600_MONO,
00906     {3, 33, 18, 18},
00907     {5, 33, 10, 10},
00908     PCL_COLOR_CMYK | PCL_COLOR_CMYK4,
00909     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00910       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00911     dj1100_papersizes,
00912     basic_papertypes,
00913     dj_papersources,
00914   },
00915   /* Deskjet 1200C */
00916   { 1200,
00917     17 * 72 / 2, 14 * 72,
00918     1, 1,                               /* Min paper size */
00919     PCL_RES_150_150 | PCL_RES_300_300,
00920     {12, 12, 18, 18},
00921     {12, 12, 10, 10},   /* Check/Fix */
00922     PCL_COLOR_CMY,
00923     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00924       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00925     dj1200_papersizes,
00926     basic_papertypes,
00927     dj_papersources,
00928   },
00929   /* Deskjet 1600C */
00930   { 1600,
00931     17 * 72 / 2, 14 * 72,
00932     1, 1,                               /* Min paper size */
00933     PCL_RES_150_150 | PCL_RES_300_300,
00934     {12, 12, 18, 18},
00935     {12, 12, 10, 10},   /* Check/Fix */
00936     PCL_COLOR_CMYK,
00937     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00938       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00939     dj1200_papersizes,
00940     basic_papertypes,
00941     dj_papersources,
00942   },
00943   /* Deskjet 2000 */
00944   { 2000,
00945     17 * 72 / 2, 14 * 72,
00946     1, 1,                               /* Min paper size */
00947     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600,
00948     {0, 35, 18, 18},                    /* Michel Goraczko */
00949     {0, 35, 10, 10},    /* Check/Fix */
00950     PCL_COLOR_CMYK,
00951     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00952       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00953     dj2000_papersizes,
00954     new_papertypes,
00955     dj_papersources,
00956   },
00957   /* Deskjet 2500 */
00958   { 2500,
00959     13 * 72, 19 * 72,
00960     1, 1,                               /* Min paper size */
00961     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600,
00962     {12, 12, 18, 18},
00963     {12, 12, 10, 10},   /* Check/Fix */
00964     PCL_COLOR_CMYK,
00965     PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE |
00966       PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE,
00967     dj2500_papersizes,
00968     new_papertypes,
00969     dj2500_papersources,
00970   },
00971   /* LaserJet II series */
00972   { 2,
00973     17 * 72 / 2, 14 * 72,
00974     1, 1,                               /* Min paper size */
00975     PCL_RES_150_150 | PCL_RES_300_300,
00976     {12, 12, 18, 18},
00977     {12, 12, 10, 10},   /* Check/Fix */
00978     PCL_COLOR_NONE,
00979     PCL_PRINTER_LJ,
00980     ljsmall_papersizes,
00981     emptylist,
00982     laserjet_papersources,
00983   },
00984   /* LaserJet IIP (TIFF but no blankline) */
00985   { 21,
00986     17 * 72 / 2, 14 * 72,
00987     1, 1,                               /* Min paper size */
00988     PCL_RES_150_150 | PCL_RES_300_300,
00989     {12, 12, 18, 18},
00990     {12, 12, 10, 10},   /* Check/Fix */
00991     PCL_COLOR_NONE,
00992     PCL_PRINTER_LJ | PCL_PRINTER_TIFF,
00993     ljsmall_papersizes,
00994     emptylist,
00995     laserjet_papersources,
00996   },
00997   /* LaserJet III series */
00998   { 3,
00999     17 * 72 / 2, 14 * 72,
01000     1, 1,                               /* Min paper size */
01001     PCL_RES_150_150 | PCL_RES_300_300,
01002     {12, 12, 18, 18},
01003     {12, 12, 10, 10},   /* Check/Fix */
01004     PCL_COLOR_NONE,
01005     PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
01006     ljsmall_papersizes,
01007     emptylist,
01008     laserjet_papersources,
01009   },
01010   /* LaserJet 4L */
01011   { 4,
01012     17 * 72 / 2, 14 * 72,
01013     1, 1,                               /* Min paper size */
01014     PCL_RES_150_150 | PCL_RES_300_300,
01015     {12, 12, 18, 18},
01016     {12, 12, 10, 10},   /* Check/Fix */
01017     PCL_COLOR_NONE,
01018     PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
01019     ljsmall_papersizes,
01020     emptylist,
01021     laserjet_papersources,
01022   },
01023   /* LaserJet 4V, 4Si */
01024   { 5,
01025     13 * 72, 19 * 72,
01026     1, 1,                               /* Min paper size */
01027     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600,
01028     {12, 12, 18, 18},
01029     {12, 12, 10, 10},   /* Check/Fix */
01030     PCL_COLOR_NONE,
01031     PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
01032     ljbig_papersizes,
01033     emptylist,
01034     laserjet_papersources,
01035   },
01036   /* LaserJet 4 series (except as above), 5 series, 6 series */
01037   { 6,
01038     17 * 72 / 2, 14 * 72,
01039     1, 1,                               /* Min paper size */
01040     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600,
01041     {12, 12, 18, 18},
01042     {12, 12, 10, 10},   /* Check/Fix */
01043     PCL_COLOR_NONE,
01044     PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
01045     ljsmall_papersizes,
01046     emptylist,
01047     laserjet_papersources,
01048   },
01049   /* LaserJet 5Si */
01050   { 7,
01051     13 * 72, 19 * 72,
01052     1, 1,                               /* Min paper size */
01053     PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600,
01054     {12, 12, 18, 18},
01055     {12, 12, 10, 10},   /* Check/Fix */
01056     PCL_COLOR_NONE,
01057     PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE,
01058     ljbig_papersizes,
01059     emptylist,
01060     laserjet_papersources,
01061   },
01062 };
01063 
01064 
01065 static const char standard_sat_adjustment[] =
01066 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
01067 "<gimp-print>\n"
01068 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
01069 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
01070 /* C */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* B */
01071 /* B */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* M */
01072 /* M */  "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 "  /* R */
01073 /* R */  "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 "  /* Y */
01074 /* Y */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* G */
01075 /* G */  "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 "  /* C */
01076 "</sequence>\n"
01077 "</curve>\n"
01078 "</gimp-print>\n";
01079 
01080 static const char standard_lum_adjustment[] =
01081 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
01082 "<gimp-print>\n"
01083 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
01084 "<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n"
01085 /* C */  "0.50 0.52 0.56 0.60 0.66 0.71 0.74 0.77 "  /* B */
01086 /* B */  "0.81 0.79 0.74 0.68 0.70 0.74 0.77 0.82 "  /* M */
01087 /* M */  "0.88 0.93 0.95 0.97 0.97 0.96 0.95 0.95 "  /* R */
01088 /* R */  "0.95 0.96 0.97 0.98 0.99 1.00 1.00 1.00 "  /* Y */
01089 /* Y */  "1.00 0.97 0.94 0.92 0.90 0.88 0.85 0.79 "  /* G */
01090 /* G */  "0.69 0.64 0.58 0.54 0.54 0.54 0.53 0.51 "  /* C */
01091 "</sequence>\n"
01092 "</curve>\n"
01093 "</gimp-print>\n";
01094 
01095 static const char standard_hue_adjustment[] =
01096 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
01097 "<gimp-print>\n"
01098 "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
01099 "<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n"
01100 /* C */  "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 "  /* B */
01101 /* B */  "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 "  /* M */
01102 /* M */  "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 "  /* R */
01103 /* R */  "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 "  /* Y */
01104 /* Y */  "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 "  /* G */
01105 /* G */  "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 "  /* C */
01106 "</sequence>\n"
01107 "</curve>\n"
01108 "</gimp-print>\n";
01109 
01110 static const stp_parameter_t the_parameters[] =
01111 {
01112   {
01113     "PageSize", N_("Page Size"), N_("Basic Printer Setup"),
01114     N_("Size of the paper being printed to"),
01115     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
01116     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01117   },
01118   {
01119     "MediaType", N_("Media Type"), N_("Basic Printer Setup"),
01120     N_("Type of media (plain paper, photo paper, etc.)"),
01121     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01122     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01123   },
01124   {
01125     "InputSlot", N_("Media Source"), N_("Basic Printer Setup"),
01126     N_("Source (input slot) of the media"),
01127     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01128     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01129   },
01130   {
01131     "Resolution", N_("Resolution"), N_("Basic Printer Setup"),
01132     N_("Resolution and quality of the print"),
01133     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01134     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01135   },
01136   {
01137     "InkType", N_("Ink Type"), N_("Advanced Printer Setup"),
01138     N_("Type of ink in the printer"),
01139     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE,
01140     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01141   },
01142   {
01143     "InkChannels", N_("Ink Channels"), N_("Advanced Printer Functionality"),
01144     N_("Ink Channels"),
01145     STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE,
01146     STP_PARAMETER_LEVEL_INTERNAL, 0, 0, -1, 0, 0
01147   },
01148   {
01149     "PrintingMode", N_("Printing Mode"), N_("Core Parameter"),
01150     N_("Printing Output Mode"),
01151     STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE,
01152     STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1, 0
01153   },
01154 };
01155 
01156 static const int the_parameter_count =
01157 sizeof(the_parameters) / sizeof(const stp_parameter_t);
01158 
01159 typedef struct
01160 {
01161   const stp_parameter_t param;
01162   double min;
01163   double max;
01164   double defval;
01165   int color_only;
01166 } float_param_t;
01167 
01168 static const float_param_t float_parameters[] =
01169 {
01170   {
01171     {
01172       "CyanDensity", N_("Cyan Balance"), N_("Output Level Adjustment"),
01173       N_("Adjust the cyan balance"),
01174       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01175       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0
01176     }, 0.0, 2.0, 1.0, 1
01177   },
01178   {
01179     {
01180       "MagentaDensity", N_("Magenta Balance"), N_("Output Level Adjustment"),
01181       N_("Adjust the magenta balance"),
01182       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01183       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0
01184     }, 0.0, 2.0, 1.0, 1
01185   },
01186   {
01187     {
01188       "YellowDensity", N_("Yellow Balance"), N_("Output Level Adjustment"),
01189       N_("Adjust the yellow balance"),
01190       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01191       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0
01192     }, 0.0, 2.0, 1.0, 1
01193   },
01194   {
01195     {
01196       "BlackDensity", N_("Black Balance"), N_("Output Level Adjustment"),
01197       N_("Adjust the black balance"),
01198       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01199       STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0
01200     }, 0.0, 2.0, 1.0, 1
01201   },
01202   {
01203     {
01204       "LightCyanTransition", N_("Light Cyan Transition"), N_("Advanced Ink Adjustment"),
01205       N_("Light Cyan Transition"),
01206       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01207       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
01208     }, 0.0, 5.0, 1.0, 1
01209   },
01210   {
01211     {
01212       "LightMagentaTransition", N_("Light Magenta Transition"), N_("Advanced Ink Adjustment"),
01213       N_("Light Magenta Transition"),
01214       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
01215       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 1, 0
01216     }, 0.0, 5.0, 1.0, 1
01217   },
01218 };
01219 
01220 static const int float_parameter_count =
01221 sizeof(float_parameters) / sizeof(const float_param_t);
01222 
01223 /*
01224  * Convert a name into it's option value
01225  */
01226 
01227 static int pcl_string_to_val(const char *string,                /* I: String */
01228                            const pcl_t *options,        /* I: Options */
01229                            int num_options)             /* I: Num options */
01230 {
01231 
01232   int i;
01233   int code = -1;
01234 
01235  /*
01236   * Look up the string in the table and convert to the code.
01237   */
01238 
01239   for (i=0; i<num_options; i++) {
01240     if (!strcmp(string, options[i].pcl_name)) {
01241        code=options[i].pcl_code;
01242        break;
01243        }
01244   }
01245 
01246   stp_deprintf(STP_DBG_PCL, "String: %s, Code: %d\n", string, code);
01247 
01248   return(code);
01249 }
01250 
01251 /*
01252  * Convert a value into it's option name
01253  */
01254 
01255 static const char * pcl_val_to_string(int code,                 /* I: Code */
01256                            const pcl_t *options,        /* I: Options */
01257                            int num_options)             /* I: Num options */
01258 {
01259 
01260   int i;
01261   const char *string = NULL;
01262 
01263  /*
01264   * Look up the code in the table and convert to the string.
01265   */
01266 
01267   for (i=0; i<num_options; i++) {
01268     if (code == options[i].pcl_code) {
01269        string=options[i].pcl_name;
01270        break;
01271        }
01272   }
01273 
01274   stp_deprintf(STP_DBG_PCL, "Code: %d, String: %s\n", code, string);
01275 
01276   return(string);
01277 }
01278 
01279 static const char * pcl_val_to_text(int code,                   /* I: Code */
01280                            const pcl_t *options,        /* I: Options */
01281                            int num_options)             /* I: Num options */
01282 {
01283 
01284   int i;
01285   const char *string = NULL;
01286 
01287  /*
01288   * Look up the code in the table and convert to the string.
01289   */
01290 
01291   for (i=0; i<num_options; i++) {
01292     if (code == options[i].pcl_code) {
01293        string=options[i].pcl_text;
01294        break;
01295        }
01296   }
01297 
01298   stp_deprintf(STP_DBG_PCL, "Code: %d, String: %s\n", code, string);
01299 
01300   return(string);
01301 }
01302 
01303 static const double dot_sizes[] = { 0.5, 0.832, 1.0 };
01304 static const double dot_sizes_cret[] = { 1.0, 1.0, 1.0 };
01305 
01306 static const stp_dotsize_t variable_dotsizes[] =
01307 {
01308   { 0x1, 0.5 },
01309   { 0x2, 0.67 },
01310   { 0x3, 1.0 }
01311 };
01312 
01313 static const stp_shade_t variable_shades[] =
01314 {
01315   { 0.38, 3, variable_dotsizes },
01316   { 1.0, 3, variable_dotsizes }
01317 };
01318 
01319 /*
01320  * pcl_get_model_capabilities() - Return struct of model capabilities
01321  */
01322 
01323 static const pcl_cap_t *                                /* O: Capabilities */
01324 pcl_get_model_capabilities(int model)   /* I: Model */
01325 {
01326   int i;
01327   int models= sizeof(pcl_model_capabilities) / sizeof(pcl_cap_t);
01328   for (i=0; i<models; i++) {
01329     if (pcl_model_capabilities[i].model == model) {
01330       return &(pcl_model_capabilities[i]);
01331     }
01332   }
01333   stp_erprintf("pcl: model %d not found in capabilities list.\n",model);
01334   return &(pcl_model_capabilities[0]);
01335 }
01336 
01337 /*
01338  * Convert Media size name into PCL media code for printer
01339  */
01340 
01341 static int pcl_convert_media_size(const char *media_size,       /* I: Media size string */
01342                                   int  model)           /* I: model number */
01343 {
01344 
01345   int i;
01346   int media_code = 0;
01347   const pcl_cap_t *caps;
01348 
01349  /*
01350   * First look up the media size in the table and convert to the code.
01351   */
01352 
01353   media_code = pcl_string_to_val(media_size, pcl_media_sizes,
01354                                  NUM_PRINTER_PAPER_SIZES);
01355 
01356   stp_deprintf(STP_DBG_PCL, "Media Size: %s, Code: %d\n", media_size, media_code);
01357 
01358  /*
01359   * Now see if the printer supports the code found.
01360   */
01361 
01362   if (media_code != -1) {
01363     caps = pcl_get_model_capabilities(model);
01364 
01365     for (i=0; (i<NUM_PRINTER_PAPER_SIZES) && (caps->paper_sizes[i] != -1); i++) {
01366       if (media_code == (int) caps->paper_sizes[i])
01367         return(media_code);             /* Is supported */
01368     }
01369 
01370     stp_deprintf(STP_DBG_PCL, "Media Code %d not supported by printer model %d.\n",
01371       media_code, model);
01372     return(-1);                         /* Not supported */
01373   }
01374   else
01375     return(-1);                         /* Not supported */
01376 }
01377 
01378 
01379 static const stp_param_string_t ink_types[] =
01380 {
01381   { "CMYK",     N_ ("Color + Black Cartridges") },
01382   { "Photo",    N_ ("Color + Photo Cartridges") }
01383 };
01384 
01385 
01386 /*
01387  * 'pcl_papersize_valid()' - Is the paper size valid for this printer.
01388  */
01389 
01390 static const int
01391 pcl_papersize_valid(const stp_papersize_t *pt,
01392                     int model)
01393 {
01394 
01395   const pcl_cap_t *caps = pcl_get_model_capabilities(model);
01396 
01397 #ifdef PCL_NO_CUSTOM_PAPERSIZES
01398   int use_custom = 0;
01399 #else
01400   int use_custom = ((caps->stp_printer_type & PCL_PRINTER_CUSTOM_SIZE)
01401                      == PCL_PRINTER_CUSTOM_SIZE);
01402 #endif
01403 
01404   unsigned int pwidth = pt->width;
01405   unsigned int pheight = pt->height;
01406 
01407 /*
01408  * This function decides whether a paper size is allowed for the
01409  * current printer. The DeskJet feed mechanisms set a minimum and
01410  * maximum size for the paper, BUT some of the directly supported
01411  * media sizes are less than this minimum (eg card and envelopes)
01412  * So, we allow supported sizes though, but clamp custom sizes
01413  * to the min and max sizes.
01414  */
01415 
01416 /*
01417  * Is it a valid name?
01418  */
01419 
01420   if (strlen(pt->name) <= 0)
01421     return(0);
01422 
01423 /*
01424  * Is it a recognised supported name?
01425  */
01426 
01427   if (pcl_convert_media_size(pt->name, model) != -1)
01428     return(1);
01429 
01430 /*
01431  * If we are not allowed to use custom paper sizes, we are done
01432  */
01433 
01434   if (use_custom == 0)
01435     return(0);
01436 
01437 /*
01438  * We are allowed custom paper sizes. Check that the size is within
01439  * limits.
01440  */
01441 
01442   if (pwidth <= caps->custom_max_width &&
01443      pheight <= caps->custom_max_height &&
01444      (pheight >=  caps->custom_min_height || pheight == 0) &&
01445      (pwidth >= caps->custom_min_width || pwidth == 0))
01446     return(1);
01447 
01448   return(0);
01449 }
01450 
01451 /*
01452  * 'pcl_parameters()' - Return the parameter values for the given parameter.
01453  */
01454 
01455 static stp_parameter_list_t
01456 pcl_list_parameters(const stp_vars_t *v)
01457 {
01458   stp_parameter_list_t *ret = stp_parameter_list_create();
01459   int i;
01460   for (i = 0; i < the_parameter_count; i++)
01461     stp_parameter_list_add_param(ret, &(the_parameters[i]));
01462   for (i = 0; i < float_parameter_count; i++)
01463     stp_parameter_list_add_param(ret, &(float_parameters[i].param));
01464   return ret;
01465 }
01466 
01467 static void
01468 pcl_parameters(const stp_vars_t *v, const char *name,
01469                stp_parameter_t *description)
01470 {
01471   int           model = stp_get_model_id(v);
01472   int           i;
01473   const pcl_cap_t *caps;
01474   description->p_type = STP_PARAMETER_TYPE_INVALID;
01475 
01476   if (name == NULL)
01477     return;
01478 
01479   stp_deprintf(STP_DBG_PCL, "pcl_parameters(): Name = %s\n", name);
01480 
01481   caps = pcl_get_model_capabilities(model);
01482 
01483   stp_deprintf(STP_DBG_PCL, "Printer model = %d\n", model);
01484   stp_deprintf(STP_DBG_PCL, "PageWidth = %d, PageHeight = %d\n", caps->custom_max_width, caps->custom_max_height);
01485   stp_deprintf(STP_DBG_PCL, "MinPageWidth = %d, MinPageHeight = %d\n", caps->custom_min_width, caps->custom_min_height);
01486   stp_deprintf(STP_DBG_PCL, "Normal Margins: top = %d, bottom = %d, left = %d, right = %d\n",
01487     caps->normal_margins.top_margin, caps->normal_margins.bottom_margin,
01488     caps->normal_margins.left_margin, caps->normal_margins.right_margin);
01489   stp_deprintf(STP_DBG_PCL, "A4 Margins: top = %d, bottom = %d, left = %d, right = %d\n",
01490     caps->a4_margins.top_margin, caps->a4_margins.bottom_margin,
01491     caps->a4_margins.left_margin, caps->a4_margins.right_margin);
01492   stp_deprintf(STP_DBG_PCL, "Resolutions: %d\n", caps->resolutions);
01493   stp_deprintf(STP_DBG_PCL, "ColorType = %d, PrinterType = %d\n", caps->color_type, caps->stp_printer_type);
01494 
01495   for (i = 0; i < float_parameter_count; i++)
01496     if (strcmp(name, float_parameters[i].param.name) == 0)
01497       {
01498         stp_fill_parameter_settings(description,
01499                                     &(float_parameters[i].param));
01500         description->deflt.dbl = float_parameters[i].defval;
01501         description->bounds.dbl.upper = float_parameters[i].max;
01502         description->bounds.dbl.lower = float_parameters[i].min;
01503       }
01504 
01505   for (i = 0; i < the_parameter_count; i++)
01506     if (strcmp(name, the_parameters[i].name) == 0)
01507       {
01508         stp_fill_parameter_settings(description, &(the_parameters[i]));
01509         break;
01510       }
01511   description->deflt.str = NULL;
01512 
01513   if (strcmp(name, "PageSize") == 0)
01514     {
01515       int papersizes = stp_known_papersizes();
01516       description->bounds.str = stp_string_list_create();
01517       for (i = 0; i < papersizes; i++)
01518         {
01519           const stp_papersize_t *pt = stp_get_papersize_by_index(i);
01520           if (strlen(pt->name) > 0 && pcl_papersize_valid(pt, model))
01521             stp_string_list_add_string(description->bounds.str,
01522                                        pt->name, pt->text);
01523         }
01524       description->deflt.str =
01525         stp_string_list_param(description->bounds.str, 0)->name;
01526     }
01527   else if (strcmp(name, "MediaType") == 0)
01528   {
01529     description->bounds.str = stp_string_list_create();
01530     if (caps->paper_types[0] != -1)
01531       {
01532         for (i=0; (i < NUM_PRINTER_PAPER_TYPES) && (caps->paper_types[i] != -1); i++)
01533           stp_string_list_add_string(description->bounds.str,
01534                                     pcl_val_to_string(caps->paper_types[i],
01535                                                       pcl_media_types,
01536                                                       NUM_PRINTER_PAPER_TYPES),
01537                                     pcl_val_to_text(caps->paper_types[i],
01538                                                     pcl_media_types,
01539                                                     NUM_PRINTER_PAPER_TYPES));
01540         description->deflt.str =
01541           stp_string_list_param(description->bounds.str, 0)->name;
01542       }
01543     else
01544       description->is_active = 0;
01545   }
01546   else if (strcmp(name, "InputSlot") == 0)
01547   {
01548     description->bounds.str = stp_string_list_create();
01549     if (caps->paper_sources[0] != -1)
01550       {
01551         for (i=0; (i < NUM_PRINTER_PAPER_SOURCES) && (caps->paper_sources[i] != -1); i++)
01552           stp_string_list_add_string(description->bounds.str,
01553                                     pcl_val_to_string(caps->paper_sources[i],
01554                                                       pcl_media_sources,
01555                                                       NUM_PRINTER_PAPER_SOURCES),
01556                                     pcl_val_to_text(caps->paper_sources[i],
01557                                                     pcl_media_sources,
01558                                                     NUM_PRINTER_PAPER_SOURCES));
01559         description->deflt.str =
01560           stp_string_list_param(description->bounds.str, 0)->name;
01561       }
01562     else
01563       description->is_active = 0;
01564   }
01565   else if (strcmp(name, "Resolution") == 0)
01566   {
01567     description->bounds.str = stp_string_list_create();
01568     description->deflt.str = NULL;
01569     for (i = 0; i < NUM_RESOLUTIONS; i++)
01570       if (caps->resolutions & pcl_resolutions[i].pcl_code)
01571         {
01572           if (pcl_resolutions[i].pcl_code >= PCL_RES_300_300 &&
01573               description->deflt.str == NULL)
01574             description->deflt.str =
01575               pcl_val_to_string(pcl_resolutions[i].pcl_code,
01576                                 pcl_resolutions, NUM_RESOLUTIONS);
01577           stp_string_list_add_string
01578             (description->bounds.str,
01579              pcl_val_to_string(pcl_resolutions[i].pcl_code,
01580                                pcl_resolutions, NUM_RESOLUTIONS),
01581              pcl_val_to_text(pcl_resolutions[i].pcl_code,
01582                              pcl_resolutions, NUM_RESOLUTIONS));
01583         }
01584     if (description->deflt.str == NULL)
01585       stp_erprintf("No default resolution set!\n");
01586   }
01587   else if (strcmp(name, "InkType") == 0)
01588   {
01589     description->bounds.str = stp_string_list_create();
01590     if (caps->color_type & PCL_COLOR_CMYKcm)
01591     {
01592       description->deflt.str = ink_types[0].name;
01593       stp_string_list_add_string(description->bounds.str,
01594                                ink_types[0].name,_(ink_types[0].text));
01595       stp_string_list_add_string(description->bounds.str,
01596                                ink_types[1].name,_(ink_types[1].text));
01597     }
01598     else
01599       description->is_active = 0;
01600   }
01601   else if (strcmp(name, "CyanDensity") == 0 ||
01602            strcmp(name, "MagentaDensity") == 0 ||
01603            strcmp(name, "YellowDensity") == 0 ||
01604            strcmp(name, "BlackDensity") == 0)
01605     {
01606       if (caps->color_type != PCL_COLOR_NONE &&
01607           stp_check_string_parameter(v, "PrintingMode", STP_PARAMETER_DEFAULTED) &&
01608           strcmp(stp_get_string_parameter(v, "PrintingMode"), "Color") == 0)
01609         description->is_active = 1;
01610       else
01611         description->is_active = 0;
01612     }
01613   else if (strcmp(name, "LightCyanTransition") == 0 ||
01614            strcmp(name, "LightMagentaTransition") == 0)
01615     {
01616       if (caps->color_type & PCL_COLOR_CMYKcm &&
01617           stp_check_string_parameter(v, "PrintingMode", STP_PARAMETER_DEFAULTED) &&
01618           strcmp(stp_get_string_parameter(v, "PrintingMode"), "Color") == 0)
01619         description->is_active = 1;
01620       else
01621         description->is_active = 0;
01622     }
01623   else if (strcmp(name, "InkChannels") == 0)
01624     {
01625       if (caps->color_type & PCL_COLOR_CMYKcm)
01626         description->deflt.integer = 6;
01627       else if (caps->color_type == PCL_COLOR_NONE)
01628         description->deflt.integer = 1;
01629       else
01630         description->deflt.integer = 4;
01631       description->bounds.integer.lower = -1;
01632       description->bounds.integer.upper = -1;
01633     }
01634   else if (strcmp(name, "PrintingMode") == 0)
01635     {
01636       description->bounds.str = stp_string_list_create();
01637       if (caps->color_type != PCL_COLOR_NONE)
01638         stp_string_list_add_string
01639           (description->bounds.str, "Color", _("Color"));
01640       stp_string_list_add_string
01641         (description->bounds.str, "BW", _("Black and White"));
01642       description->deflt.str =
01643         stp_string_list_param(description->bounds.str, 0)->name;
01644     }
01645 }
01646 
01647 
01648 /*
01649  * 'pcl_imageable_area()' - Return the imageable area of the page.
01650  */
01651 static void
01652 internal_imageable_area(const stp_vars_t *v,     /* I */
01653                         int  use_paper_margins,
01654                         int  *left,     /* O - Left position in points */
01655                         int  *right,    /* O - Right position in points */
01656                         int  *bottom,   /* O - Bottom position in points */
01657                         int  *top)      /* O - Top position in points */
01658 {
01659   int   width, height;                  /* Size of page */
01660   const pcl_cap_t *caps;                /* Printer caps */
01661   int   pcl_media_size;                 /* Converted media size */
01662   const char *media_size = stp_get_string_parameter(v, "PageSize");
01663   const stp_papersize_t *pp = NULL;
01664   int left_margin = 0;
01665   int right_margin = 0;
01666   int bottom_margin = 0;
01667   int top_margin = 0;
01668 
01669   caps = pcl_get_model_capabilities(stp_get_model_id(v));
01670 
01671   stp_default_media_size(v, &width, &height);
01672 
01673 /* If we are using A4 paper, then the margins are different than any
01674  * other paper size. This is because HP wanted to have the same printable
01675  * width for A4 as for letter. Go figure.
01676  */
01677 
01678   if (!media_size)
01679     media_size = "";
01680   if (strlen(media_size) == 0 &&
01681       ((pp = stp_get_papersize_by_size(stp_get_page_height(v),
01682                                        stp_get_page_width(v))) != NULL))
01683     media_size = pp->name;
01684 
01685   stp_deprintf(STP_DBG_PCL, "pcl_imageable_area(): media_size: '%s'\n",
01686                media_size);
01687 
01688   pcl_media_size = pcl_convert_media_size(media_size, stp_get_model_id(v));
01689   if (media_size)
01690     pp = stp_get_papersize_by_name(media_size);
01691   if (pp && use_paper_margins)
01692     {
01693       left_margin = pp->left;
01694       right_margin = pp->right;
01695       bottom_margin = pp->bottom;
01696       top_margin = pp->top;
01697     }
01698 
01699   if (pcl_media_size == PCL_PAPERSIZE_A4)
01700   {
01701     left_margin = MAX(left_margin, caps->a4_margins.left_margin);
01702     right_margin = MAX(right_margin, caps->a4_margins.right_margin);
01703     top_margin = MAX(top_margin, caps->a4_margins.top_margin);
01704     bottom_margin = MAX(bottom_margin, caps->a4_margins.bottom_margin);
01705   }
01706   else
01707   {
01708     left_margin = MAX(left_margin, caps->normal_margins.left_margin);
01709     right_margin = MAX(right_margin, caps->normal_margins.right_margin);
01710     top_margin = MAX(top_margin, caps->normal_margins.top_margin);
01711     bottom_margin = MAX(bottom_margin, caps->normal_margins.bottom_margin);
01712   }
01713   *left =       left_margin;
01714   *right =      width - right_margin;
01715   *top =        top_margin;
01716   *bottom =     height - bottom_margin;
01717 }
01718 
01719 static void
01720 pcl_imageable_area(const stp_vars_t *v,     /* I */
01721                    int  *left,          /* O - Left position in points */
01722                    int  *right,         /* O - Right position in points */
01723                    int  *bottom,        /* O - Bottom position in points */
01724                    int  *top)           /* O - Top position in points */
01725 {
01726   internal_imageable_area(v, 1, left, right, bottom, top);
01727 }
01728 
01729 static void
01730 pcl_limit(const stp_vars_t *v,                  /* I */
01731           int *width,
01732           int *height,
01733           int *min_width,
01734           int *min_height)
01735 {
01736   const pcl_cap_t *caps= pcl_get_model_capabilities(stp_get_model_id(v));
01737   *width =      caps->custom_max_width;
01738   *height =     caps->custom_max_height;
01739   *min_width =  caps->custom_min_width;
01740   *min_height = caps->custom_min_height;
01741 }
01742 
01743 static const char *
01744 pcl_describe_output(const stp_vars_t *v)
01745 {
01746   int printing_color = 0;
01747   int model = stp_get_model_id(v);
01748   const pcl_cap_t *caps = pcl_get_model_capabilities(model);
01749   const char *print_mode = stp_get_string_parameter(v, "PrintingMode");
01750   int xdpi, ydpi;
01751 
01752   pcl_describe_resolution(v, &xdpi, &ydpi);
01753   if (!print_mode || strcmp(print_mode, "Color") == 0)
01754     printing_color = 1;
01755   if (((caps->resolutions & PCL_RES_600_600_MONO) == PCL_RES_600_600_MONO) &&
01756       printing_color && xdpi == 600 && ydpi == 600)
01757     printing_color = 0;
01758   if (printing_color)
01759     {
01760       if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY)
01761         return "CMY";
01762       else
01763         return "CMYK";
01764     }
01765   else
01766     return "Grayscale";
01767 }
01768 
01769 /*
01770  * 'pcl_print()' - Print an image to an HP printer.
01771  */
01772 
01773 static void
01774 pcl_printfunc(stp_vars_t *v)
01775 {
01776   pcl_privdata_t *pd = (pcl_privdata_t *) stp_get_component_data(v, "Driver");
01777   int do_blank = pd->do_blank;
01778   unsigned char *black = stp_dither_get_channel(v, STP_ECOLOR_K, 0);
01779   unsigned char *cyan = stp_dither_get_channel(v, STP_ECOLOR_C, 0);
01780   unsigned char *lcyan = stp_dither_get_channel(v, STP_ECOLOR_C, 1);
01781   unsigned char *magenta = stp_dither_get_channel(v, STP_ECOLOR_M, 0);
01782   unsigned char *lmagenta = stp_dither_get_channel(v, STP_ECOLOR_M, 1);
01783   unsigned char *yellow = stp_dither_get_channel(v, STP_ECOLOR_Y, 0);
01784   int len_c = stp_dither_get_last_position(v, STP_ECOLOR_C, 0);
01785   int len_lc = stp_dither_get_last_position(v, STP_ECOLOR_C, 1);
01786   int len_m = stp_dither_get_last_position(v, STP_ECOLOR_M, 0);
01787   int len_lm = stp_dither_get_last_position(v, STP_ECOLOR_M, 1);
01788   int len_y = stp_dither_get_last_position(v, STP_ECOLOR_Y, 0);
01789   int len_k = stp_dither_get_last_position(v, STP_ECOLOR_K, 0);
01790   int is_blank = (do_blank && (len_c == -1) && (len_lc == -1) &&
01791                   (len_m == -1) && (len_lm == -1) && (len_y == -1) &&
01792                   (len_k == -1));
01793   int height = pd->height;
01794   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
01795 
01796   if (is_blank && (pd->blank_lines != 0))       /* repeated blank line */
01797     {
01798       pd->blank_lines++;
01799     }
01800   else                          /* Not blank, or is first one */
01801     {
01802       if (! is_blank)
01803         {
01804           if (pd->blank_lines > 1)              /* Output accumulated lines */
01805             {
01806               pd->blank_lines--;                /* correct for one already output */
01807               stp_deprintf(STP_DBG_PCL, "Blank Lines = %d\n", pd->blank_lines);
01808               stp_zprintf(v, "\033*b%dY", pd->blank_lines);
01809               pd->blank_lines=0;
01810             }
01811           else;
01812         }
01813       else
01814         {
01815           pd->blank_lines++;
01816         }
01817 
01818       if (pd->do_cret)
01819         {
01820           /*
01821            * 4-level (CRet) dithers...
01822            */
01823           if (strcmp(print_mode, "BW") == 0)
01824             {
01825               (*(pd->writefunc))(v, black + height / 2, height / 2, 0);
01826               (*(pd->writefunc))(v, black, height / 2, 1);
01827             }
01828           else
01829             {
01830               if(pd->do_cretb)
01831                 {
01832                   /*        (*(pd->writefunc))(v, black + height / 2, 0, 0); */
01833                   (*(pd->writefunc))(v, black, height/2, 0);
01834                 }
01835               else
01836                 {
01837                   (*(pd->writefunc))(v, black + height / 2, height / 2, 0);
01838                   (*(pd->writefunc))(v, black, height / 2, 0);
01839                 }
01840               (*(pd->writefunc))(v, cyan + height / 2, height / 2, 0);
01841               (*(pd->writefunc))(v, cyan, height / 2, 0);
01842               (*(pd->writefunc))(v, magenta + height / 2, height / 2, 0);
01843               (*(pd->writefunc))(v, magenta, height / 2, 0);
01844               (*(pd->writefunc))(v, yellow + height / 2, height / 2, 0);
01845               if (pd->do_6color)
01846                 {
01847                   (*(pd->writefunc))(v, yellow, height / 2, 0);
01848                   (*(pd->writefunc))(v, lcyan + height / 2, height / 2, 0);
01849                   (*(pd->writefunc))(v, lcyan, height / 2, 0);
01850                   (*(pd->writefunc))(v, lmagenta + height / 2, height / 2, 0);
01851                   (*(pd->writefunc))(v, lmagenta, height / 2, 1);               /* Last plane set on light magenta */
01852                 }
01853               else
01854                 (*(pd->writefunc))(v, yellow, height / 2, 1);           /* Last plane set on yellow */
01855             }
01856         }
01857       else
01858         {
01859           /*
01860            * Standard 2-level dithers...
01861            */
01862 
01863           if (strcmp(print_mode, "BW") == 0)
01864             {
01865               (*(pd->writefunc))(v, black, height, 1);
01866             }
01867           else
01868             {
01869               if (black != NULL)
01870                 (*(pd->writefunc))(v, black, height, 0);
01871               (*(pd->writefunc))(v, cyan, height, 0);
01872               (*(pd->writefunc))(v, magenta, height, 0);
01873               if (pd->do_6color)
01874                 {
01875                   (*(pd->writefunc))(v, yellow, height, 0);
01876                   (*(pd->writefunc))(v, lcyan, height, 0);
01877                   (*(pd->writefunc))(v, lmagenta, height, 1);           /* Last plane set on light magenta */
01878                 }
01879               else
01880                 (*(pd->writefunc))(v, yellow, height, 1);               /* Last plane set on yellow */
01881             }
01882         }
01883     }
01884 }
01885 
01886 static double
01887 get_double_param(stp_vars_t *v, const char *param)
01888 {
01889   if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE))
01890     return stp_get_float_parameter(v, param);
01891   else
01892     return 1.0;
01893 }
01894 
01895 static int
01896 pcl_do_print(stp_vars_t *v, stp_image_t *image)
01897 {
01898   int i;
01899   pcl_privdata_t privdata;
01900   int           status = 1;
01901   int           model = stp_get_model_id(v);
01902   const char    *resolution = stp_get_string_parameter(v, "Resolution");
01903   const char    *media_size = stp_get_string_parameter(v, "PageSize");
01904   const char    *media_type = stp_get_string_parameter(v, "MediaType");
01905   const char    *media_source = stp_get_string_parameter(v, "InputSlot");
01906   const char    *ink_type = stp_get_string_parameter(v, "InkType");
01907   const char    *print_mode = stp_get_string_parameter(v, "PrintingMode");
01908   int printing_color = 0;
01909   int           top = stp_get_top(v);
01910   int           left = stp_get_left(v);
01911   int           y;              /* Looping vars */
01912   int           xdpi, ydpi;     /* Resolution */
01913   unsigned char *black,         /* Black bitmap data */
01914                 *cyan,          /* Cyan bitmap data */
01915                 *magenta,       /* Magenta bitmap data */
01916                 *yellow,        /* Yellow bitmap data */
01917                 *lcyan,         /* Light Cyan bitmap data */
01918                 *lmagenta;      /* Light Magenta bitmap data */
01919   int           page_width,     /* Width of page */
01920                 page_height,    /* Height of page */
01921                 page_left,
01922                 page_top,
01923                 page_right,
01924                 page_bottom,
01925                 out_width,      /* Width of image on page */
01926                 out_height,     /* Height of image on page */
01927                 out_channels,   /* Output bytes per pixel */
01928                 errdiv,         /* Error dividend */
01929                 errmod,         /* Error modulus */
01930                 errval,         /* Current error value */
01931                 errline,        /* Current raster line */
01932                 errlast;        /* Last raster line loaded */
01933   unsigned      zero_mask;
01934   int           image_height,
01935                 image_width;
01936   const pcl_cap_t *caps;                /* Printer capabilities */
01937   int           planes = 3;     /* # of output planes */
01938   int           pcl_media_size, /* PCL media size code */
01939                 pcl_media_type, /* PCL media type code */
01940                 pcl_media_source;       /* PCL media source code */
01941   const double *dot_sizes_use;
01942   const stp_papersize_t *pp;
01943   int           the_top_margin, /* Corrected top margin */
01944                 the_left_margin;        /* Corrected left margin */
01945   stp_curve_t   *lum_adjustment;
01946   stp_curve_t   *hue_adjustment;
01947   double density;
01948 
01949   if (!stp_verify(v))
01950     {
01951       stp_eprintf(v, "Print options not verified; cannot print.\n");
01952       return 0;
01953     }
01954   if (strcmp(print_mode, "Color") == 0)
01955     printing_color = 1;
01956 
01957   caps = pcl_get_model_capabilities(model);
01958 
01959  /*
01960   * Setup a read-only pixel region for the entire image...
01961   */
01962 
01963   stp_image_init(image);
01964   image_height = stp_image_height(image);
01965   image_width = stp_image_width(image);
01966 
01967  /*
01968   * Figure out the output resolution...
01969   */
01970 
01971   xdpi = 0;
01972   ydpi = 0;
01973   if (resolution)
01974     {
01975       for (i = 0; i < NUM_RESOLUTIONS; i++)
01976         {
01977           if (!strcmp(resolution, pcl_resolutions[i].pcl_name))
01978             {
01979               xdpi = pcl_resolutions[i].p0;
01980               ydpi = pcl_resolutions[i].p1;
01981               break;
01982             }
01983         }
01984     }
01985 
01986   stp_deprintf(STP_DBG_PCL,"pcl: resolution=%dx%d\n",xdpi,ydpi);
01987   if (xdpi == 0 || ydpi == 0)
01988     return 0;
01989 
01990  /*
01991   * Choose the correct color conversion function...
01992   */
01993   if (((caps->resolutions & PCL_RES_600_600_MONO) == PCL_RES_600_600_MONO) &&
01994       printing_color && xdpi == 600 && ydpi == 600)
01995     {
01996       stp_eprintf(v, "600x600 resolution only available in MONO\n");
01997       stp_set_string_parameter(v, "PrintingMode", "BW");
01998       printing_color = 0;
01999     }
02000 
02001   privdata.do_cret = (xdpi >= 300 &&
02002              ((caps->color_type & PCL_COLOR_CMYK4) == PCL_COLOR_CMYK4));
02003   privdata.do_cretb = (xdpi >= 600 && ydpi >= 600 &&
02004               ((caps->color_type & PCL_COLOR_CMYK4b) == PCL_COLOR_CMYK4b) &&
02005               printing_color);
02006   if (privdata.do_cretb){
02007     privdata.do_cret = 1;
02008     dot_sizes_use=dot_sizes_cret;
02009   }else{
02010     dot_sizes_use=dot_sizes;
02011   }
02012 
02013   stp_deprintf(STP_DBG_PCL, "privdata.do_cret = %d\n", privdata.do_cret);
02014   stp_deprintf(STP_DBG_PCL, "privdata.do_cretb = %d\n", privdata.do_cretb);
02015 
02016   if (ink_type)
02017     privdata.do_6color = (strcmp(ink_type, "Photo") == 0);
02018   else
02019     privdata.do_6color = 0;
02020 
02021   stp_deprintf(STP_DBG_PCL, "privdata.do_6color = %d\n", privdata.do_6color);
02022 
02023  /*
02024   * Compute the output size...
02025   */
02026 
02027   out_width = stp_get_width(v);
02028   out_height = stp_get_height(v);
02029 
02030   internal_imageable_area(v, 0, &page_left, &page_right,
02031                           &page_bottom, &page_top);
02032   left -= page_left;
02033   top -= page_top;
02034   page_width = page_right - page_left;
02035   page_height = page_bottom - page_top;
02036 
02037   image_height = stp_image_height(image);
02038   image_width = stp_image_width(image);
02039 
02040  /*
02041   * Send PCL initialization commands...
02042   */
02043 
02044   if (privdata.do_cretb)
02045     {
02046       stp_puts("\033*rbC", v);  /* End raster graphics */
02047     }
02048   stp_puts("\033E", v);                                 /* PCL reset */
02049   if (privdata.do_cretb)
02050     {
02051       stp_zprintf(v, "\033%%-12345X@PJL ENTER LANGUAGE=PCL3GUI\n");
02052     }
02053 
02054  /*
02055   * Set media size
02056   */
02057 
02058   if (!media_size)
02059     media_size = "";
02060   if (strlen(media_size) == 0 &&
02061       ((pp = stp_get_papersize_by_size(stp_get_page_height(v),
02062                                        stp_get_page_width(v))) != NULL))
02063     media_size = pp->name;
02064 
02065   pcl_media_size = pcl_convert_media_size(media_size, model);
02066 
02067   stp_deprintf(STP_DBG_PCL,"pcl_media_size = %d, media_size = %s\n", pcl_media_size, media_size);
02068 
02069  /*
02070   * If the media size requested is unknown, try it as a custom size.
02071   *
02072   * Warning: The margins may need to be fixed for this!
02073   */
02074 
02075   if (pcl_media_size == -1) {
02076     stp_deprintf(STP_DBG_PCL, "Paper size %s is not directly supported by printer.\n",
02077       media_size);
02078     stp_deprintf(STP_DBG_PCL, "Trying as custom pagesize (watch the margins!)\n");
02079     pcl_media_size = PCL_PAPERSIZE_CUSTOM;                      /* Custom */
02080   }
02081 
02082   stp_zprintf(v, "\033&l%dA", pcl_media_size);
02083 
02084   stp_puts("\033&l0L", v);                      /* Turn off perforation skip */
02085   stp_puts("\033&l0E", v);                      /* Reset top margin to 0 */
02086 
02087  /*
02088   * Convert media source string to the code, if specified.
02089   */
02090 
02091   if (media_source && strlen(media_source) != 0) {
02092     pcl_media_source = pcl_string_to_val(media_source, pcl_media_sources,
02093                          sizeof(pcl_media_sources) / sizeof(pcl_t));
02094 
02095     stp_deprintf(STP_DBG_PCL,"pcl_media_source = %d, media_source = %s\n", pcl_media_source,
02096            media_source);
02097 
02098     if (pcl_media_source == -1)
02099       stp_deprintf(STP_DBG_PCL, "Unknown media source %s, ignored.\n", media_source);
02100     else if (pcl_media_source != PCL_PAPERSOURCE_STANDARD) {
02101 
02102 /* Correct the value by taking the modulus */
02103 
02104       pcl_media_source = pcl_media_source % PAPERSOURCE_MOD;
02105       stp_zprintf(v, "\033&l%dH", pcl_media_source);
02106     }
02107   }
02108 
02109  /*
02110   * Convert media type string to the code, if specified.
02111   */
02112 
02113   if (media_type && strlen(media_type) != 0) {
02114     pcl_media_type = pcl_string_to_val(media_type, pcl_media_types,
02115                        sizeof(pcl_media_types) / sizeof(pcl_t));
02116 
02117     stp_deprintf(STP_DBG_PCL,"pcl_media_type = %d, media_type = %s\n", pcl_media_type,
02118            media_type);
02119 
02120     if (pcl_media_type == -1) {
02121       stp_deprintf(STP_DBG_PCL, "Unknown media type %s, set to PLAIN.\n", media_type);
02122       pcl_media_type = PCL_PAPERTYPE_PLAIN;
02123     }
02124 
02125 /*
02126  * The HP812C doesn't like glossy paper being selected when using 600x600
02127  * C-RET (PhotoRET II). So we use Premium paper instead.
02128  *
02129  */
02130 
02131     if (privdata.do_cretb && pcl_media_type == PCL_PAPERTYPE_GLOSSY) {
02132       stp_deprintf(STP_DBG_PCL, "Media type GLOSSY, set to PREMIUM for PhotoRET II.\n");
02133       pcl_media_type = PCL_PAPERTYPE_PREMIUM;
02134     }
02135   }
02136   else
02137     pcl_media_type = PCL_PAPERTYPE_PLAIN;
02138 
02139  /*
02140   * Set DJ print quality to "best" if resolution >= 300
02141   */
02142 
02143   if ((xdpi >= 300) && ((caps->stp_printer_type & PCL_PRINTER_DJ) == PCL_PRINTER_DJ))
02144   {
02145     if ((caps->stp_printer_type & PCL_PRINTER_MEDIATYPE) == PCL_PRINTER_MEDIATYPE)
02146     {
02147       stp_puts("\033*o1M", v);                  /* Quality = presentation */
02148       stp_zprintf(v, "\033&l%dM", pcl_media_type);
02149     }
02150     else
02151     {
02152       stp_puts("\033*r2Q", v);                  /* Quality (high) */
02153       stp_puts("\033*o2Q", v);                  /* Shingling (4 passes) */
02154 
02155  /* Depletion depends on media type and cart type. */
02156 
02157       if ((pcl_media_type == PCL_PAPERTYPE_PLAIN)
02158         || (pcl_media_type == PCL_PAPERTYPE_BOND)) {
02159       if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY)
02160           stp_puts("\033*o2D", v);                      /* Depletion 25% */
02161         else
02162           stp_puts("\033*o5D", v);                      /* Depletion 50% with gamma correction */
02163       }
02164 
02165       else if ((pcl_media_type == PCL_PAPERTYPE_PREMIUM)
02166              || (pcl_media_type == PCL_PAPERTYPE_GLOSSY)
02167              || (pcl_media_type == PCL_PAPERTYPE_TRANS))
02168         stp_puts("\033*o1D", v);                        /* Depletion none */
02169     }
02170   }
02171 
02172   if ((xdpi != ydpi) || (privdata.do_cret) || (privdata.do_6color))
02173                                                 /* Set resolution using CRD */
02174   {
02175 
02176    /*
02177     * Send configure image data command with horizontal and
02178     * vertical resolutions as well as a color count...
02179     */
02180 
02181     if (printing_color)
02182       if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY)
02183         planes = 3;
02184       else
02185         if (privdata.do_6color)
02186           planes = 6;
02187         else
02188           planes = 4;
02189     else
02190       planes = 1;
02191 
02192     stp_zprintf(v, "\033*g%dW", 2 + (planes * 6));
02193     stp_putc(2, v);                             /* Format 2 (Complex Direct Planar) */
02194     stp_putc(planes, v);                                /* # output planes */
02195 
02196     if (planes != 3) {          /* Black resolution */
02197       stp_send_command(v, "", "HHH", xdpi, ydpi, (privdata.do_cretb || !privdata.do_cret) ? 2 : 4);
02198     }
02199 
02200     if (planes != 1) {          /* Cyan, magenta, yellow resolutions */
02201       stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2);
02202       stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2);
02203       stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2);
02204     }
02205     if (planes == 6)            /* LC, LM resolutions */
02206     {
02207       stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2);
02208       stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2);
02209     }
02210   }
02211   else
02212   {
02213     stp_zprintf(v, "\033*t%dR", xdpi);          /* Simple resolution */
02214     if (printing_color)
02215     {
02216       if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY)
02217         stp_puts("\033*r-3U", v);               /* Simple CMY color */
02218       else
02219         stp_puts("\033*r-4U", v);               /* Simple KCMY color */
02220     }
02221   }
02222 
02223 #ifndef PCL_DEBUG_DISABLE_COMPRESSION
02224   if ((caps->stp_printer_type & PCL_PRINTER_TIFF) == PCL_PRINTER_TIFF)
02225   {
02226     stp_puts("\033*b2M", v);                    /* Mode 2 (TIFF) */
02227   }
02228   else
02229 #endif
02230   {
02231     stp_puts("\033*b0M", v);                    /* Mode 0 (no compression) */
02232   }
02233 
02234  /*
02235   * Convert image size to printer resolution and setup the page for printing...
02236   */
02237 
02238   out_width  = xdpi * out_width / 72;
02239   out_height = ydpi * out_height / 72;
02240 
02241   if (pcl_media_size == PCL_PAPERSIZE_A4)
02242   {
02243     the_left_margin = caps->a4_margins.left_margin;
02244     the_top_margin = caps->a4_margins.top_margin;
02245   }
02246   else
02247   {
02248     the_left_margin = caps->normal_margins.left_margin;
02249     the_top_margin = caps->normal_margins.top_margin;
02250   }
02251 
02252   stp_deprintf(STP_DBG_PCL, "left %d margin %d top %d margin %d width %d height %d\n",
02253           left, the_left_margin, top, the_top_margin, out_width, out_height);
02254 
02255   if (!privdata.do_cretb) {
02256     stp_zprintf(v, "\033&a%dH", 10 * left);             /* Set left raster position */
02257     stp_zprintf(v, "\033&a%dV", 10 * (top + the_top_margin));
02258                                 /* Set top raster position */
02259   }
02260   stp_zprintf(v, "\033*r%dS", out_width);               /* Set raster width */
02261   stp_zprintf(v, "\033*r%dT", out_height);      /* Set raster height */
02262 
02263   if (privdata.do_cretb)
02264     {
02265       /* Move to top left of printed area */
02266       stp_zprintf(v, "\033*p%dY", (top + the_top_margin)*4); /* Measured in dots. */
02267       stp_zprintf(v, "\033*p%dX", left*4);
02268     }
02269   stp_puts("\033*r1A", v);                      /* Start GFX */
02270 
02271  /*
02272   * Allocate memory for the raster data...
02273   */
02274 
02275   privdata.height = (out_width + 7) / 8;
02276   if (privdata.do_cret)
02277     privdata.height *= 2;
02278 
02279   if (!printing_color)
02280   {
02281     black   = stp_malloc(privdata.height);
02282     cyan    = NULL;
02283     magenta = NULL;
02284     yellow  = NULL;
02285     lcyan    = NULL;
02286     lmagenta = NULL;
02287   }
02288   else
02289   {
02290     cyan    = stp_malloc(privdata.height);
02291     magenta = stp_malloc(privdata.height);
02292     yellow  = stp_malloc(privdata.height);
02293 
02294     if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY)
02295       black = NULL;
02296     else
02297       black = stp_malloc(privdata.height);
02298     if (privdata.do_6color)
02299     {
02300       lcyan    = stp_malloc(privdata.height);
02301       lmagenta = stp_malloc(privdata.height);
02302     }
02303     else
02304     {
02305       lcyan    = NULL;
02306       lmagenta = NULL;
02307     }
02308   }
02309 
02310   if (black)
02311     {
02312       if (cyan)
02313         stp_set_string_parameter(v, "STPIOutputType", "KCMY");
02314       else
02315         stp_set_string_parameter(v, "STPIOutputType", "Grayscale");
02316     }
02317   else
02318     stp_set_string_parameter(v, "STPIOutputType", "CMY");
02319 
02320 /* Allocate buffer for pcl_mode2 tiff compression */
02321 
02322 #ifndef PCL_DEBUG_DISABLE_COMPRESSION
02323   if ((caps->stp_printer_type & PCL_PRINTER_TIFF) == PCL_PRINTER_TIFF)
02324   {
02325     privdata.comp_buf = stp_malloc((privdata.height + 128 + 7) * 129 / 128);
02326     privdata.writefunc = pcl_mode2;
02327   }
02328   else
02329 #endif
02330   {
02331     privdata.comp_buf = NULL;
02332     privdata.writefunc = pcl_mode0;
02333   }
02334 
02335 /* Set up dithering for special printers. */
02336 
02337 #if 1           /* Leave alone for now */
02338   if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE))
02339     stp_set_default_float_parameter(v, "GCRLower", .3);
02340   if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE))
02341     stp_set_default_float_parameter(v, "GCRUpper", .999);
02342 #endif
02343   stp_dither_init(v, image, out_width, xdpi, ydpi);
02344 
02345   if (black)
02346     stp_dither_add_channel(v, black, STP_ECOLOR_K, 0);
02347   if (cyan)
02348     stp_dither_add_channel(v, cyan, STP_ECOLOR_C, 0);
02349   if (lcyan)
02350     stp_dither_add_channel(v, lcyan, STP_ECOLOR_C, 1);
02351   if (magenta)
02352     stp_dither_add_channel(v, magenta, STP_ECOLOR_M, 0);
02353   if (lmagenta)
02354     stp_dither_add_channel(v, lmagenta, STP_ECOLOR_M, 1);
02355   if (yellow)
02356     stp_dither_add_channel(v, yellow, STP_ECOLOR_Y, 0);
02357 
02358 /* Ensure that density does not exceed 1.0 */
02359 
02360   if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED))
02361     {
02362       stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE);
02363       stp_set_float_parameter(v, "Density", 1.0);
02364     }
02365 
02366   stp_deprintf(STP_DBG_PCL, "Density: %f\n", stp_get_float_parameter(v, "Density"));
02367   if (stp_get_float_parameter(v, "Density") > 1.0)
02368     stp_set_float_parameter(v, "Density", 1.0);
02369   density = stp_get_float_parameter(v, "Density");
02370 
02371   if (privdata.do_cret)                 /* 4-level printing for 800/1120 */
02372     {
02373       stp_dither_set_inks_simple(v, STP_ECOLOR_Y, 3, dot_sizes_use, 1.0, 0.08);
02374       if (!privdata.do_cretb)
02375         stp_dither_set_inks_simple(v, STP_ECOLOR_K, 3, dot_sizes_use, 1.0, 1.0);
02376 
02377       /* Note: no printer I know of does both CRet (4-level) and 6 colour, but
02378          what the heck. variable_dither_ranges copied from print-escp2.c */
02379 
02380       if (privdata.do_6color)                   /* Photo for 69x */
02381         {
02382           stp_dither_set_inks_full(v, STP_ECOLOR_C, 6, variable_shades, 1.0,
02383                                     0.31 / .5);
02384           stp_dither_set_inks_full(v, STP_ECOLOR_M, 6, variable_shades, 1.0,
02385                                     0.61 / .97);
02386         }
02387       else
02388         {
02389           stp_dither_set_inks_simple(v, STP_ECOLOR_C, 3, dot_sizes_use, 1.0,
02390                                       0.31 / .5);
02391           stp_dither_set_inks_simple(v, STP_ECOLOR_M, 3, dot_sizes_use, 1.0,
02392                                       0.61 / .7);
02393         }
02394     }
02395   else if (privdata.do_6color)
02396     {
02397       /* Set light inks for 6 colour printers.
02398          Numbers copied from print-escp2.c */
02399       stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0,
02400                                 0.31 / .5);
02401       stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0,
02402                                 0.61 / .7);
02403     }
02404   if (black)
02405     stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0,
02406                                        get_double_param(v, "BlackDensity") *
02407                                        get_double_param(v, "Density"));
02408   if (cyan)
02409     stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0,
02410                                        get_double_param(v, "CyanDensity") *
02411                                        get_double_param(v, "Density"));
02412   if (magenta)
02413     stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0,
02414                                        get_double_param(v, "MagentaDensity") *
02415                                        get_double_param(v, "Density"));
02416   if (yellow)
02417     stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0,
02418                                         get_double_param(v, "YellowDensity") *
02419                                         get_double_param(v, "Density"));
02420   if (lcyan)
02421     stp_channel_set_density_adjustment
02422       (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") *
02423                         get_double_param(v, "LightCyanTransition") *
02424                         get_double_param(v, "Density")));
02425   if (lmagenta)
02426     stp_channel_set_density_adjustment
02427       (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") *
02428                         get_double_param(v, "LightMagentaTransition") *
02429                         get_double_param(v, "Density")));
02430 
02431 
02432   if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE))
02433     {
02434       hue_adjustment = stp_curve_create_from_string(standard_hue_adjustment);
02435       stp_set_curve_parameter(v, "HueMap", hue_adjustment);
02436       stp_curve_destroy(hue_adjustment);
02437     }
02438   if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE))
02439     {
02440       lum_adjustment = stp_curve_create_from_string(standard_lum_adjustment);
02441       stp_curve_destroy(lum_adjustment);
02442     }
02443 
02444   out_channels = stp_color_init(v, image, 65536);
02445 
02446   errdiv  = image_height / out_height;
02447   errmod  = image_height % out_height;
02448   errval  = 0;
02449   errlast = -1;
02450   errline  = 0;
02451   privdata.blank_lines = 0;
02452 #ifndef PCL_DEBUG_DISABLE_BLANKLINE_REMOVAL
02453   privdata.do_blank = ((caps->stp_printer_type & PCL_PRINTER_BLANKLINE) ==
02454                        PCL_PRINTER_BLANKLINE);
02455 #else
02456   privdata.do_blank = 0;
02457 #endif
02458   stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata);
02459 
02460   for (y = 0; y < out_height; y ++)
02461   {
02462     int duplicate_line = 1;
02463     if (errline != errlast)
02464     {
02465       errlast = errline;
02466       duplicate_line = 0;
02467       if (stp_color_get_row(v, image, errline, &zero_mask))
02468         {
02469           status = 2;
02470           break;
02471         }
02472     }
02473     stp_dither(v, y, duplicate_line, zero_mask, NULL);
02474     pcl_printfunc(v);
02475     stp_deprintf(STP_DBG_PCL,"pcl_print: y = %d, line = %d, val = %d, mod = %d, height = %d\n",
02476                   y, errline, errval, errmod, out_height);
02477     errval += errmod;
02478     errline += errdiv;
02479     if (errval >= out_height)
02480     {
02481       errval -= out_height;
02482       errline ++;
02483     }
02484   }
02485 
02486 /* Output trailing blank lines (may not be required?) */
02487 
02488   if (privdata.blank_lines > 1)
02489   {
02490     privdata.blank_lines--;             /* correct for one already output */
02491     stp_deprintf(STP_DBG_PCL, "Blank Lines = %d\n", privdata.blank_lines);
02492     stp_zprintf(v, "\033*b%dY", privdata.blank_lines);
02493     privdata.blank_lines=0;
02494   }
02495 
02496   stp_image_conclude(image);
02497 
02498  /*
02499   * Cleanup...
02500   */
02501 
02502   if (black != NULL)
02503     stp_free(black);
02504   if (cyan != NULL)
02505   {
02506     stp_free(cyan);
02507     stp_free(magenta);
02508     stp_free(yellow);
02509   }
02510   if (lcyan != NULL)
02511   {
02512     stp_free(lcyan);
02513     stp_free(lmagenta);
02514   }
02515 
02516   if (privdata.comp_buf != NULL)
02517     stp_free(privdata.comp_buf);
02518 
02519   if ((caps->stp_printer_type & PCL_PRINTER_NEW_ERG) == PCL_PRINTER_NEW_ERG)
02520     stp_puts("\033*rC", v);
02521   else
02522     stp_puts("\033*rB", v);
02523 
02524   stp_puts("\033&l0H", v);              /* Eject page */
02525   if (privdata.do_cretb)
02526     {
02527       stp_zprintf(v, "\033%%-12345X\n");
02528     }
02529   stp_puts("\033E", v);                                 /* PCL reset */
02530   return status;
02531 }
02532 
02533 static int
02534 pcl_print(const stp_vars_t *v, stp_image_t *image)
02535 {
02536   int status;
02537   stp_vars_t *nv = stp_vars_create_copy(v);
02538   stp_prune_inactive_options(nv);
02539   status = pcl_do_print(nv, image);
02540   stp_vars_destroy(nv);
02541   return status;
02542 }
02543 
02544 static const stp_printfuncs_t print_pcl_printfuncs =
02545 {
02546   pcl_list_parameters,
02547   pcl_parameters,
02548   stp_default_media_size,
02549   pcl_imageable_area,
02550   pcl_limit,
02551   pcl_print,
02552   pcl_describe_resolution,
02553   pcl_describe_output,
02554   stp_verify_printer_params,
02555   NULL,
02556   NULL
02557 };
02558 
02559 
02560 /*
02561  * 'pcl_mode0()' - Send PCL graphics using mode 0 (no) compression.
02562  */
02563 
02564 static void
02565 pcl_mode0(stp_vars_t *v,                /* I - Print file or command */
02566           unsigned char *line,          /* I - Output bitmap data */
02567           int           height,         /* I - Height of bitmap data */
02568           int           last_plane)     /* I - True if this is the last plane */
02569 {
02570   stp_zprintf(v, "\033*b%d%c", height, last_plane ? 'W' : 'V');
02571   stp_zfwrite((const char *) line, height, 1, v);
02572 }
02573 
02574 
02575 /*
02576  * 'pcl_mode2()' - Send PCL graphics using mode 2 (TIFF) compression.
02577  */
02578 
02579 static void
02580 pcl_mode2(stp_vars_t *v,                /* I - Print file or command */
02581           unsigned char *line,          /* I - Output bitmap data */
02582           int           height,         /* I - Height of bitmap data */
02583           int           last_plane)     /* I - True if this is the last plane */
02584 {
02585   pcl_privdata_t *privdata =
02586     (pcl_privdata_t *) stp_get_component_data(v, "Driver");
02587   unsigned char *comp_buf = privdata->comp_buf;
02588   unsigned char *comp_ptr;              /* Current slot in buffer */
02589 
02590   stp_pack_tiff(v, line, height, comp_buf, &comp_ptr, NULL, NULL);
02591 
02592  /*
02593   * Send a line of raster graphics...
02594   */
02595 
02596   stp_zprintf(v, "\033*b%d%c", (int)(comp_ptr - comp_buf), last_plane ? 'W' : 'V');
02597   stp_zfwrite((const char *)comp_buf, comp_ptr - comp_buf, 1, v);
02598 }
02599 
02600 
02601 static stp_family_t print_pcl_module_data =
02602   {
02603     &print_pcl_printfuncs,
02604     NULL
02605   };
02606 
02607 
02608 static int
02609 print_pcl_module_init(void)
02610 {
02611   return stp_family_register(print_pcl_module_data.printer_list);
02612 }
02613 
02614 
02615 static int
02616 print_pcl_module_exit(void)
02617 {
02618   return stp_family_unregister(print_pcl_module_data.printer_list);
02619 }
02620 
02621 
02622 /* Module header */
02623 #define stp_module_version print_pcl_LTX_stp_module_version
02624 #define stp_module_data print_pcl_LTX_stp_module_data
02625 
02626 stp_module_version_t stp_module_version = {0, 0};
02627 
02628 stp_module_t stp_module_data =
02629   {
02630     "pcl",
02631     VERSION,
02632     "PCL family driver",
02633     STP_MODULE_CLASS_FAMILY,
02634     NULL,
02635     print_pcl_module_init,
02636     print_pcl_module_exit,
02637     (void *) &print_pcl_module_data
02638   };
02639 

Generated on Wed May 12 20:21:33 2004 for libgimpprint API Reference by doxygen1.2.17