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

src/main/print-pcl.c

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

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