1/* 2 * "$Id: print-pcl.c,v 1.160 2010/12/05 21:38:15 rlk Exp $" 3 * 4 * Print plug-in HP PCL driver for the GIMP. 5 * 6 * Copyright 1997-2000 Michael Sweet (mike@easysw.com), 7 * Robert Krawitz (rlk@alum.mit.edu) and 8 * Dave Hill (dave@minnie.demon.co.uk) 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 * for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 */ 24 25/* 26 * This file must include only standard C header files. The core code must 27 * compile on generic platforms that don't support glib, gimp, gtk, etc. 28 */ 29 30#ifdef HAVE_CONFIG_H 31#include <config.h> 32#endif 33#include <gutenprint/gutenprint.h> 34#include <gutenprint/gutenprint-intl-internal.h> 35#include "gutenprint-internal.h" 36#include <stdio.h> 37#include <string.h> 38 39/* #define DEBUG */ 40/* #define PCL_DEBUG_DISABLE_BLANKLINE_REMOVAL */ 41 42/* 43 * Local functions... 44 */ 45static void pcl_mode0(stp_vars_t *, unsigned char *, int, int); 46static void pcl_mode2(stp_vars_t *, unsigned char *, int, int); 47 48#ifndef MAX 49# define MAX(a, b) ((a) > (b) ? (a) : (b)) 50#endif /* !MAX */ 51 52typedef struct 53{ 54 int do_blank; 55 int blank_lines; 56 unsigned char *comp_buf; 57 void (*writefunc)(stp_vars_t *, unsigned char *, int, int); /* PCL output function */ 58 int do_cret; 59 int do_cretb; 60 int do_6color; 61 int height; 62 int duplex; 63 int tumble; 64 int use_crd; 65} pcl_privdata_t; 66 67/* 68 * Generic define for a name/value set 69 */ 70 71typedef struct 72{ 73 const char *pcl_name; 74 const char *pcl_text; 75 int pcl_code; 76 int p0; 77 int p1; 78} pcl_t; 79 80static const stp_dotsize_t single_dotsize[] = 81{ 82 { 0x1, 1.0 } 83}; 84 85static const stp_shade_t photo_dither_shades[] = 86{ 87 { 1.0000, 1, single_dotsize }, 88 { 0.3333, 1, single_dotsize }, 89}; 90 91/* 92 * Media size to PCL media size code table 93 * 94 * Note, you can force the list of papersizes given in the GUI to be only those 95 * supported by defining PCL_NO_CUSTOM_PAPERSIZES 96 */ 97 98/* #define PCL_NO_CUSTOM_PAPERSIZES */ 99 100#define PCL_PAPERSIZE_EXECUTIVE 1 101#define PCL_PAPERSIZE_LETTER 2 102#define PCL_PAPERSIZE_LEGAL 3 103#define PCL_PAPERSIZE_TABLOID 6 /* "Ledger" */ 104#define PCL_PAPERSIZE_STATEMENT 15 /* Called "Manual" in print-util */ 105#define PCL_PAPERSIZE_SUPER_B 16 /* Called "13x19" in print-util */ 106#define PCL_PAPERSIZE_A5 25 107#define PCL_PAPERSIZE_A4 26 108#define PCL_PAPERSIZE_A3 27 109#define PCL_PAPERSIZE_JIS_B5 45 110#define PCL_PAPERSIZE_JIS_B4 46 111#define PCL_PAPERSIZE_HAGAKI_CARD 71 112#define PCL_PAPERSIZE_OUFUKU_CARD 72 113#define PCL_PAPERSIZE_A6_CARD 73 114#define PCL_PAPERSIZE_4x6 74 115#define PCL_PAPERSIZE_5x8 75 116#define PCL_PAPERSIZE_3x5 78 117#define PCL_PAPERSIZE_MONARCH_ENV 80 118#define PCL_PAPERSIZE_COMMERCIAL10_ENV 81 119#define PCL_PAPERSIZE_DL_ENV 90 120#define PCL_PAPERSIZE_C5_ENV 91 121#define PCL_PAPERSIZE_C6_ENV 92 122#define PCL_PAPERSIZE_CUSTOM 101 /* Custom size */ 123#define PCL_PAPERSIZE_INVITATION_ENV 109 124#define PCL_PAPERSIZE_JAPANESE_3_ENV 110 125#define PCL_PAPERSIZE_JAPANESE_4_ENV 111 126#define PCL_PAPERSIZE_KAKU_ENV 113 127#define PCL_PAPERSIZE_HP_CARD 114 /* HP Greeting card!?? */ 128 129/* 130 * This data comes from the HP documentation "Deskjet 1220C and 1120C 131 * PCL reference guide 2.0, Nov 1999". NOTE: The first name *must* match 132 * those in print-util.c for the lookups to work properly! 133 * The long names are not used so they have been removed, the ones in 134 * print-util.c are used in the interface. 135 */ 136 137static const pcl_t pcl_media_sizes[] = 138{ 139 { "Executive", "notused", PCL_PAPERSIZE_EXECUTIVE}, /* US Exec (7.25 x 10.5 in) */ 140 { "Letter", "notused", PCL_PAPERSIZE_LETTER}, /* US Letter (8.5 x 11 in) */ 141 { "Legal", "notused", PCL_PAPERSIZE_LEGAL}, /* US Legal (8.5 x 14 in) */ 142 { "Tabloid", "notused", PCL_PAPERSIZE_TABLOID}, /* US Tabloid (11 x 17 in) */ 143 { "Statement", "notused", PCL_PAPERSIZE_STATEMENT}, /* US Manual/Statement (5.5 x 8.5 in) */ 144 { "SuperB", "notused", PCL_PAPERSIZE_SUPER_B}, /* US 13x19/Super B (13 x 19 in) */ 145 { "A5", "notused", PCL_PAPERSIZE_A5}, /* ISO/JIS A5 (148 x 210 mm) */ 146 { "A4", "notused", PCL_PAPERSIZE_A4}, /* ISO/JIS A4 (210 x 297 mm) */ 147 { "A3", "notused", PCL_PAPERSIZE_A3}, /* ISO/JIS A3 (297 x 420 mm) */ 148 { "B5", "notused", PCL_PAPERSIZE_JIS_B5}, /* JIS B5 (182 x 257 mm). */ 149 { "B4", "notused", PCL_PAPERSIZE_JIS_B4}, /* JIS B4 (257 x 364 mm). */ 150 { "w283h420", "notused", PCL_PAPERSIZE_HAGAKI_CARD}, /* Japanese Hagaki Card (100 x 148 mm) */ 151 { "w420h567", "notused", PCL_PAPERSIZE_OUFUKU_CARD}, /* Japanese Oufuku Card (148 x 200 mm) */ 152 { "A6", "notused", PCL_PAPERSIZE_A6_CARD}, /* ISO/JIS A6 card */ 153 { "w288h432", "notused", PCL_PAPERSIZE_4x6}, /* US Index card (4 x 6 in) */ 154 { "w360h576", "notused", PCL_PAPERSIZE_5x8}, /* US Index card (5 x 8 in) */ 155 { "w216h360", "notused", PCL_PAPERSIZE_3x5}, /* US Index card (3 x 5 in) */ 156 { "Monarch", "notused", PCL_PAPERSIZE_MONARCH_ENV}, /* Monarch Envelope (3 7/8 x 7 1/2 in) */ 157 { "COM10", "notused", PCL_PAPERSIZE_COMMERCIAL10_ENV}, /* US Commercial 10 Envelope (4.125 x 9.5 in) Portrait */ 158 { "DL", "notused", PCL_PAPERSIZE_DL_ENV}, /* DL envelope (110 x 220 mm) Portrait */ 159 { "C5", "notused", PCL_PAPERSIZE_C5_ENV}, /* C5 envelope (162 x 229 mm) */ 160 { "C6", "notused", PCL_PAPERSIZE_C6_ENV}, /* C6 envelope (114 x 162 mm) */ 161 { "w315h414", "notused", PCL_PAPERSIZE_INVITATION_ENV}, /* US A2 Invitation envelope (4 3/8 x 5 3/4 in) */ 162 { "w340h666", "notused", PCL_PAPERSIZE_JAPANESE_3_ENV}, /* Japanese Long Envelope #3 (120 x 235 mm) */ 163 { "w255h581", "notused", PCL_PAPERSIZE_JAPANESE_4_ENV}, /* Japanese Long Envelope #4 (90 x 205 mm) */ 164 { "w680h941", "notused", PCL_PAPERSIZE_KAKU_ENV}, /* Japanese Kaku Envelope (240 x 332.1 mm) */ 165/**** MRS: this size not supported by print-util funcs! ****/ 166 { "w612h792", "notused", PCL_PAPERSIZE_HP_CARD}, /* Hp greeting card */ 167}; 168#define NUM_PRINTER_PAPER_SIZES (sizeof(pcl_media_sizes) / sizeof(pcl_t)) 169 170/* 171 * Media type to code table 172 */ 173 174#define PCL_PAPERTYPE_PLAIN 0 175#define PCL_PAPERTYPE_BOND 1 176#define PCL_PAPERTYPE_PREMIUM 2 177#define PCL_PAPERTYPE_GLOSSY 3 /* or photo */ 178#define PCL_PAPERTYPE_TRANS 4 179#define PCL_PAPERTYPE_QPHOTO 5 /* Quick dry photo (2000 only) */ 180#define PCL_PAPERTYPE_QTRANS 6 /* Quick dry transparency (2000 only) */ 181 182static const pcl_t pcl_media_types[] = 183{ 184 { "Plain", N_ ("Plain"), PCL_PAPERTYPE_PLAIN}, 185 { "Bond", N_ ("Bond"), PCL_PAPERTYPE_BOND}, 186 { "Premium", N_ ("Premium"), PCL_PAPERTYPE_PREMIUM}, 187 { "Glossy", N_ ("Glossy Photo"), PCL_PAPERTYPE_GLOSSY}, 188 { "Transparency", N_ ("Transparency"), PCL_PAPERTYPE_TRANS}, 189 { "GlossyQD", N_ ("Quick-dry Photo"), PCL_PAPERTYPE_QPHOTO}, 190 { "TransparencyQD", N_ ("Quick-dry Transparency"), PCL_PAPERTYPE_QTRANS}, 191}; 192#define NUM_PRINTER_PAPER_TYPES (sizeof(pcl_media_types) / sizeof(pcl_t)) 193 194/* 195 * Media feed to code table. There are different names for the same code, 196 * so we encode them by adding "lumps" of "PAPERSOURCE_MOD". 197 * This is removed later to get back to the main codes. 198 */ 199 200#define PAPERSOURCE_MOD 16 201#define PAPERSOURCE_340_MOD (PAPERSOURCE_MOD) 202#define PAPERSOURCE_DJ_MOD (PAPERSOURCE_MOD << 1) 203#define PAPERSOURCE_ADJ_GUIDE (PAPERSOURCE_MOD << 2) 204 205#define PCL_PAPERSOURCE_STANDARD 0 /* Don't output code */ 206#define PCL_PAPERSOURCE_MANUAL 2 207#define PCL_PAPERSOURCE_MANUAL_ADJ (PCL_PAPERSOURCE_MANUAL + PAPERSOURCE_ADJ_GUIDE) 208#define PCL_PAPERSOURCE_ENVELOPE 3 /* Not used */ 209 210/* LaserJet types */ 211#define PCL_PAPERSOURCE_LJ_TRAY2 1 212#define PCL_PAPERSOURCE_LJ_TRAY3 4 213#define PCL_PAPERSOURCE_LJ_TRAY4 5 214#define PCL_PAPERSOURCE_LJ_TRAY1 8 215#define PCL_PAPERSOURCE_LJ_TRAY1_ADJ (PCL_PAPERSOURCE_LJ_TRAY1 + PAPERSOURCE_ADJ_GUIDE) 216#define PCL_PAPERSOURCE_LJ_TRAY2_ADJ (PCL_PAPERSOURCE_LJ_TRAY2 + PAPERSOURCE_ADJ_GUIDE) 217#define PCL_PAPERSOURCE_LJ_TRAY3_ADJ (PCL_PAPERSOURCE_LJ_TRAY3 + PAPERSOURCE_ADJ_GUIDE) 218#define PCL_PAPERSOURCE_LJ_TRAY4_ADJ (PCL_PAPERSOURCE_LJ_TRAY4 + PAPERSOURCE_ADJ_GUIDE) 219 220/* Deskjet 340 types */ 221#define PCL_PAPERSOURCE_340_PCSF (1 + PAPERSOURCE_340_MOD) 222 /* Portable sheet feeder for 340 */ 223#define PCL_PAPERSOURCE_340_DCSF (4 + PAPERSOURCE_340_MOD) 224 /* Desktop sheet feeder for 340 */ 225 226/* Other Deskjet types */ 227#define PCL_PAPERSOURCE_DJ_TRAY (1 + PAPERSOURCE_DJ_MOD) 228#define PCL_PAPERSOURCE_DJ_TRAY2 (4 + PAPERSOURCE_DJ_MOD) 229 /* Tray 2 for 2500 */ 230#define PCL_PAPERSOURCE_DJ_OPTIONAL (5 + PAPERSOURCE_DJ_MOD) 231 /* Optional source for 2500 */ 232#define PCL_PAPERSOURCE_DJ_AUTO (7 + PAPERSOURCE_DJ_MOD) 233 /* Autoselect for 2500 */ 234 235static const pcl_t pcl_media_sources[] = 236{ 237 { "Standard", N_ ("Standard"), PCL_PAPERSOURCE_STANDARD}, 238 { "Manual", N_ ("Manual"), PCL_PAPERSOURCE_MANUAL}, 239 { "ManualAdj", N_ ("Manual - Movable Guides"), PCL_PAPERSOURCE_MANUAL_ADJ}, 240/* {"Envelope", PCL_PAPERSOURCE_ENVELOPE}, */ 241 { "MultiPurposeAdj", N_ ("Tray 1 - Movable Guides"), PCL_PAPERSOURCE_LJ_TRAY1_ADJ}, 242 { "MultiPurpose", N_ ("Tray 1"), PCL_PAPERSOURCE_LJ_TRAY1}, 243 { "UpperAdj", N_ ("Tray 2 - Movable Guides"), PCL_PAPERSOURCE_LJ_TRAY2_ADJ}, 244 { "Upper", N_ ("Tray 2"), PCL_PAPERSOURCE_LJ_TRAY2}, 245 { "LowerAdj", N_ ("Tray 3 - Movable Guides"), PCL_PAPERSOURCE_LJ_TRAY3_ADJ}, 246 { "Lower", N_ ("Tray 3"), PCL_PAPERSOURCE_LJ_TRAY3}, 247 { "LargeCapacityAdj", N_ ("Tray 4 - Movable Guides"), PCL_PAPERSOURCE_LJ_TRAY4_ADJ}, 248 { "LargeCapacity", N_ ("Tray 4"), PCL_PAPERSOURCE_LJ_TRAY4}, 249 { "Portable", N_ ("Portable Sheet Feeder"), PCL_PAPERSOURCE_340_PCSF}, 250 { "Desktop", N_ ("Desktop Sheet Feeder"), PCL_PAPERSOURCE_340_DCSF}, 251 { "Tray", N_ ("Tray"), PCL_PAPERSOURCE_DJ_TRAY}, 252 { "Tray2", N_ ("Tray 2"), PCL_PAPERSOURCE_DJ_TRAY2}, 253 { "Optional", N_ ("Optional Source"), PCL_PAPERSOURCE_DJ_OPTIONAL}, 254 { "Auto", N_ ("Autoselect"), PCL_PAPERSOURCE_DJ_AUTO}, 255}; 256#define NUM_PRINTER_PAPER_SOURCES (sizeof(pcl_media_sources) / sizeof(pcl_t)) 257 258#define PCL_RES_150_150 1 259#define PCL_RES_300_300 2 260#define PCL_RES_600_300 4 /* DJ 600 series */ 261#define PCL_RES_600_600_MONO 8 /* DJ 600/800/1100/2000 b/w only */ 262#define PCL_RES_600_600 16 /* DJ 9xx/1220C/PhotoSmart */ 263#define PCL_RES_1200_600 32 /* DJ 9xx/1220C/PhotoSmart */ 264#define PCL_RES_2400_600 64 /* DJ 9xx/1220C/PhotoSmart */ 265 266static const pcl_t pcl_resolutions[] = 267{ 268 { "150dpi", N_("150x150 DPI"), PCL_RES_150_150, 150, 150}, 269 { "300dpi", N_("300x300 DPI"), PCL_RES_300_300, 300, 300}, 270 { "600x300dpi", N_("600x300 DPI"), PCL_RES_600_300, 600, 300}, 271 { "600mono", N_("600x600 DPI monochrome"), PCL_RES_600_600_MONO, 600, 600}, 272 { "600dpi", N_("600x600 DPI"), PCL_RES_600_600, 600, 600}, 273 { "1200x600dpi", N_("1200x600 DPI"), PCL_RES_1200_600, 1200, 600}, 274 { "2400x600dpi", N_("2400x600 DPI"), PCL_RES_2400_600, 2400, 600}, 275}; 276#define NUM_RESOLUTIONS (sizeof(pcl_resolutions) / sizeof (pcl_t)) 277 278static const pcl_t pcl_qualities[] = 279{ 280 { "Draft", N_("Draft"), PCL_RES_150_150, 150, 150}, 281 { "Standard", N_("Standard"), PCL_RES_300_300, 300, 300}, 282 { "High", N_("High"), PCL_RES_600_600, 600, 600}, 283 { "High", N_("Standard"), PCL_RES_600_300, 600, 300}, 284 { "Photo", N_("Photo"), PCL_RES_1200_600, 1200, 600}, 285 { "Photo", N_("Photo"), PCL_RES_2400_600, 2400, 600}, 286}; 287#define NUM_QUALITIES (sizeof(pcl_qualities) / sizeof (pcl_t)) 288 289typedef struct { 290 int top_margin; 291 int bottom_margin; 292 int left_margin; 293 int right_margin; 294} margins_t; 295 296/* 297 * Printer capability data 298 */ 299 300typedef struct { 301 int model; 302 int custom_max_width; 303 int custom_max_height; 304 int custom_min_width; 305 int custom_min_height; 306 int resolutions; 307 margins_t normal_margins; 308 margins_t a4_margins; 309 int color_type; /* 2 print head or one, 2 level or 4 */ 310 int stp_printer_type; /* Deskjet/Laserjet and quirks */ 311/* The paper size, paper type and paper source codes cannot be combined */ 312 const short *paper_sizes; /* Paper sizes */ 313 const short *paper_types; /* Paper types */ 314 const short *paper_sources; /* Paper sources */ 315 } pcl_cap_t; 316 317#define PCL_COLOR_NONE 0 318#define PCL_COLOR_CMY 1 /* One print head */ 319#define PCL_COLOR_CMYK 2 /* Two print heads */ 320#define PCL_COLOR_CMYK4 4 /* CRet printing */ 321#define PCL_COLOR_CMYKcm 8 /* CMY + Photo Cart */ 322#define PCL_COLOR_CMYK4b 16 /* CRet for HP840c */ 323 324#define PCL_PRINTER_LJ 1 325#define PCL_PRINTER_DJ 2 326#define PCL_PRINTER_NEW_ERG 4 /* use "\033*rC" to end raster graphics, 327 instead of "\033*rB" */ 328#define PCL_PRINTER_TIFF 8 /* Use TIFF compression */ 329#define PCL_PRINTER_MEDIATYPE 16 /* Use media type & print quality */ 330#define PCL_PRINTER_CUSTOM_SIZE 32 /* Custom sizes supported */ 331#define PCL_PRINTER_BLANKLINE 64 /* Blank line removal supported */ 332#define PCL_PRINTER_DUPLEX 128 /* Printer can have duplexer */ 333 334/* 335 * FIXME - the 520 shouldn't be lumped in with the 500 as it supports 336 * more paper sizes. 337 * 338 * The following models use depletion, raster quality and shingling:- 339 * 500, 500c, 510, 520, 550c, 560c. 340 * The rest use Media Type and Print Quality. 341 * 342 * This data comes from the HP documentation "Deskjet 1220C and 1120C 343 * PCL reference guide 2.0, Nov 1999". 344 */ 345 346static const short emptylist[] = 347{ 348 -1 349}; 350 351static const short standard_papersizes[] = 352{ 353 PCL_PAPERSIZE_EXECUTIVE, 354 PCL_PAPERSIZE_STATEMENT, 355 PCL_PAPERSIZE_LETTER, 356 PCL_PAPERSIZE_LEGAL, 357 PCL_PAPERSIZE_A4, 358 -1, 359}; 360 361static const short letter_only_papersizes[] = 362{ 363 PCL_PAPERSIZE_LETTER, 364 -1 365}; 366 367static const short letter_a4_papersizes[] = 368{ 369 PCL_PAPERSIZE_A4, 370 PCL_PAPERSIZE_LETTER, 371 -1 372}; 373 374static const short dj340_papersizes[] = 375{ 376 PCL_PAPERSIZE_EXECUTIVE, 377 PCL_PAPERSIZE_LETTER, 378 PCL_PAPERSIZE_LEGAL, 379 PCL_PAPERSIZE_A4, 380 -1, 381}; 382 383static const short dj400_papersizes[] = 384{ 385 PCL_PAPERSIZE_EXECUTIVE, 386 PCL_PAPERSIZE_LETTER, 387 PCL_PAPERSIZE_LEGAL, 388 PCL_PAPERSIZE_A4, 389 PCL_PAPERSIZE_JIS_B5, 390 -1, 391}; 392 393static const short dj500_papersizes[] = 394{ 395/* PCL_PAPERSIZE_EXECUTIVE, The 500 doesn't support this, the 520 does */ 396 PCL_PAPERSIZE_LETTER, 397 PCL_PAPERSIZE_LEGAL, 398 PCL_PAPERSIZE_A4, 399 PCL_PAPERSIZE_COMMERCIAL10_ENV, 400/* PCL_PAPERSIZE_DL_ENV, The 500 doesn't support this, the 520 does */ 401 -1, 402}; 403 404static const short dj540_papersizes[] = 405{ 406 PCL_PAPERSIZE_EXECUTIVE, 407 PCL_PAPERSIZE_LETTER, 408 PCL_PAPERSIZE_LEGAL, 409 PCL_PAPERSIZE_A4, 410 PCL_PAPERSIZE_A5, 411 PCL_PAPERSIZE_JIS_B5, 412 PCL_PAPERSIZE_HAGAKI_CARD, 413 PCL_PAPERSIZE_A6_CARD, 414 PCL_PAPERSIZE_4x6, 415 PCL_PAPERSIZE_5x8, 416 PCL_PAPERSIZE_COMMERCIAL10_ENV, 417 PCL_PAPERSIZE_DL_ENV, 418 PCL_PAPERSIZE_C6_ENV, 419 -1, 420}; 421 422static const short dj600_papersizes[] = 423{ 424 PCL_PAPERSIZE_EXECUTIVE, 425 PCL_PAPERSIZE_LETTER, 426 PCL_PAPERSIZE_LEGAL, 427 PCL_PAPERSIZE_A4, 428 PCL_PAPERSIZE_A5, 429 PCL_PAPERSIZE_HAGAKI_CARD, 430 PCL_PAPERSIZE_A6_CARD, 431 PCL_PAPERSIZE_4x6, 432 PCL_PAPERSIZE_5x8, 433 PCL_PAPERSIZE_COMMERCIAL10_ENV, 434 PCL_PAPERSIZE_DL_ENV, 435 PCL_PAPERSIZE_C6_ENV, 436 PCL_PAPERSIZE_INVITATION_ENV, 437 -1, 438}; 439 440static const short dj1220_papersizes[] = 441{ 442 PCL_PAPERSIZE_EXECUTIVE, 443 PCL_PAPERSIZE_LETTER, 444 PCL_PAPERSIZE_LEGAL, 445 PCL_PAPERSIZE_TABLOID, 446 PCL_PAPERSIZE_STATEMENT, 447 PCL_PAPERSIZE_SUPER_B, 448 PCL_PAPERSIZE_A5, 449 PCL_PAPERSIZE_A4, 450 PCL_PAPERSIZE_A3, 451 PCL_PAPERSIZE_JIS_B5, 452 PCL_PAPERSIZE_JIS_B4, 453 PCL_PAPERSIZE_HAGAKI_CARD, 454 PCL_PAPERSIZE_OUFUKU_CARD, 455 PCL_PAPERSIZE_A6_CARD, 456 PCL_PAPERSIZE_4x6, 457 PCL_PAPERSIZE_5x8, 458 PCL_PAPERSIZE_3x5, 459 PCL_PAPERSIZE_HP_CARD, 460 PCL_PAPERSIZE_MONARCH_ENV, 461 PCL_PAPERSIZE_COMMERCIAL10_ENV, 462 PCL_PAPERSIZE_DL_ENV, 463 PCL_PAPERSIZE_C5_ENV, 464 PCL_PAPERSIZE_C6_ENV, 465 PCL_PAPERSIZE_INVITATION_ENV, 466 PCL_PAPERSIZE_JAPANESE_3_ENV, 467 PCL_PAPERSIZE_JAPANESE_4_ENV, 468 PCL_PAPERSIZE_KAKU_ENV, 469 -1, 470}; 471 472static const short dj1100_papersizes[] = 473{ 474 PCL_PAPERSIZE_EXECUTIVE, 475 PCL_PAPERSIZE_LETTER, 476 PCL_PAPERSIZE_LEGAL, 477 PCL_PAPERSIZE_TABLOID, 478 PCL_PAPERSIZE_STATEMENT, 479 PCL_PAPERSIZE_SUPER_B, 480 PCL_PAPERSIZE_A5, 481 PCL_PAPERSIZE_A4, 482 PCL_PAPERSIZE_A3, 483 PCL_PAPERSIZE_JIS_B5, 484 PCL_PAPERSIZE_JIS_B4, 485 PCL_PAPERSIZE_HAGAKI_CARD, 486 PCL_PAPERSIZE_A6_CARD, 487 PCL_PAPERSIZE_4x6, 488 PCL_PAPERSIZE_5x8, 489 PCL_PAPERSIZE_COMMERCIAL10_ENV, 490 PCL_PAPERSIZE_DL_ENV, 491 PCL_PAPERSIZE_C6_ENV, 492 PCL_PAPERSIZE_INVITATION_ENV, 493 PCL_PAPERSIZE_JAPANESE_3_ENV, 494 PCL_PAPERSIZE_JAPANESE_4_ENV, 495 PCL_PAPERSIZE_KAKU_ENV, 496 -1, 497}; 498 499static const short dj1200_papersizes[] = 500{ 501 /* This printer is not mentioned in the Comparison tables, 502 so I'll just pick some likely sizes... */ 503 PCL_PAPERSIZE_EXECUTIVE, 504 PCL_PAPERSIZE_LETTER, 505 PCL_PAPERSIZE_LEGAL, 506 PCL_PAPERSIZE_A5, 507 PCL_PAPERSIZE_A4, 508 PCL_PAPERSIZE_4x6, 509 PCL_PAPERSIZE_5x8, 510 -1, 511}; 512 513static const short dj2000_papersizes[] = 514{ 515 PCL_PAPERSIZE_EXECUTIVE, 516 PCL_PAPERSIZE_LETTER, 517 PCL_PAPERSIZE_LEGAL, 518 PCL_PAPERSIZE_A5, 519 PCL_PAPERSIZE_A4, 520 PCL_PAPERSIZE_HAGAKI_CARD, 521 PCL_PAPERSIZE_A6_CARD, 522 PCL_PAPERSIZE_4x6, 523 PCL_PAPERSIZE_5x8, 524 PCL_PAPERSIZE_3x5, 525 PCL_PAPERSIZE_COMMERCIAL10_ENV, 526 PCL_PAPERSIZE_DL_ENV, 527 PCL_PAPERSIZE_C6_ENV, 528 PCL_PAPERSIZE_INVITATION_ENV, 529 -1, 530}; 531 532static const short dj2500_papersizes[] = 533{ 534 PCL_PAPERSIZE_EXECUTIVE, 535 PCL_PAPERSIZE_LETTER, 536 PCL_PAPERSIZE_LEGAL, 537 PCL_PAPERSIZE_TABLOID, 538 PCL_PAPERSIZE_STATEMENT, 539 PCL_PAPERSIZE_A5, 540 PCL_PAPERSIZE_A4, 541 PCL_PAPERSIZE_A3, 542 PCL_PAPERSIZE_JIS_B5, 543 PCL_PAPERSIZE_JIS_B4, 544 PCL_PAPERSIZE_HAGAKI_CARD, 545 PCL_PAPERSIZE_A6_CARD, 546 PCL_PAPERSIZE_4x6, 547 PCL_PAPERSIZE_5x8, 548 PCL_PAPERSIZE_COMMERCIAL10_ENV, 549 PCL_PAPERSIZE_DL_ENV, 550 -1, 551}; 552 553static const short ljsmall_papersizes[] = 554{ 555 PCL_PAPERSIZE_EXECUTIVE, 556 PCL_PAPERSIZE_STATEMENT, 557 PCL_PAPERSIZE_LETTER, 558 PCL_PAPERSIZE_LEGAL, 559 PCL_PAPERSIZE_A4, 560 PCL_PAPERSIZE_MONARCH_ENV, 561 PCL_PAPERSIZE_COMMERCIAL10_ENV, 562 PCL_PAPERSIZE_DL_ENV, 563 PCL_PAPERSIZE_C5_ENV, 564 PCL_PAPERSIZE_C6_ENV, 565 -1, 566}; 567 568static const short ljbig_papersizes[] = 569{ 570 PCL_PAPERSIZE_EXECUTIVE, 571 PCL_PAPERSIZE_STATEMENT, 572 PCL_PAPERSIZE_LETTER, 573 PCL_PAPERSIZE_LEGAL, 574 PCL_PAPERSIZE_TABLOID, 575 PCL_PAPERSIZE_SUPER_B, 576 PCL_PAPERSIZE_A5, 577 PCL_PAPERSIZE_A4, 578 PCL_PAPERSIZE_A3, 579 PCL_PAPERSIZE_JIS_B5, 580 PCL_PAPERSIZE_JIS_B4, /* Guess */ 581 PCL_PAPERSIZE_4x6, 582 PCL_PAPERSIZE_5x8, 583 PCL_PAPERSIZE_MONARCH_ENV, 584 PCL_PAPERSIZE_COMMERCIAL10_ENV, 585 PCL_PAPERSIZE_DL_ENV, 586 PCL_PAPERSIZE_C5_ENV, 587 PCL_PAPERSIZE_C6_ENV, 588 -1, 589}; 590 591static const short ljtabloid_papersizes[] = 592{ 593 PCL_PAPERSIZE_EXECUTIVE, 594 PCL_PAPERSIZE_STATEMENT, 595 PCL_PAPERSIZE_LETTER, 596 PCL_PAPERSIZE_LEGAL, 597 PCL_PAPERSIZE_TABLOID, 598 PCL_PAPERSIZE_A5, 599 PCL_PAPERSIZE_A4, 600 PCL_PAPERSIZE_A3, 601 PCL_PAPERSIZE_JIS_B5, 602 PCL_PAPERSIZE_JIS_B4, /* Guess */ 603 PCL_PAPERSIZE_4x6, 604 PCL_PAPERSIZE_5x8, 605 PCL_PAPERSIZE_MONARCH_ENV, 606 PCL_PAPERSIZE_COMMERCIAL10_ENV, 607 PCL_PAPERSIZE_DL_ENV, 608 PCL_PAPERSIZE_C5_ENV, 609 PCL_PAPERSIZE_C6_ENV, 610 -1, 611}; 612 613static const short basic_papertypes[] = 614{ 615 PCL_PAPERTYPE_PLAIN, 616 PCL_PAPERTYPE_BOND, 617 PCL_PAPERTYPE_PREMIUM, 618 PCL_PAPERTYPE_GLOSSY, 619 PCL_PAPERTYPE_TRANS, 620 -1, 621}; 622 623static const short new_papertypes[] = 624{ 625 PCL_PAPERTYPE_PLAIN, 626 PCL_PAPERTYPE_BOND, 627 PCL_PAPERTYPE_PREMIUM, 628 PCL_PAPERTYPE_GLOSSY, 629 PCL_PAPERTYPE_TRANS, 630 PCL_PAPERTYPE_QPHOTO, 631 PCL_PAPERTYPE_QTRANS, 632 -1, 633}; 634 635static const short laserjet_papersources[] = 636{ 637 PCL_PAPERSOURCE_STANDARD, 638 PCL_PAPERSOURCE_MANUAL_ADJ, 639 PCL_PAPERSOURCE_MANUAL, 640 PCL_PAPERSOURCE_LJ_TRAY1_ADJ, 641 PCL_PAPERSOURCE_LJ_TRAY1, 642 PCL_PAPERSOURCE_LJ_TRAY2_ADJ, 643 PCL_PAPERSOURCE_LJ_TRAY2, 644 PCL_PAPERSOURCE_LJ_TRAY3_ADJ, 645 PCL_PAPERSOURCE_LJ_TRAY3, 646 PCL_PAPERSOURCE_LJ_TRAY4_ADJ, 647 PCL_PAPERSOURCE_LJ_TRAY4, 648 -1, 649}; 650 651static const short dj340_papersources[] = 652{ 653 PCL_PAPERSOURCE_STANDARD, 654 PCL_PAPERSOURCE_MANUAL, 655 PCL_PAPERSOURCE_340_PCSF, 656 PCL_PAPERSOURCE_340_DCSF, 657 -1, 658}; 659 660static const short dj_papersources[] = 661{ 662 PCL_PAPERSOURCE_STANDARD, 663 PCL_PAPERSOURCE_MANUAL, 664 PCL_PAPERSOURCE_DJ_TRAY, 665 -1, 666}; 667 668static const short dj2500_papersources[] = 669{ 670 PCL_PAPERSOURCE_STANDARD, 671 PCL_PAPERSOURCE_MANUAL, 672 PCL_PAPERSOURCE_DJ_AUTO, 673 PCL_PAPERSOURCE_DJ_TRAY, 674 PCL_PAPERSOURCE_DJ_TRAY2, 675 PCL_PAPERSOURCE_DJ_OPTIONAL, 676 -1, 677}; 678 679static const short standard_papersources[] = 680{ 681 PCL_PAPERSOURCE_STANDARD, 682 -1 683}; 684 685static const pcl_cap_t pcl_model_capabilities[] = 686{ 687 /* Default/unknown printer - assume laserjet */ 688 { 0, 689 17 * 72 / 2, 14 * 72, /* Max paper size */ 690 1, 1, /* Min paper size */ 691 PCL_RES_150_150 | PCL_RES_300_300, /* Resolutions */ 692 {12, 12, 18, 18}, /* non-A4 Margins */ 693 {12, 12, 10, 10}, /* A4 Margins */ 694 PCL_COLOR_NONE, 695 PCL_PRINTER_LJ, 696 standard_papersizes, 697 emptylist, 698 emptylist, 699 }, 700 /* DesignJet 230/430 (monochrome ) */ 701 { 10230, 702 36 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 703 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 704 PCL_RES_300_300 | PCL_RES_600_600, 705 {49, 49, 15, 15}, 706 {49, 49, 15, 15}, 707 PCL_COLOR_NONE, 708 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 709 letter_a4_papersizes, 710 basic_papertypes, 711 standard_papersources, 712 }, 713 /* DesignJet 250C/450C/455CA/488CA */ 714 /* The "CA" versions have a "software RIP" but are the same hardware */ 715 { 10250, 716 36 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 717 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 718 PCL_RES_300_300 | PCL_RES_600_600_MONO, 719 {49, 49, 15, 15}, 720 {49, 49, 15, 15}, 721 PCL_COLOR_CMYK, 722 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 723 letter_a4_papersizes, 724 basic_papertypes, 725 standard_papersources, 726 }, 727 /* DesignJet 700 (monochrome) */ 728 { 10700, 729 36 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 730 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 731 PCL_RES_300_300 | PCL_RES_600_600, 732 {30, 30, 15, 15}, /* These margins are for sheet mode FIX */ 733 {30, 30, 15, 15}, 734 PCL_COLOR_NONE, 735 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 736 letter_a4_papersizes, 737 basic_papertypes, 738 standard_papersources, 739 }, 740 /* DesignJet 750C */ 741 { 10750, 742 36 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 743 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 744 PCL_RES_300_300 | PCL_RES_600_600_MONO, 745 {30, 30, 15, 15}, /* These margins are for roll mode FIX */ 746 {30, 30, 15, 15}, 747 PCL_COLOR_CMYK, 748 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 749 letter_a4_papersizes, 750 basic_papertypes, 751 standard_papersources, 752 }, 753 /* DesignJet 2000C/2500C (36" wide) */ 754 { 12500, /* Deskjet 2500 already has "2500" */ 755 36 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 756 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 757 PCL_RES_300_300 | PCL_RES_600_600_MONO, 758 {49, 49, 15, 15}, /* Check/Fix */ 759 {49, 49, 15, 15}, 760 PCL_COLOR_CMYK, 761 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 762 letter_a4_papersizes, 763 basic_papertypes, 764 standard_papersources, 765 }, 766 /* DesignJet 3000C/3500C (54" wide) */ 767 { 13500, /* Deskjet 2500 already has "2500" */ 768 54 * 72, 150 * 12 * 72, /* 150ft in roll mode, 64" in sheet */ 769 826 * 72 / 100, 583 * 72 / 100, /* 8.3" wide min in sheet mode */ 770 PCL_RES_300_300 | PCL_RES_600_600_MONO, 771 {49, 49, 15, 15}, /* Check/Fix */ 772 {49, 49, 15, 15}, 773 PCL_COLOR_CMYK, 774 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_NEW_ERG, 775 letter_a4_papersizes, 776 basic_papertypes, 777 standard_papersources, 778 }, 779 /* Deskjet 340 */ 780 { 340, 781 17 * 72 / 2, 14 * 72, 782 1, 1, /* Min paper size */ 783 PCL_RES_150_150 | PCL_RES_300_300, 784 {6, 48, 18, 18}, /* from bpd07933.pdf */ 785 {6, 48, 10, 11}, /* from bpd07933.pdf */ 786 PCL_COLOR_CMY, 787 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 788 dj340_papersizes, 789 basic_papertypes, 790 dj340_papersources, 791 }, 792 /* Deskjet 400 */ 793 { 400, 794 17 * 72 / 2, 14 * 72, 795 1, 1, /* Min paper size */ 796 PCL_RES_150_150 | PCL_RES_300_300, 797 {7, 41, 18, 18}, 798 {7, 41, 10, 10}, /* Check/Fix */ 799 PCL_COLOR_CMY, 800 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 801 dj400_papersizes, 802 basic_papertypes, 803 emptylist, 804 }, 805 /* Deskjet 500, 520. Lexmark 4076 */ 806 { 500, 807 17 * 72 / 2, 14 * 72, 808 1, 1, /* Min paper size */ 809 PCL_RES_150_150 | PCL_RES_300_300, 810 {7, 41, 18, 18}, 811 {7, 41, 10, 10}, /* Check/Fix */ 812 PCL_COLOR_NONE, 813 PCL_PRINTER_DJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 814 dj500_papersizes, 815 basic_papertypes, 816 dj_papersources, 817 }, 818 /* Deskjet 500C */ 819 { 501, 820 17 * 72 / 2, 14 * 72, 821 1, 1, /* Min paper size */ 822 PCL_RES_150_150 | PCL_RES_300_300, 823 {7, 33, 18, 18}, 824 {7, 33, 10, 10}, /* Check/Fix */ 825 PCL_COLOR_CMY, 826 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 827 dj500_papersizes, 828 basic_papertypes, 829 dj_papersources, 830 }, 831 /* Deskjet 540C */ 832 { 540, 833 17 * 72 / 2, 14 * 72, 834 1, 1, /* Min paper size */ 835 PCL_RES_150_150 | PCL_RES_300_300, 836 {7, 33, 18, 18}, 837 {7, 33, 10, 10}, /* Check/Fix */ 838 PCL_COLOR_CMY, 839 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 840 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 841 dj540_papersizes, 842 basic_papertypes, 843 dj_papersources, 844 }, 845 /* Deskjet 550C, 560C */ 846 { 550, 847 17 * 72 / 2, 14 * 72, 848 1, 1, /* Min paper size */ 849 PCL_RES_150_150 | PCL_RES_300_300, 850 {3, 33, 18, 18}, 851 {5, 33, 10, 10}, 852 PCL_COLOR_CMYK, 853 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 854/* The 550/560 support COM10 and DL envelope, but the control codes 855 are negative, indicating landscape mode. This needs thinking about! */ 856 dj340_papersizes, 857 basic_papertypes, 858 dj_papersources, 859 }, 860 /* Deskjet 600/600C */ 861 { 600, 862 17 * 72 / 2, 14 * 72, 863 5 * 72, 583 * 72 / 100, /* Min paper size */ 864 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600_MONO, 865 {0, 33, 18, 18}, 866 {0, 33, 10, 10}, /* Check/Fix */ 867 PCL_COLOR_CMY, 868 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 869 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 870 dj600_papersizes, 871 basic_papertypes, 872 emptylist, 873 }, 874 /* Deskjet 6xx series */ 875 { 601, 876 17 * 72 / 2, 14 * 72, 877 1, 1, /* Min paper size */ 878 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600_MONO, 879 {0, 33, 18, 18}, 880 {0, 33, 10, 10}, /* Check/Fix */ 881 PCL_COLOR_CMYK, 882 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 883 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 884 dj600_papersizes, 885 basic_papertypes, 886 emptylist, 887 }, 888 /* Deskjet 69x series (Photo Capable) */ 889 { 690, 890 17 * 72 / 2, 14 * 72, 891 1, 1, /* Min paper size */ 892 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600, 893 {0, 33, 18, 18}, 894 {0, 33, 10, 10}, /* Check/Fix */ 895 PCL_COLOR_CMYK | PCL_COLOR_CMYKcm, 896 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 897 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 898 dj600_papersizes, 899 basic_papertypes, 900 emptylist, 901 }, 902 /* Deskjet 850/855/870/890 (C-RET) */ 903 { 800, 904 17 * 72 / 2, 14 * 72, 905 1, 1, /* Min paper size */ 906 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600_MONO, 907 {3, 33, 18, 18}, 908 {5, 33, 10, 10}, 909 PCL_COLOR_CMYK | PCL_COLOR_CMYK4, 910 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 911 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 912 dj600_papersizes, 913 basic_papertypes, 914 emptylist, 915 }, 916 /* Deskjet 810C, 812C, 840C, 842C, 845C, 895C (C-RET) */ 917 { 840, 918 17 * 72 / 2, 14 * 72, 919 1, 1, /* Min paper size */ 920 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_300 | PCL_RES_600_600, 921 {0, 33, 18, 18}, 922 {0, 33, 10, 10}, /* Check/Fix */ 923 PCL_COLOR_CMYK | PCL_COLOR_CMYK4b, 924 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 925 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 926 dj600_papersizes, 927 basic_papertypes, 928 emptylist, 929 }, 930 /* Deskjet 900 series, 1220C, PhotoSmart P1000/P1100 */ 931 { 900, 932 17 * 72 / 2, 14 * 72, 933 1, 1, /* Min paper size */ 934 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600 /* | PCL_RES_1200_600 | PCL_RES_2400_600 */, 935 {3, 33, 18, 18}, 936 {5, 33, 10, 10}, /* Oliver Vecernik */ 937 PCL_COLOR_CMYK, 938 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 939 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE | PCL_PRINTER_DUPLEX, 940 dj600_papersizes, 941 basic_papertypes, 942 emptylist, 943 }, 944 /* Deskjet 1220C (or other large format 900) */ 945 { 901, 946 13 * 72, 19 * 72, 947 1, 1, /* Min paper size */ 948 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600 /* | PCL_RES_1200_600 | PCL_RES_2400_600 */, 949 {3, 33, 18, 18}, 950 {5, 33, 10, 10}, 951 PCL_COLOR_CMYK, 952 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 953 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 954 dj1220_papersizes, 955 basic_papertypes, 956 emptylist, 957 }, 958 /* Deskjet 1100C, 1120C */ 959 { 1100, 960 13 * 72, 19 * 72, 961 1, 1, /* Min paper size */ 962 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600_MONO, 963 {3, 33, 18, 18}, 964 {5, 33, 10, 10}, 965 PCL_COLOR_CMYK | PCL_COLOR_CMYK4, 966 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 967 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 968 dj1100_papersizes, 969 basic_papertypes, 970 dj_papersources, 971 }, 972 /* Deskjet 1200C */ 973 { 1200, 974 17 * 72 / 2, 14 * 72, 975 1, 1, /* Min paper size */ 976 PCL_RES_150_150 | PCL_RES_300_300, 977 {12, 12, 18, 18}, 978 {12, 12, 10, 10}, /* Check/Fix */ 979 PCL_COLOR_CMY, 980 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 981 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 982 dj1200_papersizes, 983 basic_papertypes, 984 dj_papersources, 985 }, 986 /* Deskjet 1600C */ 987 { 1600, 988 17 * 72 / 2, 14 * 72, 989 1, 1, /* Min paper size */ 990 PCL_RES_150_150 | PCL_RES_300_300, 991 {12, 12, 18, 18}, 992 {12, 12, 10, 10}, /* Check/Fix */ 993 PCL_COLOR_CMYK, 994 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 995 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 996 dj1200_papersizes, 997 basic_papertypes, 998 dj_papersources, 999 }, 1000 /* Deskjet 2000 */ 1001 { 2000, 1002 17 * 72 / 2, 14 * 72, 1003 1, 1, /* Min paper size */ 1004 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1005 {0, 35, 18, 18}, /* Michel Goraczko */ 1006 {0, 35, 10, 10}, /* Check/Fix */ 1007 PCL_COLOR_CMYK, 1008 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 1009 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 1010 dj2000_papersizes, 1011 new_papertypes, 1012 dj_papersources, 1013 }, 1014 /* Deskjet 2500 */ 1015 { 2500, 1016 13 * 72, 19 * 72, 1017 1, 1, /* Min paper size */ 1018 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1019 {12, 12, 18, 18}, 1020 {12, 12, 10, 10}, /* Check/Fix */ 1021 PCL_COLOR_CMYK, 1022 PCL_PRINTER_DJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_MEDIATYPE | 1023 PCL_PRINTER_CUSTOM_SIZE | PCL_PRINTER_BLANKLINE, 1024 dj2500_papersizes, 1025 new_papertypes, 1026 dj2500_papersources, 1027 }, 1028 /* LaserJet II series */ 1029 { 2, 1030 17 * 72 / 2, 14 * 72, 1031 1, 1, /* Min paper size */ 1032 PCL_RES_150_150 | PCL_RES_300_300, 1033 {12, 12, 18, 18}, 1034 {12, 12, 10, 10}, /* Check/Fix */ 1035 PCL_COLOR_NONE, 1036 PCL_PRINTER_LJ, 1037 ljsmall_papersizes, 1038 emptylist, 1039 laserjet_papersources, 1040 }, 1041 /* LaserJet IIP (TIFF but no blankline) */ 1042 { 21, 1043 17 * 72 / 2, 14 * 72, 1044 1, 1, /* Min paper size */ 1045 PCL_RES_150_150 | PCL_RES_300_300, 1046 {12, 12, 18, 18}, 1047 {12, 12, 10, 10}, /* Check/Fix */ 1048 PCL_COLOR_NONE, 1049 PCL_PRINTER_LJ | PCL_PRINTER_TIFF, 1050 ljsmall_papersizes, 1051 emptylist, 1052 laserjet_papersources, 1053 }, 1054 /* Some laser printers don't have expanded A4 margins */ 1055 { 22, 1056 17 * 72 / 2, 14 * 72, 1057 1, 1, /* Min paper size */ 1058 PCL_RES_150_150 | PCL_RES_300_300, 1059 {12, 12, 18, 18}, 1060 {12, 12, 18, 18}, /* Check/Fix */ 1061 PCL_COLOR_NONE, 1062 PCL_PRINTER_LJ, 1063 ljsmall_papersizes, 1064 emptylist, 1065 laserjet_papersources, 1066 }, 1067 /* PCL-4 with large paper */ 1068 { 23, 1069 13 * 72, 19 * 72, 1070 1, 1, /* Min paper size */ 1071 PCL_RES_150_150 | PCL_RES_300_300, 1072 {12, 12, 18, 18}, 1073 {12, 12, 10, 10}, /* Check/Fix */ 1074 PCL_COLOR_NONE, 1075 PCL_PRINTER_LJ, 1076 ljbig_papersizes, 1077 emptylist, 1078 laserjet_papersources, 1079 }, 1080 /* PCL-4 with large paper, no expanded A4 margins */ 1081 { 24, 1082 13 * 72, 19 * 72, 1083 1, 1, /* Min paper size */ 1084 PCL_RES_150_150 | PCL_RES_300_300, 1085 {12, 12, 18, 18}, 1086 {12, 12, 18, 18}, /* Check/Fix */ 1087 PCL_COLOR_NONE, 1088 PCL_PRINTER_LJ, 1089 ljbig_papersizes, 1090 emptylist, 1091 laserjet_papersources, 1092 }, 1093 /* LaserJet III series */ 1094 { 3, 1095 17 * 72 / 2, 14 * 72, 1096 1, 1, /* Min paper size */ 1097 PCL_RES_150_150 | PCL_RES_300_300, 1098 {12, 12, 18, 18}, 1099 {12, 12, 10, 10}, /* Check/Fix */ 1100 PCL_COLOR_NONE, 1101 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1102 ljsmall_papersizes, 1103 emptylist, 1104 laserjet_papersources, 1105 }, 1106 /* LaserJet III series */ 1107 { 31, 1108 17 * 72 / 2, 14 * 72, 1109 1, 1, /* Min paper size */ 1110 PCL_RES_150_150 | PCL_RES_300_300, 1111 {12, 12, 18, 18}, 1112 {12, 12, 10, 10}, /* Check/Fix */ 1113 PCL_COLOR_NONE, 1114 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1115 ljsmall_papersizes, 1116 emptylist, 1117 laserjet_papersources, 1118 }, 1119 /* Some laser printers don't have expanded A4 margins */ 1120 { 32, 1121 17 * 72 / 2, 14 * 72, 1122 1, 1, /* Min paper size */ 1123 PCL_RES_150_150 | PCL_RES_300_300, 1124 {12, 12, 18, 18}, 1125 {12, 12, 18, 18}, /* Check/Fix */ 1126 PCL_COLOR_NONE, 1127 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1128 ljsmall_papersizes, 1129 emptylist, 1130 laserjet_papersources, 1131 }, 1132 /* PCL-5 with large paper */ 1133 { 33, 1134 13 * 72, 19 * 72, 1135 1, 1, /* Min paper size */ 1136 PCL_RES_150_150 | PCL_RES_300_300, 1137 {12, 12, 18, 18}, 1138 {12, 12, 10, 10}, /* Check/Fix */ 1139 PCL_COLOR_NONE, 1140 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1141 ljbig_papersizes, 1142 emptylist, 1143 laserjet_papersources, 1144 }, 1145 /* PCL-5 with large paper, no expanded margins */ 1146 { 34, 1147 13 * 72, 19 * 72, 1148 1, 1, /* Min paper size */ 1149 PCL_RES_150_150 | PCL_RES_300_300, 1150 {12, 12, 18, 18}, 1151 {12, 12, 18, 18}, /* Check/Fix */ 1152 PCL_COLOR_NONE, 1153 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1154 ljbig_papersizes, 1155 emptylist, 1156 laserjet_papersources, 1157 }, 1158 /* PCL-5 with tabloid paper, no expanded margins */ 1159 { 35, 1160 118 * 72 / 10, 17 * 72, 1161 1, 1, /* Min paper size */ 1162 PCL_RES_150_150 | PCL_RES_300_300, 1163 {12, 12, 18, 18}, 1164 {12, 12, 18, 18}, /* Check/Fix */ 1165 PCL_COLOR_NONE, 1166 PCL_PRINTER_LJ | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1167 ljtabloid_papersizes, 1168 emptylist, 1169 laserjet_papersources, 1170 }, 1171 /* LaserJet 4L */ 1172 { 4, 1173 17 * 72 / 2, 14 * 72, 1174 1, 1, /* Min paper size */ 1175 PCL_RES_150_150 | PCL_RES_300_300, 1176 {12, 12, 18, 18}, 1177 {12, 12, 10, 10}, /* Check/Fix */ 1178 PCL_COLOR_NONE, 1179 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1180 ljsmall_papersizes, 1181 emptylist, 1182 laserjet_papersources, 1183 }, 1184 /* LaserJet 4V */ 1185 { 5, 1186 13 * 72, 19 * 72, 1187 1, 1, /* Min paper size */ 1188 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1189 {12, 12, 18, 18}, 1190 {12, 12, 10, 10}, /* Check/Fix */ 1191 PCL_COLOR_NONE, 1192 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE, 1193 ljbig_papersizes, 1194 emptylist, 1195 laserjet_papersources, 1196 }, 1197 /* LaserJet 4Si */ 1198 { 51, 1199 13 * 72, 19 * 72, 1200 1, 1, /* Min paper size */ 1201 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1202 {12, 12, 18, 18}, 1203 {12, 12, 10, 10}, /* Check/Fix */ 1204 PCL_COLOR_NONE, 1205 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1206 PCL_PRINTER_DUPLEX, 1207 ljbig_papersizes, 1208 emptylist, 1209 laserjet_papersources, 1210 }, 1211 /* LaserJet 4 series (except as above), 5 series, 6 series */ 1212 { 6, 1213 17 * 72 / 2, 14 * 72, 1214 1, 1, /* Min paper size */ 1215 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1216 {12, 12, 18, 18}, 1217 {12, 12, 10, 10}, /* Check/Fix */ 1218 PCL_COLOR_NONE, 1219 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1220 PCL_PRINTER_DUPLEX, 1221 ljsmall_papersizes, 1222 emptylist, 1223 laserjet_papersources, 1224 }, 1225 /* PCL-5c/5e/6/XL with large paper */ 1226 { 61, 1227 13 * 72, 19 * 72, 1228 1, 1, /* Min paper size */ 1229 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1230 {12, 12, 18, 18}, 1231 {12, 12, 10, 10}, /* Check/Fix */ 1232 PCL_COLOR_NONE, 1233 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1234 PCL_PRINTER_DUPLEX, 1235 ljbig_papersizes, 1236 emptylist, 1237 laserjet_papersources, 1238 }, 1239 /* Some laser printers don't have expanded A4 margins */ 1240 { 62, 1241 17 * 72 / 2, 14 * 72, 1242 1, 1, /* Min paper size */ 1243 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1244 {12, 12, 18, 18}, 1245 {12, 12, 18, 18}, /* Check/Fix */ 1246 PCL_COLOR_NONE, 1247 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1248 PCL_PRINTER_DUPLEX, 1249 ljsmall_papersizes, 1250 emptylist, 1251 laserjet_papersources, 1252 }, 1253 /* PCL-5c/5e/6/XL with large paper, no expanded A4 margins */ 1254 { 63, 1255 13 * 72, 19 * 72, 1256 1, 1, /* Min paper size */ 1257 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1258 {12, 12, 18, 18}, 1259 {12, 12, 18, 18}, /* Check/Fix */ 1260 PCL_COLOR_NONE, 1261 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1262 PCL_PRINTER_DUPLEX, 1263 ljbig_papersizes, 1264 emptylist, 1265 laserjet_papersources, 1266 }, 1267 /* PCL-5c/5e/6/XL with tabloid paper, no expanded A4 margins */ 1268 { 64, 1269 118 * 72 / 10, 17 * 72, 1270 1, 1, /* Min paper size */ 1271 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1272 {12, 12, 18, 18}, 1273 {12, 12, 18, 18}, /* Check/Fix */ 1274 PCL_COLOR_NONE, 1275 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1276 PCL_PRINTER_DUPLEX, 1277 ljtabloid_papersizes, 1278 emptylist, 1279 laserjet_papersources, 1280 }, 1281 /* LaserJet 5Si */ 1282 { 7, 1283 13 * 72, 19 * 72, 1284 1, 1, /* Min paper size */ 1285 PCL_RES_150_150 | PCL_RES_300_300 | PCL_RES_600_600, 1286 {12, 12, 18, 18}, 1287 {12, 12, 10, 10}, /* Check/Fix */ 1288 PCL_COLOR_NONE, 1289 PCL_PRINTER_LJ | PCL_PRINTER_NEW_ERG | PCL_PRINTER_TIFF | PCL_PRINTER_BLANKLINE | 1290 PCL_PRINTER_DUPLEX, 1291 ljbig_papersizes, 1292 emptylist, 1293 laserjet_papersources, 1294 }, 1295}; 1296 1297 1298static const char standard_sat_adjustment[] = 1299"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 1300"<gutenprint>\n" 1301"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n" 1302"<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n" 1303/* C */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* B */ 1304/* B */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* M */ 1305/* M */ "1.00 0.95 0.90 0.90 0.90 0.90 0.90 0.90 " /* R */ 1306/* R */ "0.90 0.95 0.95 1.00 1.00 1.00 1.00 1.00 " /* Y */ 1307/* Y */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* G */ 1308/* G */ "1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 " /* C */ 1309"</sequence>\n" 1310"</curve>\n" 1311"</gutenprint>\n"; 1312 1313static const char standard_lum_adjustment[] = 1314"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 1315"<gutenprint>\n" 1316"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n" 1317"<sequence count=\"48\" lower-bound=\"0\" upper-bound=\"4\">\n" 1318/* C */ "0.65 0.67 0.70 0.72 0.77 0.80 0.82 0.85 " /* B */ 1319/* B */ "0.87 0.86 0.82 0.79 0.79 0.82 0.85 0.88 " /* M */ 1320/* M */ "0.92 0.95 0.96 0.97 0.97 0.97 0.96 0.96 " /* R */ 1321/* R */ "0.96 0.97 0.97 0.98 0.99 1.00 1.00 1.00 " /* Y */ 1322/* Y */ "1.00 0.97 0.95 0.94 0.93 0.92 0.90 0.86 " /* G */ 1323/* G */ "0.79 0.76 0.71 0.68 0.68 0.68 0.68 0.66 " /* C */ 1324"</sequence>\n" 1325"</curve>\n" 1326"</gutenprint>\n"; 1327 1328static const char standard_hue_adjustment[] = 1329"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 1330"<gutenprint>\n" 1331"<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n" 1332"<sequence count=\"48\" lower-bound=\"-6\" upper-bound=\"6\">\n" 1333/* C */ "0.00 0.06 0.10 0.10 0.06 -.01 -.09 -.17 " /* B */ 1334/* B */ "-.25 -.33 -.38 -.38 -.36 -.34 -.34 -.34 " /* M */ 1335/* M */ "-.34 -.34 -.36 -.40 -.50 -.40 -.30 -.20 " /* R */ 1336/* R */ "-.12 -.07 -.04 -.02 0.00 0.00 0.00 0.00 " /* Y */ 1337/* Y */ "0.00 0.00 0.00 -.05 -.10 -.15 -.22 -.24 " /* G */ 1338/* G */ "-.26 -.30 -.33 -.28 -.25 -.20 -.13 -.06 " /* C */ 1339"</sequence>\n" 1340"</curve>\n" 1341"</gutenprint>\n"; 1342 1343static const stp_parameter_t the_parameters[] = 1344{ 1345 { 1346 "PageSize", N_("Page Size"), "Color=No,Category=Basic Printer Setup", 1347 N_("Size of the paper being printed to"), 1348 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE, 1349 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1350 }, 1351 { 1352 "MediaType", N_("Media Type"), "Color=Yes,Category=Basic Printer Setup", 1353 N_("Type of media (plain paper, photo paper, etc.)"), 1354 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1355 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1356 }, 1357 { 1358 "InputSlot", N_("Media Source"), "Color=No,Category=Basic Printer Setup", 1359 N_("Source (input slot) of the media"), 1360 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1361 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1362 }, 1363 { 1364 "Quality", N_("Print Quality"), "Color=Yes,Category=Basic Output Adjustment", 1365 N_("Print Quality"), 1366 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1367 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 0, 0 1368 }, 1369 { 1370 "Resolution", N_("Resolution"), "Color=Yes,Category=Basic Printer Setup", 1371 N_("Resolution of the print"), 1372 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1373 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1374 }, 1375 { 1376 "InkType", N_("Ink Type"), "Color=Yes,Category=Advanced Printer Setup", 1377 N_("Type of ink in the printer"), 1378 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1379 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1380 }, 1381 { 1382 "InkChannels", N_("Ink Channels"), "Color=Yes,Category=Advanced Printer Functionality", 1383 N_("Ink Channels"), 1384 STP_PARAMETER_TYPE_INT, STP_PARAMETER_CLASS_FEATURE, 1385 STP_PARAMETER_LEVEL_INTERNAL, 0, 0, STP_CHANNEL_NONE, 0, 0 1386 }, 1387 { 1388 "PrintingMode", N_("Printing Mode"), "Color=Yes,Category=Core Parameter", 1389 N_("Printing Output Mode"), 1390 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_CORE, 1391 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1392 }, 1393 { 1394 "Duplex", N_("Double-Sided Printing"), "Color=No,Category=Basic Printer Setup", 1395 N_("Duplex/Tumble Setting"), 1396 STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_FEATURE, 1397 STP_PARAMETER_LEVEL_BASIC, 1, 1, STP_CHANNEL_NONE, 1, 0 1398 }, 1399}; 1400 1401static const int the_parameter_count = 1402sizeof(the_parameters) / sizeof(const stp_parameter_t); 1403 1404typedef struct 1405{ 1406 const stp_parameter_t param; 1407 double min; 1408 double max; 1409 double defval; 1410 int color_only; 1411} float_param_t; 1412 1413static const float_param_t float_parameters[] = 1414{ 1415 { 1416 { 1417 "CyanDensity", N_("Cyan Density"), "Color=Yes,Category=Output Level Adjustment", 1418 N_("Adjust the cyan density"), 1419 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1420 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 1, 1, 0 1421 }, 0.0, 2.0, 1.0, 1 1422 }, 1423 { 1424 { 1425 "MagentaDensity", N_("Magenta Density"), "Color=Yes,Category=Output Level Adjustment", 1426 N_("Adjust the magenta density"), 1427 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1428 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 2, 1, 0 1429 }, 0.0, 2.0, 1.0, 1 1430 }, 1431 { 1432 { 1433 "YellowDensity", N_("Yellow Density"), "Color=Yes,Category=Output Level Adjustment", 1434 N_("Adjust the yellow density"), 1435 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1436 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 3, 1, 0 1437 }, 0.0, 2.0, 1.0, 1 1438 }, 1439 { 1440 { 1441 "BlackDensity", N_("Black Density"), "Color=Yes,Category=Output Level Adjustment", 1442 N_("Adjust the black density"), 1443 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1444 STP_PARAMETER_LEVEL_ADVANCED, 0, 1, 0, 1, 0 1445 }, 0.0, 2.0, 1.0, 1 1446 }, 1447 { 1448 { 1449 "LightCyanTrans", N_("Light Cyan Transition"), "Color=Yes,Category=Advanced Ink Adjustment", 1450 N_("Light Cyan Transition"), 1451 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1452 STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0 1453 }, 0.0, 5.0, 1.0, 1 1454 }, 1455 { 1456 { 1457 "LightMagentaTrans", N_("Light Magenta Transition"), "Color=Yes,Category=Advanced Ink Adjustment", 1458 N_("Light Magenta Transition"), 1459 STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT, 1460 STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, STP_CHANNEL_NONE, 1, 0 1461 }, 0.0, 5.0, 1.0, 1 1462 }, 1463}; 1464 1465static const int float_parameter_count = 1466sizeof(float_parameters) / sizeof(const float_param_t); 1467 1468/* 1469 * Convert a name into it's option value 1470 */ 1471 1472static int pcl_string_to_val(const char *string, /* I: String */ 1473 const pcl_t *options, /* I: Options */ 1474 int num_options) /* I: Num options */ 1475{ 1476 1477 int i; 1478 int code = -1; 1479 1480 /* 1481 * Look up the string in the table and convert to the code. 1482 */ 1483 1484 for (i=0; i<num_options; i++) { 1485 if (!strcmp(string, options[i].pcl_name)) { 1486 code=options[i].pcl_code; 1487 break; 1488 } 1489 } 1490 1491 stp_deprintf(STP_DBG_PCL, "String: %s, Code: %d\n", string, code); 1492 1493 return(code); 1494} 1495 1496/* 1497 * Convert a value into it's option name 1498 */ 1499 1500static const char * pcl_val_to_string(int code, /* I: Code */ 1501 const pcl_t *options, /* I: Options */ 1502 int num_options) /* I: Num options */ 1503{ 1504 1505 int i; 1506 const char *string = NULL; 1507 1508 /* 1509 * Look up the code in the table and convert to the string. 1510 */ 1511 1512 for (i=0; i<num_options; i++) { 1513 if (code == options[i].pcl_code) { 1514 string=options[i].pcl_name; 1515 break; 1516 } 1517 } 1518 1519 stp_deprintf(STP_DBG_PCL, "Code: %d, String: %s\n", code, string); 1520 1521 return(string); 1522} 1523 1524static const char * pcl_val_to_text(int code, /* I: Code */ 1525 const pcl_t *options, /* I: Options */ 1526 int num_options) /* I: Num options */ 1527{ 1528 1529 int i; 1530 const char *string = NULL; 1531 1532 /* 1533 * Look up the code in the table and convert to the string. 1534 */ 1535 1536 for (i=0; i<num_options; i++) { 1537 if (code == options[i].pcl_code) { 1538 string=gettext(options[i].pcl_text); 1539 break; 1540 } 1541 } 1542 1543 stp_deprintf(STP_DBG_PCL, "Code: %d, String: %s\n", code, string); 1544 1545 return(string); 1546} 1547 1548static const double dot_sizes[] = { 0.5, 0.832, 1.0 }; 1549static const double dot_sizes_cret[] = { 1.0, 1.0, 1.0 }; 1550 1551static const stp_dotsize_t variable_dotsizes[] = 1552{ 1553 { 0x1, 0.5 }, 1554 { 0x2, 0.67 }, 1555 { 0x3, 1.0 } 1556}; 1557 1558static const stp_shade_t variable_shades[] = 1559{ 1560 { 0.38, 3, variable_dotsizes }, 1561 { 1.0, 3, variable_dotsizes } 1562}; 1563 1564/* 1565 * pcl_get_model_capabilities() - Return struct of model capabilities 1566 */ 1567 1568static const pcl_cap_t * /* O: Capabilities */ 1569pcl_get_model_capabilities(int model) /* I: Model */ 1570{ 1571 int i; 1572 int models= sizeof(pcl_model_capabilities) / sizeof(pcl_cap_t); 1573 for (i=0; i<models; i++) { 1574 if (pcl_model_capabilities[i].model == model) { 1575 return &(pcl_model_capabilities[i]); 1576 } 1577 } 1578 stp_erprintf("pcl: model %d not found in capabilities list.\n",model); 1579 return &(pcl_model_capabilities[0]); 1580} 1581 1582/* 1583 * Determine the current resolution based on quality and resolution settings 1584 */ 1585 1586static void 1587pcl_describe_resolution(const stp_vars_t *v, int *x, int *y) 1588{ 1589 int i; 1590 int model = stp_get_model_id(v); 1591 const char *resolution = stp_get_string_parameter(v, "Resolution"); 1592 const char *quality; 1593 const pcl_cap_t *caps = NULL; 1594 if (resolution) 1595 { 1596 for (i = 0; i < NUM_RESOLUTIONS; i++) 1597 { 1598 if (!strcmp(resolution, pcl_resolutions[i].pcl_name)) 1599 { 1600 *x = pcl_resolutions[i].p0; 1601 *y = pcl_resolutions[i].p1; 1602 return; 1603 } 1604 } 1605 } 1606 quality = stp_get_string_parameter(v, "Quality"); 1607 caps = pcl_get_model_capabilities(model); 1608 if (quality && strcmp(quality, "None") == 0) 1609 quality = "Standard"; 1610 if (quality) 1611 { 1612 for (i = 0; i < NUM_QUALITIES; i++) 1613 { 1614 if ((caps->resolutions & pcl_qualities[i].pcl_code) && 1615 !strcmp(quality, pcl_qualities[i].pcl_name)) 1616 { 1617 *x = pcl_qualities[i].p0; 1618 *y = pcl_qualities[i].p1; 1619 return; 1620 } 1621 } 1622 } 1623 *x = -1; 1624 *y = -1; 1625} 1626 1627/* 1628 * Convert Media size name into PCL media code for printer 1629 */ 1630 1631static int pcl_convert_media_size(const char *media_size, /* I: Media size string */ 1632 int model) /* I: model number */ 1633{ 1634 1635 int i; 1636 int media_code = 0; 1637 const pcl_cap_t *caps; 1638 1639 /* 1640 * First look up the media size in the table and convert to the code. 1641 */ 1642 1643 media_code = pcl_string_to_val(media_size, pcl_media_sizes, 1644 NUM_PRINTER_PAPER_SIZES); 1645 1646 stp_deprintf(STP_DBG_PCL, "Media Size: %s, Code: %d\n", media_size, media_code); 1647 1648 /* 1649 * Now see if the printer supports the code found. 1650 */ 1651 1652 if (media_code != -1) { 1653 caps = pcl_get_model_capabilities(model); 1654 1655 for (i=0; (i<NUM_PRINTER_PAPER_SIZES) && (caps->paper_sizes[i] != -1); i++) { 1656 if (media_code == (int) caps->paper_sizes[i]) 1657 return(media_code); /* Is supported */ 1658 } 1659 1660 stp_deprintf(STP_DBG_PCL, "Media Code %d not supported by printer model %d.\n", 1661 media_code, model); 1662 return(-1); /* Not supported */ 1663 } 1664 else 1665 return(-1); /* Not supported */ 1666} 1667 1668 1669static const stp_param_string_t ink_types[] = 1670{ 1671 { "CMYK", N_ ("Color + Black Cartridges") }, 1672 { "Photo", N_ ("Color + Photo Cartridges") } 1673}; 1674 1675/* 1676 * Duplex support - modes available 1677 * Note that the internal names MUST match those in cups/genppd.c else the 1678 * PPD files will not be generated correctly 1679 */ 1680 1681static const stp_param_string_t duplex_types[] = 1682{ 1683 { "None", N_ ("Off") }, 1684 { "DuplexNoTumble", N_ ("Long Edge (Standard)") }, 1685 { "DuplexTumble", N_ ("Short Edge (Flip)") } 1686}; 1687#define NUM_DUPLEX (sizeof (duplex_types) / sizeof (stp_param_string_t)) 1688 1689/* 1690 * 'pcl_papersize_valid()' - Is the paper size valid for this printer. 1691 */ 1692 1693static int 1694pcl_papersize_valid(const stp_papersize_t *pt, 1695 int model) 1696{ 1697 1698 const pcl_cap_t *caps = pcl_get_model_capabilities(model); 1699 1700#ifdef PCL_NO_CUSTOM_PAPERSIZES 1701 int use_custom = 0; 1702#else 1703 int use_custom = ((caps->stp_printer_type & PCL_PRINTER_CUSTOM_SIZE) 1704 == PCL_PRINTER_CUSTOM_SIZE); 1705#endif 1706 1707 unsigned int pwidth = pt->width; 1708 unsigned int pheight = pt->height; 1709 1710/* 1711 * This function decides whether a paper size is allowed for the 1712 * current printer. The DeskJet feed mechanisms set a minimum and 1713 * maximum size for the paper, BUT some of the directly supported 1714 * media sizes are less than this minimum (eg card and envelopes) 1715 * So, we allow supported sizes though, but clamp custom sizes 1716 * to the min and max sizes. 1717 */ 1718 1719/* 1720 * Is it a valid name? 1721 */ 1722 1723 if (strlen(pt->name) <= 0) 1724 return(0); 1725 1726/* 1727 * Is it a recognised supported name? 1728 */ 1729 1730 if (pcl_convert_media_size(pt->name, model) != -1) 1731 return(1); 1732 1733/* 1734 * If we are not allowed to use custom paper sizes, we are done 1735 */ 1736 1737 if (use_custom == 0) 1738 return(0); 1739 1740/* 1741 * We are allowed custom paper sizes. Check that the size is within 1742 * limits. 1743 */ 1744 1745 if (pwidth <= caps->custom_max_width && 1746 pheight <= caps->custom_max_height && 1747 (pheight >= caps->custom_min_height || pheight == 0) && 1748 (pwidth >= caps->custom_min_width || pwidth == 0)) 1749 return(1); 1750 1751 return(0); 1752} 1753 1754/* 1755 * 'pcl_parameters()' - Return the parameter values for the given parameter. 1756 */ 1757 1758static stp_parameter_list_t 1759pcl_list_parameters(const stp_vars_t *v) 1760{ 1761 stp_parameter_list_t *ret = stp_parameter_list_create(); 1762 int i; 1763 for (i = 0; i < the_parameter_count; i++) 1764 stp_parameter_list_add_param(ret, &(the_parameters[i])); 1765 for (i = 0; i < float_parameter_count; i++) 1766 stp_parameter_list_add_param(ret, &(float_parameters[i].param)); 1767 return ret; 1768} 1769 1770static void 1771pcl_parameters(const stp_vars_t *v, const char *name, 1772 stp_parameter_t *description) 1773{ 1774 int model = stp_get_model_id(v); 1775 int i; 1776 const pcl_cap_t *caps; 1777 description->p_type = STP_PARAMETER_TYPE_INVALID; 1778 1779 if (name == NULL) 1780 return; 1781 1782 stp_deprintf(STP_DBG_PCL, "pcl_parameters(): Name = %s\n", name); 1783 1784 caps = pcl_get_model_capabilities(model); 1785 1786 stp_deprintf(STP_DBG_PCL, "Printer model = %d\n", model); 1787 stp_deprintf(STP_DBG_PCL, "PageWidth = %d, PageHeight = %d\n", caps->custom_max_width, caps->custom_max_height); 1788 stp_deprintf(STP_DBG_PCL, "MinPageWidth = %d, MinPageHeight = %d\n", caps->custom_min_width, caps->custom_min_height); 1789 stp_deprintf(STP_DBG_PCL, "Normal Margins: top = %d, bottom = %d, left = %d, right = %d\n", 1790 caps->normal_margins.top_margin, caps->normal_margins.bottom_margin, 1791 caps->normal_margins.left_margin, caps->normal_margins.right_margin); 1792 stp_deprintf(STP_DBG_PCL, "A4 Margins: top = %d, bottom = %d, left = %d, right = %d\n", 1793 caps->a4_margins.top_margin, caps->a4_margins.bottom_margin, 1794 caps->a4_margins.left_margin, caps->a4_margins.right_margin); 1795 stp_deprintf(STP_DBG_PCL, "Resolutions: %d\n", caps->resolutions); 1796 stp_deprintf(STP_DBG_PCL, "ColorType = %d, PrinterType = %d\n", caps->color_type, caps->stp_printer_type); 1797 1798 for (i = 0; i < the_parameter_count; i++) 1799 if (strcmp(name, the_parameters[i].name) == 0) 1800 { 1801 stp_fill_parameter_settings(description, &(the_parameters[i])); 1802 break; 1803 } 1804 description->deflt.str = NULL; 1805 1806 for (i = 0; i < float_parameter_count; i++) 1807 if (strcmp(name, float_parameters[i].param.name) == 0) 1808 { 1809 stp_fill_parameter_settings(description, 1810 &(float_parameters[i].param)); 1811 description->deflt.dbl = float_parameters[i].defval; 1812 description->bounds.dbl.upper = float_parameters[i].max; 1813 description->bounds.dbl.lower = float_parameters[i].min; 1814 break; 1815 } 1816 1817 if (strcmp(name, "PageSize") == 0) 1818 { 1819 int papersizes = stp_known_papersizes(); 1820 description->bounds.str = stp_string_list_create(); 1821 for (i = 0; i < papersizes; i++) 1822 { 1823 const stp_papersize_t *pt = stp_get_papersize_by_index(i); 1824 if (strlen(pt->name) > 0 && pcl_papersize_valid(pt, model)) 1825 stp_string_list_add_string(description->bounds.str, 1826 pt->name, gettext(pt->text)); 1827 } 1828 description->deflt.str = 1829 stp_string_list_param(description->bounds.str, 0)->name; 1830 } 1831 else if (strcmp(name, "MediaType") == 0) 1832 { 1833 description->bounds.str = stp_string_list_create(); 1834 if (caps->paper_types[0] != -1) 1835 { 1836 for (i=0; (i < NUM_PRINTER_PAPER_TYPES) && (caps->paper_types[i] != -1); i++) 1837 stp_string_list_add_string(description->bounds.str, 1838 pcl_val_to_string(caps->paper_types[i], 1839 pcl_media_types, 1840 NUM_PRINTER_PAPER_TYPES), 1841 pcl_val_to_text(caps->paper_types[i], 1842 pcl_media_types, 1843 NUM_PRINTER_PAPER_TYPES)); 1844 description->deflt.str = 1845 stp_string_list_param(description->bounds.str, 0)->name; 1846 } 1847 else 1848 description->is_active = 0; 1849 } 1850 else if (strcmp(name, "InputSlot") == 0) 1851 { 1852 description->bounds.str = stp_string_list_create(); 1853 if (caps->paper_sources[0] != -1) 1854 { 1855 for (i=0; (i < NUM_PRINTER_PAPER_SOURCES) && (caps->paper_sources[i] != -1); i++) 1856 stp_string_list_add_string(description->bounds.str, 1857 pcl_val_to_string(caps->paper_sources[i], 1858 pcl_media_sources, 1859 NUM_PRINTER_PAPER_SOURCES), 1860 pcl_val_to_text(caps->paper_sources[i], 1861 pcl_media_sources, 1862 NUM_PRINTER_PAPER_SOURCES)); 1863 description->deflt.str = 1864 stp_string_list_param(description->bounds.str, 0)->name; 1865 } 1866 else 1867 description->is_active = 0; 1868 } 1869 else if (strcmp(name, "Resolution") == 0) 1870 { 1871 description->bounds.str = stp_string_list_create(); 1872 stp_string_list_add_string(description->bounds.str, "None", _("Default")); 1873 description->deflt.str = "None"; 1874 for (i = 0; i < NUM_RESOLUTIONS; i++) 1875 if (caps->resolutions & pcl_resolutions[i].pcl_code) 1876 { 1877 stp_string_list_add_string 1878 (description->bounds.str, 1879 pcl_val_to_string(pcl_resolutions[i].pcl_code, 1880 pcl_resolutions, NUM_RESOLUTIONS), 1881 pcl_val_to_text(pcl_resolutions[i].pcl_code, 1882 pcl_resolutions, NUM_RESOLUTIONS)); 1883 } 1884 } 1885 else if (strcmp(name, "Quality") == 0) 1886 { 1887 int has_standard_quality = 0; 1888 description->bounds.str = stp_string_list_create(); 1889 stp_string_list_add_string(description->bounds.str, "None", 1890 _("Manual Control")); 1891 for (i = 0; i < NUM_QUALITIES; i++) 1892 if (caps->resolutions & pcl_qualities[i].pcl_code) 1893 { 1894 const char *qual = 1895 pcl_val_to_string(pcl_qualities[i].pcl_code, 1896 pcl_qualities, NUM_QUALITIES); 1897 if (! stp_string_list_is_present(description->bounds.str, qual)) 1898 stp_string_list_add_string 1899 (description->bounds.str, qual, 1900 pcl_val_to_text(pcl_qualities[i].pcl_code, 1901 pcl_qualities, NUM_QUALITIES)); 1902 if (strcmp(qual, "Standard") == 0) 1903 has_standard_quality = 1; 1904 } 1905 if (has_standard_quality) 1906 description->deflt.str = "Standard"; 1907 else 1908 description->deflt.str = "None"; 1909 } 1910 else if (strcmp(name, "InkType") == 0) 1911 { 1912 description->bounds.str = stp_string_list_create(); 1913 if (caps->color_type & PCL_COLOR_CMYKcm) 1914 { 1915 description->deflt.str = ink_types[0].name; 1916 stp_string_list_add_string(description->bounds.str, 1917 ink_types[0].name,gettext(ink_types[0].text)); 1918 stp_string_list_add_string(description->bounds.str, 1919 ink_types[1].name,gettext(ink_types[1].text)); 1920 } 1921 else 1922 description->is_active = 0; 1923 } 1924 else if (strcmp(name, "Duplex") == 0) 1925 { 1926 int offer_duplex=0; 1927 1928 description->bounds.str = stp_string_list_create(); 1929 1930/* 1931 * Don't offer the Duplex/Tumble options if the JobMode parameter is 1932 * set to "Page" Mode. 1933 * "Page" mode is set by the Gimp Plugin, which only outputs one page at a 1934 * time, so Duplex/Tumble is meaningless. 1935 */ 1936 1937 if (stp_get_string_parameter(v, "JobMode")) 1938 offer_duplex = strcmp(stp_get_string_parameter(v, "JobMode"), "Page"); 1939 else 1940 offer_duplex=1; 1941 1942 if (offer_duplex) 1943 { 1944 if (caps->stp_printer_type & PCL_PRINTER_DUPLEX) 1945 { 1946 description->deflt.str = duplex_types[0].name; 1947 for (i=0; i < NUM_DUPLEX; i++) 1948 { 1949 stp_string_list_add_string(description->bounds.str, 1950 duplex_types[i].name,gettext(duplex_types[i].text)); 1951 } 1952 } 1953 else 1954 description->is_active = 0; /* Not supported by printer */ 1955 } 1956 else 1957 description->is_active = 0; /* Not in "Job" mode */ 1958 } 1959 else if (strcmp(name, "CyanDensity") == 0 || 1960 strcmp(name, "MagentaDensity") == 0 || 1961 strcmp(name, "YellowDensity") == 0 || 1962 strcmp(name, "BlackDensity") == 0) 1963 { 1964 if (caps->color_type != PCL_COLOR_NONE && 1965 stp_check_string_parameter(v, "PrintingMode", STP_PARAMETER_DEFAULTED) && 1966 strcmp(stp_get_string_parameter(v, "PrintingMode"), "Color") == 0) 1967 description->is_active = 1; 1968 else 1969 description->is_active = 0; 1970 } 1971 else if (strcmp(name, "LightCyanTrans") == 0 || 1972 strcmp(name, "LightMagentaTrans") == 0) 1973 { 1974 if (caps->color_type & PCL_COLOR_CMYKcm && 1975 stp_check_string_parameter(v, "PrintingMode", STP_PARAMETER_DEFAULTED) && 1976 strcmp(stp_get_string_parameter(v, "PrintingMode"), "Color") == 0) 1977 description->is_active = 1; 1978 else 1979 description->is_active = 0; 1980 } 1981 else if (strcmp(name, "InkChannels") == 0) 1982 { 1983 if (caps->color_type & PCL_COLOR_CMYKcm) 1984 description->deflt.integer = 6; 1985 else if (caps->color_type == PCL_COLOR_NONE) 1986 description->deflt.integer = 1; 1987 else 1988 description->deflt.integer = 4; 1989 description->bounds.integer.lower = -1; 1990 description->bounds.integer.upper = -1; 1991 } 1992 else if (strcmp(name, "PrintingMode") == 0) 1993 { 1994 description->bounds.str = stp_string_list_create(); 1995 if (caps->color_type != PCL_COLOR_NONE) 1996 stp_string_list_add_string 1997 (description->bounds.str, "Color", _("Color")); 1998 stp_string_list_add_string 1999 (description->bounds.str, "BW", _("Black and White")); 2000 description->deflt.str = 2001 stp_string_list_param(description->bounds.str, 0)->name; 2002 } 2003} 2004 2005 2006/* 2007 * 'pcl_imageable_area()' - Return the imageable area of the page. 2008 */ 2009static void 2010internal_imageable_area(const stp_vars_t *v, /* I */ 2011 int use_paper_margins, 2012 int *left, /* O - Left position in points */ 2013 int *right, /* O - Right position in points */ 2014 int *bottom, /* O - Bottom position in points */ 2015 int *top) /* O - Top position in points */ 2016{ 2017 int width, height; /* Size of page */ 2018 const pcl_cap_t *caps; /* Printer caps */ 2019 int pcl_media_size; /* Converted media size */ 2020 const char *media_size = stp_get_string_parameter(v, "PageSize"); 2021 const stp_papersize_t *pp = NULL; 2022 int left_margin = 0; 2023 int right_margin = 0; 2024 int bottom_margin = 0; 2025 int top_margin = 0; 2026 2027 caps = pcl_get_model_capabilities(stp_get_model_id(v)); 2028 2029 stp_default_media_size(v, &width, &height); 2030 2031/* If we are using A4 paper, then the margins are different than any 2032 * other paper size. This is because HP wanted to have the same printable 2033 * width for A4 as for letter. Go figure. 2034 */ 2035 2036 if (!media_size) 2037 media_size = ""; 2038 if (strlen(media_size) == 0 && 2039 ((pp = stp_get_papersize_by_size(stp_get_page_height(v), 2040 stp_get_page_width(v))) != NULL)) 2041 media_size = pp->name; 2042 2043 stp_deprintf(STP_DBG_PCL, "pcl_imageable_area(): media_size: '%s'\n", 2044 media_size); 2045 2046 pcl_media_size = pcl_convert_media_size(media_size, stp_get_model_id(v)); 2047 if (media_size) 2048 pp = stp_get_papersize_by_name(media_size); 2049 if (pp && use_paper_margins) 2050 { 2051 left_margin = pp->left; 2052 right_margin = pp->right; 2053 bottom_margin = pp->bottom; 2054 top_margin = pp->top; 2055 } 2056 2057 if (pcl_media_size == PCL_PAPERSIZE_A4) 2058 { 2059 left_margin = MAX(left_margin, caps->a4_margins.left_margin); 2060 right_margin = MAX(right_margin, caps->a4_margins.right_margin); 2061 top_margin = MAX(top_margin, caps->a4_margins.top_margin); 2062 bottom_margin = MAX(bottom_margin, caps->a4_margins.bottom_margin); 2063 } 2064 else 2065 { 2066 left_margin = MAX(left_margin, caps->normal_margins.left_margin); 2067 right_margin = MAX(right_margin, caps->normal_margins.right_margin); 2068 top_margin = MAX(top_margin, caps->normal_margins.top_margin); 2069 bottom_margin = MAX(bottom_margin, caps->normal_margins.bottom_margin); 2070 } 2071 *left = left_margin; 2072 *right = width - right_margin; 2073 *top = top_margin; 2074 *bottom = height - bottom_margin; 2075} 2076 2077static void 2078pcl_imageable_area(const stp_vars_t *v, /* I */ 2079 int *left, /* O - Left position in points */ 2080 int *right, /* O - Right position in points */ 2081 int *bottom, /* O - Bottom position in points */ 2082 int *top) /* O - Top position in points */ 2083{ 2084 internal_imageable_area(v, 1, left, right, bottom, top); 2085} 2086 2087static void 2088pcl_limit(const stp_vars_t *v, /* I */ 2089 int *width, 2090 int *height, 2091 int *min_width, 2092 int *min_height) 2093{ 2094 const pcl_cap_t *caps= pcl_get_model_capabilities(stp_get_model_id(v)); 2095 *width = caps->custom_max_width; 2096 *height = caps->custom_max_height; 2097 *min_width = caps->custom_min_width; 2098 *min_height = caps->custom_min_height; 2099} 2100 2101static const char * 2102pcl_describe_output(const stp_vars_t *v) 2103{ 2104 int printing_color = 0; 2105 int model = stp_get_model_id(v); 2106 const pcl_cap_t *caps = pcl_get_model_capabilities(model); 2107 const char *print_mode = stp_get_string_parameter(v, "PrintingMode"); 2108 int xdpi, ydpi; 2109 2110 pcl_describe_resolution(v, &xdpi, &ydpi); 2111 if (!print_mode || strcmp(print_mode, "Color") == 0) 2112 printing_color = 1; 2113 if (((caps->resolutions & PCL_RES_600_600_MONO) == PCL_RES_600_600_MONO) && 2114 printing_color && xdpi == 600 && ydpi == 600) 2115 printing_color = 0; 2116 if (printing_color) 2117 { 2118 if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY) 2119 return "CMY"; 2120 else 2121 return "CMYK"; 2122 } 2123 else 2124 return "Grayscale"; 2125} 2126 2127/* 2128 * 'pcl_print()' - Print an image to an HP printer. 2129 */ 2130 2131static void 2132pcl_printfunc(stp_vars_t *v) 2133{ 2134 pcl_privdata_t *pd = (pcl_privdata_t *) stp_get_component_data(v, "Driver"); 2135 int do_blank = pd->do_blank; 2136 unsigned char *black = stp_dither_get_channel(v, STP_ECOLOR_K, 0); 2137 unsigned char *cyan = stp_dither_get_channel(v, STP_ECOLOR_C, 0); 2138 unsigned char *lcyan = stp_dither_get_channel(v, STP_ECOLOR_C, 1); 2139 unsigned char *magenta = stp_dither_get_channel(v, STP_ECOLOR_M, 0); 2140 unsigned char *lmagenta = stp_dither_get_channel(v, STP_ECOLOR_M, 1); 2141 unsigned char *yellow = stp_dither_get_channel(v, STP_ECOLOR_Y, 0); 2142 int len_c = stp_dither_get_last_position(v, STP_ECOLOR_C, 0); 2143 int len_lc = stp_dither_get_last_position(v, STP_ECOLOR_C, 1); 2144 int len_m = stp_dither_get_last_position(v, STP_ECOLOR_M, 0); 2145 int len_lm = stp_dither_get_last_position(v, STP_ECOLOR_M, 1); 2146 int len_y = stp_dither_get_last_position(v, STP_ECOLOR_Y, 0); 2147 int len_k = stp_dither_get_last_position(v, STP_ECOLOR_K, 0); 2148 int is_blank = (do_blank && (len_c == -1) && (len_lc == -1) && 2149 (len_m == -1) && (len_lm == -1) && (len_y == -1) && 2150 (len_k == -1)); 2151 int height = pd->height; 2152 const char *print_mode = stp_get_string_parameter(v, "PrintingMode"); 2153 2154 if (is_blank && (pd->blank_lines != 0)) /* repeated blank line */ 2155 { 2156 pd->blank_lines++; 2157 } 2158 else /* Not blank, or is first one */ 2159 { 2160 if (! is_blank) 2161 { 2162 if (pd->blank_lines > 1) /* Output accumulated lines */ 2163 { 2164 pd->blank_lines--; /* correct for one already output */ 2165 stp_deprintf(STP_DBG_PCL, "Blank Lines = %d\n", pd->blank_lines); 2166 stp_zprintf(v, "\033*b%dY", pd->blank_lines); 2167 pd->blank_lines=0; 2168 } 2169 else; 2170 } 2171 else 2172 { 2173 pd->blank_lines++; 2174 } 2175 2176 if (pd->do_cret) 2177 { 2178 /* 2179 * 4-level (CRet) dithers... 2180 */ 2181 if (strcmp(print_mode, "BW") == 0) 2182 { 2183 (*(pd->writefunc))(v, black + height / 2, height / 2, 0); 2184 (*(pd->writefunc))(v, black, height / 2, 1); 2185 } 2186 else 2187 { 2188 if(pd->do_cretb) 2189 { 2190 /* (*(pd->writefunc))(v, black + height / 2, 0, 0); */ 2191 (*(pd->writefunc))(v, black, height/2, 0); 2192 } 2193 else 2194 { 2195 (*(pd->writefunc))(v, black + height / 2, height / 2, 0); 2196 (*(pd->writefunc))(v, black, height / 2, 0); 2197 } 2198 (*(pd->writefunc))(v, cyan + height / 2, height / 2, 0); 2199 (*(pd->writefunc))(v, cyan, height / 2, 0); 2200 (*(pd->writefunc))(v, magenta + height / 2, height / 2, 0); 2201 (*(pd->writefunc))(v, magenta, height / 2, 0); 2202 (*(pd->writefunc))(v, yellow + height / 2, height / 2, 0); 2203 if (pd->do_6color) 2204 { 2205 (*(pd->writefunc))(v, yellow, height / 2, 0); 2206 (*(pd->writefunc))(v, lcyan + height / 2, height / 2, 0); 2207 (*(pd->writefunc))(v, lcyan, height / 2, 0); 2208 (*(pd->writefunc))(v, lmagenta + height / 2, height / 2, 0); 2209 (*(pd->writefunc))(v, lmagenta, height / 2, 1); /* Last plane set on light magenta */ 2210 } 2211 else 2212 (*(pd->writefunc))(v, yellow, height / 2, 1); /* Last plane set on yellow */ 2213 } 2214 } 2215 else 2216 { 2217 /* 2218 * Standard 2-level dithers... 2219 */ 2220 2221 if (strcmp(print_mode, "BW") == 0) 2222 { 2223 (*(pd->writefunc))(v, black, height, 1); 2224 } 2225 else 2226 { 2227 if (black != NULL) 2228 (*(pd->writefunc))(v, black, height, 0); 2229 (*(pd->writefunc))(v, cyan, height, 0); 2230 (*(pd->writefunc))(v, magenta, height, 0); 2231 if (pd->do_6color) 2232 { 2233 (*(pd->writefunc))(v, yellow, height, 0); 2234 (*(pd->writefunc))(v, lcyan, height, 0); 2235 (*(pd->writefunc))(v, lmagenta, height, 1); /* Last plane set on light magenta */ 2236 } 2237 else 2238 (*(pd->writefunc))(v, yellow, height, 1); /* Last plane set on yellow */ 2239 } 2240 } 2241 } 2242} 2243 2244static double 2245get_double_param(stp_vars_t *v, const char *param) 2246{ 2247 if (param && stp_check_float_parameter(v, param, STP_PARAMETER_ACTIVE)) 2248 return stp_get_float_parameter(v, param); 2249 else 2250 return 1.0; 2251} 2252 2253static int 2254pcl_do_print(stp_vars_t *v, stp_image_t *image) 2255{ 2256 pcl_privdata_t privdata; 2257 int status = 1; 2258 int model = stp_get_model_id(v); 2259 const char *media_size = stp_get_string_parameter(v, "PageSize"); 2260 const char *media_type = stp_get_string_parameter(v, "MediaType"); 2261 const char *media_source = stp_get_string_parameter(v, "InputSlot"); 2262 const char *ink_type = stp_get_string_parameter(v, "InkType"); 2263 const char *print_mode = stp_get_string_parameter(v, "PrintingMode"); 2264 const char *duplex_mode = stp_get_string_parameter(v, "Duplex"); 2265 int page_number = stp_get_int_parameter(v, "PageNumber"); 2266 int printing_color = 0; 2267 int top = stp_get_top(v); 2268 int left = stp_get_left(v); 2269 int y; /* Looping vars */ 2270 int xdpi, ydpi; /* Resolution */ 2271 unsigned char *black, /* Black bitmap data */ 2272 *cyan, /* Cyan bitmap data */ 2273 *magenta, /* Magenta bitmap data */ 2274 *yellow, /* Yellow bitmap data */ 2275 *lcyan, /* Light Cyan bitmap data */ 2276 *lmagenta; /* Light Magenta bitmap data */ 2277 int page_width, /* Width of page */ 2278 page_height, /* Height of page */ 2279 page_left, 2280 page_top, 2281 page_right, 2282 page_bottom, 2283 out_width, /* Width of image on page */ 2284 out_height, /* Height of image on page */ 2285 out_channels, /* Output bytes per pixel */ 2286 errdiv, /* Error dividend */ 2287 errmod, /* Error modulus */ 2288 errval, /* Current error value */ 2289 errline, /* Current raster line */ 2290 errlast; /* Last raster line loaded */ 2291 unsigned zero_mask; 2292 int image_height, 2293 image_width; 2294 const pcl_cap_t *caps; /* Printer capabilities */ 2295 int planes = 3; /* # of output planes */ 2296 int pcl_media_size; /* PCL media size code */ 2297 const double *dot_sizes_use; 2298 const stp_papersize_t *pp; 2299 int the_top_margin, /* Corrected top margin */ 2300 the_left_margin; /* Corrected left margin */ 2301 int manual_feed_left_adjust = 0; 2302 int extra_left_margin = 0; 2303 stp_curve_t *lum_adjustment; 2304 stp_curve_t *hue_adjustment; 2305 double density; 2306 2307 if (!stp_verify(v)) 2308 { 2309 stp_eprintf(v, "Print options not verified; cannot print.\n"); 2310 return 0; 2311 } 2312 if (strcmp(print_mode, "Color") == 0) 2313 printing_color = 1; 2314 2315 caps = pcl_get_model_capabilities(model); 2316 2317 /* 2318 * Setup a read-only pixel region for the entire image... 2319 */ 2320 2321 stp_image_init(image); 2322 image_height = stp_image_height(image); 2323 image_width = stp_image_width(image); 2324 2325 /* 2326 * Figure out the output resolution... 2327 */ 2328 2329 pcl_describe_resolution(v, &xdpi, &ydpi); 2330 2331 stp_deprintf(STP_DBG_PCL,"pcl: resolution=%dx%d\n",xdpi,ydpi); 2332 if (xdpi <= 0 || ydpi <= 0) 2333 { 2334 stp_eprintf(v, "No resolution found; cannot print.\n"); 2335 return 0; 2336 } 2337 2338 /* 2339 * Choose the correct color conversion function... 2340 */ 2341 if (((caps->resolutions & PCL_RES_600_600_MONO) == PCL_RES_600_600_MONO) && 2342 printing_color && xdpi == 600 && ydpi == 600) 2343 { 2344 stp_eprintf(v, "600x600 resolution only available in MONO\n"); 2345 stp_set_string_parameter(v, "PrintingMode", "BW"); 2346 printing_color = 0; 2347 } 2348 2349 privdata.do_cret = (xdpi >= 300 && 2350 ((caps->color_type & PCL_COLOR_CMYK4) == PCL_COLOR_CMYK4)); 2351 privdata.do_cretb = (xdpi >= 600 && ydpi >= 600 && 2352 ((caps->color_type & PCL_COLOR_CMYK4b) == PCL_COLOR_CMYK4b) && 2353 printing_color); 2354 if (privdata.do_cretb){ 2355 privdata.do_cret = 1; 2356 dot_sizes_use=dot_sizes_cret; 2357 }else{ 2358 dot_sizes_use=dot_sizes; 2359 } 2360 2361 stp_deprintf(STP_DBG_PCL, "privdata.do_cret = %d\n", privdata.do_cret); 2362 stp_deprintf(STP_DBG_PCL, "privdata.do_cretb = %d\n", privdata.do_cretb); 2363 2364 if (ink_type && printing_color) 2365 privdata.do_6color = (strcmp(ink_type, "Photo") == 0); 2366 else 2367 privdata.do_6color = 0; 2368 2369 stp_deprintf(STP_DBG_PCL, "privdata.do_6color = %d\n", privdata.do_6color); 2370 2371 /* 2372 * Compute the output size... 2373 */ 2374 2375 out_width = stp_get_width(v); 2376 out_height = stp_get_height(v); 2377 2378 internal_imageable_area(v, 0, &page_left, &page_right, 2379 &page_bottom, &page_top); 2380 left -= page_left; 2381 top -= page_top; 2382 page_width = page_right - page_left; 2383 page_height = page_bottom - page_top; 2384 2385 image_height = stp_image_height(image); 2386 image_width = stp_image_width(image); 2387 2388 /* 2389 * Set media size here because it is needed by the margin calculation code. 2390 */ 2391 2392 if (!media_size) 2393 media_size = ""; 2394 if (strlen(media_size) == 0 && 2395 ((pp = stp_get_papersize_by_size(stp_get_page_height(v), 2396 stp_get_page_width(v))) != NULL)) 2397 media_size = pp->name; 2398 2399 pcl_media_size = pcl_convert_media_size(media_size, model); 2400 2401 stp_deprintf(STP_DBG_PCL,"pcl_media_size = %d, media_size = %s\n", pcl_media_size, media_size); 2402 2403 /* 2404 * If the media size requested is unknown, try it as a custom size. 2405 * 2406 * Warning: The margins may need to be fixed for this! 2407 */ 2408 2409 if (pcl_media_size == -1) { 2410 stp_deprintf(STP_DBG_PCL, "Paper size %s is not directly supported by printer.\n", 2411 media_size); 2412 stp_deprintf(STP_DBG_PCL, "Trying as custom pagesize (watch the margins!)\n"); 2413 pcl_media_size = PCL_PAPERSIZE_CUSTOM; /* Custom */ 2414 } 2415 2416 stp_deprintf(STP_DBG_PCL, "Duplex: %s, Page_Number: %d\n", duplex_mode, page_number); 2417 privdata.duplex=0; 2418 privdata.tumble=0; 2419 2420 /* 2421 * Duplex 2422 */ 2423 2424 if (duplex_mode) 2425 { 2426 if (caps->stp_printer_type & PCL_PRINTER_DUPLEX) 2427 { 2428 if ((strcmp(duplex_mode, "DuplexTumble") == 0) || (strcmp(duplex_mode, "DuplexNoTumble") == 0)) 2429 privdata.duplex=1; 2430 if ((strcmp(duplex_mode, "DuplexTumble") == 0)) 2431 privdata.tumble=1; 2432 } 2433 } 2434 2435 /* 2436 * Send PCL initialization commands... 2437 */ 2438 2439 if ((privdata.duplex == 0) || ((page_number & 1) == 0)) 2440 { 2441 int pcl_media_type, /* PCL media type code */ 2442 pcl_media_source; /* PCL media source code */ 2443 2444 stp_deprintf(STP_DBG_PCL, "Normal init\n"); 2445 2446 if (privdata.do_cretb) 2447 stp_puts("\033*rbC", v); /* End raster graphics */ 2448 stp_puts("\033E", v); /* PCL reset */ 2449 if (privdata.do_cretb) 2450 stp_zprintf(v, "\033%%-12345X@PJL ENTER LANGUAGE=PCL3GUI\n"); 2451 2452 stp_puts("\033&l6D\033&k12H",v); /* 6 lines per inch, 10 chars per inch */ 2453 stp_puts("\033&l0O",v); /* Portrait */ 2454 2455 stp_zprintf(v, "\033&l%dA", pcl_media_size); /* Set media size we calculated above */ 2456 stp_zprintf(v, "\033&l%dP", stp_get_page_height(v) / 12); 2457 /* Length of "forms" in "lines" */ 2458 stp_puts("\033&l0L", v); /* Turn off perforation skip */ 2459 stp_puts("\033&l0E", v); /* Reset top margin to 0 */ 2460 2461 /* 2462 * Convert media source string to the code, if specified. 2463 */ 2464 2465 if (media_source && strlen(media_source) != 0) { 2466 pcl_media_source = pcl_string_to_val(media_source, pcl_media_sources, 2467 sizeof(pcl_media_sources) / sizeof(pcl_t)); 2468 2469 stp_deprintf(STP_DBG_PCL,"pcl_media_source = %d, media_source = %s\n", pcl_media_source, 2470 media_source); 2471 2472 if (pcl_media_source == -1) 2473 stp_deprintf(STP_DBG_PCL, "Unknown media source %s, ignored.\n", media_source); 2474 else if (pcl_media_source != PCL_PAPERSOURCE_STANDARD) { 2475 2476/* Correct the value by taking the modulus */ 2477 2478 if ((pcl_media_source & PAPERSOURCE_ADJ_GUIDE) == 2479 PAPERSOURCE_ADJ_GUIDE) 2480 { 2481 manual_feed_left_adjust = 1; 2482 stp_deprintf(STP_DBG_PCL, "Adjusting left margin for manual feed.\n"); 2483 } 2484 pcl_media_source = pcl_media_source % PAPERSOURCE_MOD; 2485 stp_zprintf(v, "\033&l%dH", pcl_media_source); 2486 } 2487 } 2488 2489 /* 2490 * Convert media type string to the code, if specified. 2491 */ 2492 2493 if (media_type && strlen(media_type) != 0) { 2494 pcl_media_type = pcl_string_to_val(media_type, pcl_media_types, 2495 sizeof(pcl_media_types) / sizeof(pcl_t)); 2496 2497 stp_deprintf(STP_DBG_PCL,"pcl_media_type = %d, media_type = %s\n", pcl_media_type, 2498 media_type); 2499 2500 if (pcl_media_type == -1) { 2501 stp_deprintf(STP_DBG_PCL, "Unknown media type %s, set to PLAIN.\n", media_type); 2502 pcl_media_type = PCL_PAPERTYPE_PLAIN; 2503 } 2504 2505/* 2506 * The HP812C doesn't like glossy paper being selected when using 600x600 2507 * C-RET (PhotoRET II). So we use Premium paper instead. 2508 * 2509 */ 2510 2511 if (privdata.do_cretb && pcl_media_type == PCL_PAPERTYPE_GLOSSY) { 2512 stp_deprintf(STP_DBG_PCL, "Media type GLOSSY, set to PREMIUM for PhotoRET II.\n"); 2513 pcl_media_type = PCL_PAPERTYPE_PREMIUM; 2514 } 2515 } 2516 else 2517 pcl_media_type = PCL_PAPERTYPE_PLAIN; 2518 2519 /* 2520 * Set DJ print quality to "best" if resolution >= 300 2521 */ 2522 2523 if ((xdpi >= 300) && ((caps->stp_printer_type & PCL_PRINTER_DJ) == PCL_PRINTER_DJ)) 2524 { 2525 if ((caps->stp_printer_type & PCL_PRINTER_MEDIATYPE) == PCL_PRINTER_MEDIATYPE) 2526 { 2527 stp_puts("\033*o1M", v); /* Quality = presentation */ 2528 stp_zprintf(v, "\033&l%dM", pcl_media_type); 2529 } 2530 else 2531 { 2532 stp_puts("\033*r2Q", v); /* Quality (high) */ 2533 stp_puts("\033*o2Q", v); /* Shingling (4 passes) */ 2534 2535 /* Depletion depends on media type and cart type. */ 2536 2537 if ((pcl_media_type == PCL_PAPERTYPE_PLAIN) 2538 || (pcl_media_type == PCL_PAPERTYPE_BOND)) { 2539 if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY) 2540 stp_puts("\033*o2D", v); /* Depletion 25% */ 2541 else 2542 stp_puts("\033*o5D", v); /* Depletion 50% with gamma correction */ 2543 } 2544 2545 else if ((pcl_media_type == PCL_PAPERTYPE_PREMIUM) 2546 || (pcl_media_type == PCL_PAPERTYPE_GLOSSY) 2547 || (pcl_media_type == PCL_PAPERTYPE_TRANS)) 2548 stp_puts("\033*o1D", v); /* Depletion none */ 2549 } 2550 } 2551 2552/* 2553 * Duplex 2554 */ 2555 2556 if (privdata.duplex) 2557 stp_zprintf(v,"\033&l%dS", privdata.duplex + privdata.tumble); 2558 } 2559 else 2560 { 2561 stp_deprintf(STP_DBG_PCL, "Back face init\n"); 2562 stp_puts("\033&a2G", v); 2563 } 2564 2565/* 2566 * See if we need to use the CRD (Configure Raster Data) command, because we're 2567 * doing something interesting on a DeskJet. 2568 * (I hate long complicated if statements, the compiler will sort it out!). 2569 */ 2570 2571 privdata.use_crd = 0; 2572 if ((caps->stp_printer_type & PCL_PRINTER_DJ) == PCL_PRINTER_DJ) 2573 { 2574 if (xdpi != ydpi) /* Different X and Y Resolutions */ 2575 privdata.use_crd = 1; 2576 if (privdata.do_cret) /* Resolution Enhancement */ 2577 privdata.use_crd = 1; 2578 if (privdata.do_6color) /* Photo Ink printing */ 2579 privdata.use_crd = 1; 2580 if (privdata.duplex) /* Duplexing */ 2581 privdata.use_crd = 1; 2582 } 2583 2584 if (privdata.use_crd) 2585 /* Set resolution using CRD */ 2586 { 2587 2588/* 2589 * If duplexing on a CRD printer, we need to use the (re)load media command. 2590 */ 2591 2592 if (privdata.duplex) 2593 stp_puts("\033&l-2H",v); /* Load media */ 2594 2595 /* 2596 * Send configure image data command with horizontal and 2597 * vertical resolutions as well as a color count... 2598 */ 2599 2600 if (printing_color) 2601 if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY) 2602 planes = 3; 2603 else 2604 if (privdata.do_6color) 2605 planes = 6; 2606 else 2607 planes = 4; 2608 else 2609 planes = 1; 2610 2611 stp_zprintf(v, "\033*g%dW", 2 + (planes * 6)); 2612 stp_putc(2, v); /* Format 2 (Complex Direct Planar) */ 2613 stp_putc(planes, v); /* # output planes */ 2614 2615 if (planes != 3) { /* Black resolution */ 2616 stp_send_command(v, "", "HHH", xdpi, ydpi, (privdata.do_cretb || !privdata.do_cret) ? 2 : 4); 2617 } 2618 2619 if (planes != 1) { /* Cyan, magenta, yellow resolutions */ 2620 stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2); 2621 stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2); 2622 stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2); 2623 } 2624 if (planes == 6) /* LC, LM resolutions */ 2625 { 2626 stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2); 2627 stp_send_command(v, "", "HHH", xdpi, ydpi, privdata.do_cret ? 4 : 2); 2628 } 2629 } 2630 else 2631 { 2632 stp_zprintf(v, "\033*t%dR", xdpi); /* Simple resolution */ 2633 if (printing_color) 2634 { 2635 if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY) 2636 stp_puts("\033*r-3U", v); /* Simple CMY color */ 2637 else 2638 stp_puts("\033*r-4U", v); /* Simple KCMY color */ 2639 } 2640 } 2641 2642 if ((caps->stp_printer_type & PCL_PRINTER_TIFF) == PCL_PRINTER_TIFF && 2643 !(stp_get_debug_level() & STP_DBG_NO_COMPRESSION)) 2644 { 2645 stp_puts("\033*b2M", v); /* Mode 2 (TIFF) */ 2646 } 2647 else 2648 { 2649 stp_puts("\033*b0M", v); /* Mode 0 (no compression) */ 2650 } 2651 2652 /* 2653 * Convert image size to printer resolution and setup the page for printing... 2654 */ 2655 2656 out_width = xdpi * out_width / 72; 2657 out_height = ydpi * out_height / 72; 2658 2659 if (pcl_media_size == PCL_PAPERSIZE_A4) 2660 { 2661 the_left_margin = caps->a4_margins.left_margin; 2662 the_top_margin = caps->a4_margins.top_margin; 2663 } 2664 else 2665 { 2666 the_left_margin = caps->normal_margins.left_margin; 2667 the_top_margin = caps->normal_margins.top_margin; 2668 } 2669 2670 stp_deprintf(STP_DBG_PCL, "left %d margin %d top %d margin %d width %d height %d\n", 2671 left, the_left_margin, top, the_top_margin, out_width, out_height); 2672 2673 if (manual_feed_left_adjust) 2674 { 2675 unsigned wdelta = caps->custom_max_width - stp_get_page_width(v); 2676 if (wdelta > 0) 2677 { 2678 /* 2679 * Why 3? I would expect it would be 2 here, but it appears 2680 * that at least one printer (LJ 1022) actually partially 2681 * adjusts the margin itself. Adjusting the left margin by 1/3 2682 * of the difference between the maximum width and the actual 2683 * width experimentally yields correct results -- rlk 20081014 2684 */ 2685 stp_deprintf(STP_DBG_PCL, 2686 " Adjusting manual feed left margin by %d\n", wdelta / 3); 2687 extra_left_margin += wdelta / 3; 2688 } 2689 } 2690 2691 if (!privdata.do_cretb) { 2692 stp_zprintf(v, "\033&a%dH", 10 * (left + extra_left_margin)); /* Set left raster position */ 2693 stp_zprintf(v, "\033&a%dV", 10 * (top + the_top_margin)); 2694 /* Set top raster position */ 2695 } 2696 stp_zprintf(v, "\033*r%dS", out_width); /* Set raster width */ 2697 stp_zprintf(v, "\033*r%dT", out_height); /* Set raster height */ 2698 2699 if (privdata.do_cretb) 2700 { 2701 /* Move to top left of printed area */ 2702 stp_zprintf(v, "\033*p%dY", (top + the_top_margin)*4); /* Measured in dots. */ 2703 stp_zprintf(v, "\033*p%dX", (left + extra_left_margin)*4); 2704 } 2705 stp_puts("\033*r1A", v); /* Start GFX */ 2706 2707 /* 2708 * Allocate memory for the raster data... 2709 */ 2710 2711 privdata.height = (out_width + 7) / 8; 2712 if (privdata.do_cret) 2713 privdata.height *= 2; 2714 2715 if (!printing_color) 2716 { 2717 black = stp_malloc(privdata.height); 2718 cyan = NULL; 2719 magenta = NULL; 2720 yellow = NULL; 2721 lcyan = NULL; 2722 lmagenta = NULL; 2723 } 2724 else 2725 { 2726 cyan = stp_malloc(privdata.height); 2727 magenta = stp_malloc(privdata.height); 2728 yellow = stp_malloc(privdata.height); 2729 2730 if ((caps->color_type & PCL_COLOR_CMY) == PCL_COLOR_CMY) 2731 black = NULL; 2732 else 2733 black = stp_malloc(privdata.height); 2734 if (privdata.do_6color) 2735 { 2736 lcyan = stp_malloc(privdata.height); 2737 lmagenta = stp_malloc(privdata.height); 2738 } 2739 else 2740 { 2741 lcyan = NULL; 2742 lmagenta = NULL; 2743 } 2744 } 2745 2746 if (black) 2747 { 2748 if (cyan) 2749 stp_set_string_parameter(v, "STPIOutputType", "KCMY"); 2750 else 2751 stp_set_string_parameter(v, "STPIOutputType", "Grayscale"); 2752 } 2753 else 2754 stp_set_string_parameter(v, "STPIOutputType", "CMY"); 2755 2756/* Allocate buffer for pcl_mode2 tiff compression */ 2757 2758 if ((caps->stp_printer_type & PCL_PRINTER_TIFF) == PCL_PRINTER_TIFF && 2759 !(stp_get_debug_level() & STP_DBG_NO_COMPRESSION)) 2760 { 2761 privdata.comp_buf = stp_malloc((privdata.height + 128 + 7) * 129 / 128); 2762 privdata.writefunc = pcl_mode2; 2763 } 2764 else 2765 { 2766 privdata.comp_buf = NULL; 2767 privdata.writefunc = pcl_mode0; 2768 } 2769 2770/* Set up dithering for special printers. */ 2771 2772#if 1 /* Leave alone for now */ 2773 if (!stp_check_float_parameter(v, "GCRLower", STP_PARAMETER_ACTIVE)) 2774 stp_set_default_float_parameter(v, "GCRLower", .3); 2775 if (!stp_check_float_parameter(v, "GCRUpper", STP_PARAMETER_ACTIVE)) 2776 stp_set_default_float_parameter(v, "GCRUpper", .999); 2777#endif 2778 stp_dither_init(v, image, out_width, xdpi, ydpi); 2779 2780 if (black) 2781 { 2782 stp_dither_add_channel(v, black, STP_ECOLOR_K, 0); 2783 stp_channel_set_black_channel(v, STP_ECOLOR_K); 2784 } 2785 if (cyan) 2786 stp_dither_add_channel(v, cyan, STP_ECOLOR_C, 0); 2787 if (lcyan) 2788 stp_dither_add_channel(v, lcyan, STP_ECOLOR_C, 1); 2789 if (magenta) 2790 stp_dither_add_channel(v, magenta, STP_ECOLOR_M, 0); 2791 if (lmagenta) 2792 stp_dither_add_channel(v, lmagenta, STP_ECOLOR_M, 1); 2793 if (yellow) 2794 stp_dither_add_channel(v, yellow, STP_ECOLOR_Y, 0); 2795 2796/* Ensure that density does not exceed 1.0 */ 2797 2798 if (!stp_check_float_parameter(v, "Density", STP_PARAMETER_DEFAULTED)) 2799 { 2800 stp_set_float_parameter_active(v, "Density", STP_PARAMETER_ACTIVE); 2801 stp_set_float_parameter(v, "Density", 1.0); 2802 } 2803 2804 stp_deprintf(STP_DBG_PCL, "Density: %f\n", stp_get_float_parameter(v, "Density")); 2805 if (stp_get_float_parameter(v, "Density") > 1.0) 2806 stp_set_float_parameter(v, "Density", 1.0); 2807 density = stp_get_float_parameter(v, "Density"); 2808 2809 if (privdata.do_cret) /* 4-level printing for 800/1120 */ 2810 { 2811 if (yellow) 2812 stp_dither_set_inks_simple(v, STP_ECOLOR_Y, 3, dot_sizes_use, 1.0, 0.08); 2813 if (black && !privdata.do_cretb) 2814 stp_dither_set_inks_simple(v, STP_ECOLOR_K, 3, dot_sizes_use, 1.0, 1.0); 2815 2816 /* Note: no printer I know of does both CRet (4-level) and 6 colour, but 2817 what the heck. variable_dither_ranges copied from print-escp2.c */ 2818 2819 if (privdata.do_6color) /* Photo for 69x */ 2820 { 2821 stp_dither_set_inks_full(v, STP_ECOLOR_C, 6, variable_shades, 1.0, 2822 0.31 / .5); 2823 stp_dither_set_inks_full(v, STP_ECOLOR_M, 6, variable_shades, 1.0, 2824 0.61 / .97); 2825 } 2826 else 2827 { 2828 if (cyan) 2829 stp_dither_set_inks_simple(v, STP_ECOLOR_C, 3, dot_sizes_use, 1.0, 2830 0.31 / .5); 2831 if (magenta) 2832 stp_dither_set_inks_simple(v, STP_ECOLOR_M, 3, dot_sizes_use, 1.0, 2833 0.61 / .7); 2834 } 2835 } 2836 else if (privdata.do_6color) 2837 { 2838 /* Set light inks for 6 colour printers. 2839 Numbers copied from print-escp2.c */ 2840 stp_dither_set_inks_full(v, STP_ECOLOR_C, 2, photo_dither_shades, 1.0, 2841 0.31 / .5); 2842 stp_dither_set_inks_full(v, STP_ECOLOR_M, 2, photo_dither_shades, 1.0, 2843 0.61 / .7); 2844 } 2845 if (black) 2846 stp_channel_set_density_adjustment(v, STP_ECOLOR_K, 0, 2847 get_double_param(v, "BlackDensity") * 2848 get_double_param(v, "Density")); 2849 if (cyan) 2850 stp_channel_set_density_adjustment(v, STP_ECOLOR_C, 0, 2851 get_double_param(v, "CyanDensity") * 2852 get_double_param(v, "Density")); 2853 if (magenta) 2854 stp_channel_set_density_adjustment(v, STP_ECOLOR_M, 0, 2855 get_double_param(v, "MagentaDensity") * 2856 get_double_param(v, "Density")); 2857 if (yellow) 2858 stp_channel_set_density_adjustment(v, STP_ECOLOR_Y, 0, 2859 get_double_param(v, "YellowDensity") * 2860 get_double_param(v, "Density")); 2861 if (lcyan) 2862 stp_channel_set_density_adjustment 2863 (v, STP_ECOLOR_C, 1, (get_double_param(v, "CyanDensity") * 2864 get_double_param(v, "LightCyanTrans") * 2865 get_double_param(v, "Density"))); 2866 if (lmagenta) 2867 stp_channel_set_density_adjustment 2868 (v, STP_ECOLOR_M, 1, (get_double_param(v, "MagentaDensity") * 2869 get_double_param(v, "LightMagentaTrans") * 2870 get_double_param(v, "Density"))); 2871 2872 2873 if (!stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_ACTIVE)) 2874 { 2875 hue_adjustment = stp_curve_create_from_string(standard_hue_adjustment); 2876 stp_set_curve_parameter(v, "HueMap", hue_adjustment); 2877 stp_curve_destroy(hue_adjustment); 2878 } 2879 if (!stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_ACTIVE)) 2880 { 2881 lum_adjustment = stp_curve_create_from_string(standard_lum_adjustment); 2882 stp_curve_destroy(lum_adjustment); 2883 } 2884 2885 out_channels = stp_color_init(v, image, 65536); 2886 2887 errdiv = image_height / out_height; 2888 errmod = image_height % out_height; 2889 errval = 0; 2890 errlast = -1; 2891 errline = 0; 2892 privdata.blank_lines = 0; 2893#ifndef PCL_DEBUG_DISABLE_BLANKLINE_REMOVAL 2894 privdata.do_blank = ((caps->stp_printer_type & PCL_PRINTER_BLANKLINE) == 2895 PCL_PRINTER_BLANKLINE); 2896#else 2897 privdata.do_blank = 0; 2898#endif 2899 stp_allocate_component_data(v, "Driver", NULL, NULL, &privdata); 2900 2901 for (y = 0; y < out_height; y ++) 2902 { 2903 int duplicate_line = 1; 2904 if (errline != errlast) 2905 { 2906 errlast = errline; 2907 duplicate_line = 0; 2908 if (stp_color_get_row(v, image, errline, &zero_mask)) 2909 { 2910 status = 2; 2911 break; 2912 } 2913 } 2914 stp_dither(v, y, duplicate_line, zero_mask, NULL); 2915 pcl_printfunc(v); 2916 stp_deprintf(STP_DBG_PCL,"pcl_print: y = %d, line = %d, val = %d, mod = %d, height = %d\n", 2917 y, errline, errval, errmod, out_height); 2918 errval += errmod; 2919 errline += errdiv; 2920 if (errval >= out_height) 2921 { 2922 errval -= out_height; 2923 errline ++; 2924 } 2925 } 2926 2927/* Output trailing blank lines (may not be required?) */ 2928 2929 if (privdata.blank_lines > 1) 2930 { 2931 privdata.blank_lines--; /* correct for one already output */ 2932 stp_deprintf(STP_DBG_PCL, "Blank Lines = %d\n", privdata.blank_lines); 2933 stp_zprintf(v, "\033*b%dY", privdata.blank_lines); 2934 privdata.blank_lines=0; 2935 } 2936 2937 stp_image_conclude(image); 2938 2939 /* 2940 * Cleanup... 2941 */ 2942 2943 if (black != NULL) 2944 stp_free(black); 2945 if (cyan != NULL) 2946 { 2947 stp_free(cyan); 2948 stp_free(magenta); 2949 stp_free(yellow); 2950 } 2951 if (lcyan != NULL) 2952 { 2953 stp_free(lcyan); 2954 stp_free(lmagenta); 2955 } 2956 2957 if (privdata.comp_buf != NULL) 2958 stp_free(privdata.comp_buf); 2959 2960 if ((caps->stp_printer_type & PCL_PRINTER_NEW_ERG) == PCL_PRINTER_NEW_ERG) 2961 stp_puts("\033*rC", v); 2962 else 2963 stp_puts("\033*rB", v); 2964 2965 if ((privdata.duplex == 1) && ((page_number & 1) == 0)) 2966 stp_puts("\014", v); /* Form feed */ 2967 else 2968 { 2969 stp_puts("\033&l0H", v); /* Eject page */ 2970 if (privdata.do_cretb) 2971 stp_zprintf(v, "\033%%-12345X\n"); 2972 stp_puts("\033E", v); /* PCL reset */ 2973 } 2974 return status; 2975} 2976 2977static int 2978pcl_print(const stp_vars_t *v, stp_image_t *image) 2979{ 2980 int status; 2981 stp_vars_t *nv = stp_vars_create_copy(v); 2982 stp_prune_inactive_options(nv); 2983 status = pcl_do_print(nv, image); 2984 stp_vars_destroy(nv); 2985 return status; 2986} 2987 2988static const stp_printfuncs_t print_pcl_printfuncs = 2989{ 2990 pcl_list_parameters, 2991 pcl_parameters, 2992 stp_default_media_size, 2993 pcl_imageable_area, 2994 pcl_imageable_area, 2995 pcl_limit, 2996 pcl_print, 2997 pcl_describe_resolution, 2998 pcl_describe_output, 2999 stp_verify_printer_params, 3000 NULL, 3001 NULL, 3002 NULL 3003}; 3004 3005 3006/* 3007 * 'pcl_mode0()' - Send PCL graphics using mode 0 (no) compression. 3008 */ 3009 3010static void 3011pcl_mode0(stp_vars_t *v, /* I - Print file or command */ 3012 unsigned char *line, /* I - Output bitmap data */ 3013 int height, /* I - Height of bitmap data */ 3014 int last_plane) /* I - True if this is the last plane */ 3015{ 3016 stp_zprintf(v, "\033*b%d%c", height, last_plane ? 'W' : 'V'); 3017 stp_zfwrite((const char *) line, height, 1, v); 3018} 3019 3020 3021/* 3022 * 'pcl_mode2()' - Send PCL graphics using mode 2 (TIFF) compression. 3023 */ 3024 3025static void 3026pcl_mode2(stp_vars_t *v, /* I - Print file or command */ 3027 unsigned char *line, /* I - Output bitmap data */ 3028 int height, /* I - Height of bitmap data */ 3029 int last_plane) /* I - True if this is the last plane */ 3030{ 3031 pcl_privdata_t *privdata = 3032 (pcl_privdata_t *) stp_get_component_data(v, "Driver"); 3033 unsigned char *comp_buf = privdata->comp_buf; 3034 unsigned char *comp_ptr; /* Current slot in buffer */ 3035 3036 stp_pack_tiff(v, line, height, comp_buf, &comp_ptr, NULL, NULL); 3037 3038 /* 3039 * Send a line of raster graphics... 3040 */ 3041 3042 stp_zprintf(v, "\033*b%d%c", (int)(comp_ptr - comp_buf), last_plane ? 'W' : 'V'); 3043 stp_zfwrite((const char *)comp_buf, comp_ptr - comp_buf, 1, v); 3044} 3045 3046 3047static stp_family_t print_pcl_module_data = 3048 { 3049 &print_pcl_printfuncs, 3050 NULL 3051 }; 3052 3053 3054static int 3055print_pcl_module_init(void) 3056{ 3057 return stp_family_register(print_pcl_module_data.printer_list); 3058} 3059 3060 3061static int 3062print_pcl_module_exit(void) 3063{ 3064 return stp_family_unregister(print_pcl_module_data.printer_list); 3065} 3066 3067 3068/* Module header */ 3069#define stp_module_version print_pcl_LTX_stp_module_version 3070#define stp_module_data print_pcl_LTX_stp_module_data 3071 3072stp_module_version_t stp_module_version = {0, 0}; 3073 3074stp_module_t stp_module_data = 3075 { 3076 "pcl", 3077 VERSION, 3078 "PCL family driver", 3079 STP_MODULE_CLASS_FAMILY, 3080 NULL, 3081 print_pcl_module_init, 3082 print_pcl_module_exit, 3083 (void *) &print_pcl_module_data 3084 }; 3085 3086