File: common\printer.c

    1 /*  Printer.c
    2  *      Simple screen printing functions for FRACTINT
    3  *      By Matt Saucier CIS: [72371,3101]      7/2/89
    4  *      "True-to-the-spirit" of FRACTINT, this code makes few checks that you
    5  *      have specified a valid resolution for the printer (just in case yours
    6  *      has more dots/line than the Standard HP and IBM/EPSON,
    7  *      (eg, Wide Carriage, etc.))
    8  *
    9  *      PostScript support by Scott Taylor [72401,410] / (DGWM18A)   10/8/90
   10  *      For PostScript, use 'printer=PostScript/resolution' where resolution
   11  *      is ANY NUMBER between 10 and 600. Common values: 300,150,100,75.
   12  *      Default resolution for PostScript is 150 pixels/inch.
   13  *      At 200 DPI, a fractal that is 640x480 prints as a 3.2"x2.4" picture.
   14  *      PostScript printer names:
   15  *
   16  *      PostScript/PS                   = Portrait printing
   17  *      PostScriptH/PostScriptL/PSH/PSL = Landscape printing
   18  *
   19  *      This code supports printers attached to a LPTx (1-3) parallel port.
   20  *      It also now supports serial printers AFTER THEY ARE CONFIGURED AND
   21  *      WORKING WITH THE DOS MODE COMMAND, eg. MODE COM1:9600,n,8,1 (for HP)
   22  *      (NOW you can also configure the serial port with the comport= command)
   23  *      Printing calls are made directly to the BIOS for DOS can't handle fast
   24  *      transfer of data to the HP.  (Or maybe visa-versa, HP can't handle the
   25  *      slow transfer of data from DOS)
   26  *
   27  *      I just added direct port access for COM1 and COM2 **ONLY**. This method
   28  *      does a little more testing than BIOS, and may work (especially on
   29  *      serial printer sharing devices) where the old method doesn't. I noticed
   30  *      maybe a 5% speed increase at 9600 baud. These are selected in the
   31  *      printer=.../.../31 for COM1 or 32 for COM2.
   32  *
   33  *      I also added direct parallel port access for LPT1 and LPT2 **ONLY**.
   34  *      This toggles the "INIT" line of the parallel port to reset the printer
   35  *      for each print session. It will also WAIT for a error / out of paper /
   36  *      not selected condition instead of quitting with an error.
   37  *
   38  *      Supported Printers:     Tested Ok:
   39  *       HP LaserJet
   40  *          LJ+,LJII             MDS
   41  *       Toshiba PageLaser       MDS (Set FRACTINT to use HP)
   42  *       IBM Graphics            MDS
   43  *       EPSON
   44  *          Models?              Untested.
   45  *       IBM LaserPrinter
   46  *          with PostScript      SWT
   47  *       HP Plotter              SWT
   48  *
   49  *      Future support to include OKI 20 (color) printer, and just about
   50  *      any printer you request.
   51  *
   52  *      Future modifications to include a more flexible, standard interface
   53  *      with the surrounding program, for easier portability to other
   54  *      programs.
   55  *
   56  * PostScript Styles:
   57  *  0  Dot
   58  *  1  Dot*            [Smoother]
   59  *  2  Inverted Dot
   60  *  3  Ring
   61  *  4  Inverted Ring
   62  *  5  Triangle        [45-45-90]
   63  *  6  Triangle*       [30-75-75]
   64  *  7  Grid
   65  *  8  Diamond
   66  *  9  Line
   67  * 10  Microwaves
   68  * 11  Ellipse
   69  * 12  RoundBox
   70  * 13  Custom
   71  * 14  Star
   72  * 15  Random
   73  * 16  Line*           [Not much different]
   74  *
   75  *  *  Alternate style
   76  *
   77 
   78  */
   79 
   80 
   81 #ifndef XFRACT
   82 #include <bios.h>
   83 #include <io.h>
   84 #endif
   85 
   86 #include <fcntl.h>
   87 #include <sys/types.h>
   88 #include <errno.h>
   89 
   90 #ifndef XFRACT
   91 #include <conio.h>
   92 #endif
   93 
   94 #ifndef USE_VARARGS
   95 #include <stdarg.h>
96 #else 97 #include <varargs.h>
98 #endif 99 100 #include <string.h> 101 102 /* see Fractint.c for a description of the "include" hierarchy */ 103 #include "port.h" 104 #include "prototyp.h" 105 #include "fractype.h" 106 107 /* macros for near-space-saving purposes */ 108 /* CAE 9211 changed these for BC++ */ 109 110 #define PRINTER_PRINTF1(X) {\ 111 static FCODE tmp[] = X;\ 112 Printer_printf(tmp);\ 113 } 114 115 #define PRINTER_PRINTF2(X,Y) {\ 116 static FCODE tmp[] = X;\ 117 Printer_printf(tmp,(Y));\ 118 } 119 #define PRINTER_PRINTF3(X,Y,Z) {\ 120 static FCODE tmp[] = X;\ 121 Printer_printf(tmp,(Y),(Z));\ 122 } 123 #define PRINTER_PRINTF4(X,Y,Z,W) {\ 124 static FCODE tmp[] = X;\ 125 Printer_printf(tmp,(Y),(Z),(W));\ 126 } 127 #define PRINTER_PRINTF5(X,Y,Z,W,V) {\ 128 static FCODE tmp[] = X;\ 129 Printer_printf(tmp,(Y),(Z),(W),(V));\ 130 } 131 #define PRINTER_PRINTF6(X,Y,Z,W,V,U) {\ 132 static FCODE tmp[] = X;\ 133 Printer_printf(tmp,(Y),(Z),(W),(V),(U));\ 134 } 135 #define PRINTER_PRINTF7(X,Y,Z,W,V,U,T) {\ 136 static FCODE tmp[] = X;\ 137 Printer_printf(tmp,(Y),(Z),(W),(V),(U),(T));\ 138 } 139 140 /******** PROTOTYPES ********/ 141 142 #ifndef USE_VARARGS 143 static void Printer_printf(char far *fmt,...);
144 #else 145 static void Printer_printf();
146 #endif 147 static int _fastcall printer(int c); 148 static void _fastcall print_title(int,int,char *); 149 static void printer_reset(void); 150 static void rleprolog(int x,int y); 151 static void _fastcall graphics_init(int,int,char *); 152 153 /******** GLOBALS ********/ 154 155 int Printer_Resolution, /* 75,100,150,300 for HP; */ 156 /* 60,120,240 for IBM; */ 157 /* 90 or 180 for the PaintJet; */ 158 /* 10-600 for PS */ 159 /* 1-20 for Plotter */ 160 LPTNumber, /* ==1,2,3 LPTx; or 11,12,13,14 for COM1-4 */ 161 /* 21,22 for direct port access for LPT1-2 */ 162 /* 31,32 for direct port access for COM1-2 */ 163 Printer_Type, /* ==1 HP, 164 ==2 IBM/EPSON, 165 ==3 Epson color, 166 ==4 HP PaintJet, 167 ==5,6 PostScript, 168 ==7 HP Plotter */ 169 Printer_Titleblock, /* Print info about the fractal? */ 170 Printer_Compress, /* PostScript only - rle encode output */ 171 Printer_ColorXlat, /* PostScript only - invert colors */ 172 Printer_SetScreen, /* PostScript only - reprogram halftone ? */ 173 Printer_SFrequency, /* PostScript only - Halftone Frequency K */ 174 Printer_SAngle, /* PostScript only - Halftone angle K */ 175 Printer_SStyle, /* PostScript only - Halftone style K */ 176 Printer_RFrequency, /* PostScript only - Halftone Frequency R */ 177 Printer_RAngle, /* PostScript only - Halftone angle R */ 178 Printer_RStyle, /* PostScript only - Halftone style R */ 179 Printer_GFrequency, /* PostScript only - Halftone Frequency G */ 180 Printer_GAngle, /* PostScript only - Halftone angle G */ 181 Printer_GStyle, /* PostScript only - Halftone style G */ 182 Printer_BFrequency, /* PostScript only - Halftone Frequency B */ 183 Printer_BAngle, /* PostScript only - Halftone angle B */ 184 Printer_BStyle, /* PostScript only - Halftone style B */ 185 Print_To_File, /* Print to file toggle */ 186 EPSFileType, /* EPSFileType - 187 1 = well-behaved, 188 2 = much less behaved, 189 3 = not well behaved */ 190 Printer_CRLF, /* (0) CRLF (1) CR (2) LF */ 191 ColorPS; /* (0) B&W (1) Color */ 192 int pj_width; 193 double ci,ck; 194 195 static int repeat, item, count, repeatitem, itembuf[128], rlebitsperitem, 196 rlebitshift, bitspersample, rleitem, repeatcount, itemsperline, items, 197 /* bitsperitem, */ bitshift2; 198 /* 199 * The tables were copied from Lee Crocker's PGIF program, with 200 * the 8 undithered colors moved to the first 8 table slots. 201 * 202 * This file contains various lookup tables used by PJGIF. Patterns contains 203 * unsigned values representing each of the 330 HP PaintJet colors. Each color 204 * at 90 DPI is composed of four dots in 8 colors. Each hex digit of these 205 * unsigned values represents one of the four dots. Although the PaintJet will 206 * produce these patterns automatically in 90 DPI mode, it is much faster to do 207 * it in software with the PaintJet in 8-color 180 DPI mode. 208 * 209 * 920501 Hans Wolfgang Schulze converted from printera.asm for xfractint. 210 * (hans@garfield.metal2.polymtl.ca) 211 */ 212 213 static UIFCODE pj_patterns [] = { 214 0x7777,0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666, 215 0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007, 216 0x0110,0x0120,0x0130,0x0140,0x0150,0x0160,0x0170,0x0220, 217 0x0230,0x0240,0x0250,0x0260,0x0270,0x0330,0x0340,0x0350, 218 0x0360,0x0370,0x0440,0x0450,0x0460,0x0470,0x0550,0x0560, 219 0x0570,0x0660,0x0670,0x0770,0x0111,0x0112,0x0113,0x0114, 220 0x0115,0x0116,0x0117,0x2012,0x0123,0x0124,0x0125,0x0126, 221 0x0127,0x3013,0x0134,0x0135,0x0136,0x0137,0x4014,0x0145, 222 0x0146,0x0147,0x5015,0x0156,0x0157,0x6016,0x0167,0x7017, 223 0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,0x3023,0x0234, 224 0x0235,0x0236,0x0237,0x4024,0x0245,0x0246,0x0247,0x5025, 225 0x0256,0x0257,0x6026,0x0267,0x7027,0x0333,0x0334,0x0335, 226 0x0336,0x0337,0x4034,0x0345,0x0346,0x0347,0x5035,0x0356, 227 0x0357,0x6036,0x0367,0x7037,0x0444,0x0445,0x0446,0x0447, 228 0x5045,0x0456,0x0457,0x6046,0x0467,0x7047,0x0555,0x0556, 229 0x0557,0x6056,0x0567,0x7057,0x0666,0x0667,0x7067,0x0777, 230 0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,0x2112, 231 0x1123,0x2114,0x2115,0x2116,0x2117,0x3113,0x3114,0x3115, 232 0x3116,0x3117,0x4114,0x4115,0x4116,0x4117,0x5115,0x5116, 233 0x5117,0x6116,0x6117,0x7117,0x1222,0x1223,0x1224,0x1225, 234 0x1226,0x1227,0x3123,0x1234,0x1235,0x1236,0x1237,0x4124, 235 0x1245,0x1246,0x1247,0x5125,0x1256,0x1257,0x6126,0x1267, 236 0x7127,0x1333,0x1334,0x1335,0x1336,0x1337,0x4134,0x1345, 237 0x1346,0x1347,0x5135,0x1356,0x1357,0x6136,0x1367,0x7137, 238 0x1444,0x1445,0x1446,0x1447,0x5145,0x1456,0x1457,0x6146, 239 0x1467,0x7147,0x1555,0x1556,0x1557,0x6156,0x1567,0x7157, 240 0x1666,0x1667,0x7167,0x1777, 0x2223,0x2224,0x2225, 241 0x2226,0x2227,0x3223,0x3224,0x3225,0x3226,0x3227,0x4224, 242 0x4225,0x4226,0x4227,0x5225,0x5226,0x5227,0x6226,0x6227, 243 0x7227,0x2333,0x2334,0x2335,0x2336,0x2337,0x4234,0x2345, 244 0x2346,0x2347,0x5235,0x2356,0x2357,0x6236,0x2367,0x7237, 245 0x2444,0x2445,0x2446,0x2447,0x5245,0x2456,0x2457,0x6246, 246 0x2467,0x7247,0x2555,0x2556,0x2557,0x6256,0x2567,0x7257, 247 0x2666,0x2667,0x7267,0x2777, 0x3334,0x3335,0x3336, 248 0x3337,0x4334,0x4335,0x4336,0x4337,0x5335,0x5336,0x5337, 249 0x6336,0x6337,0x7337,0x3444,0x3445,0x3446,0x3447,0x5345, 250 0x3456,0x3457,0x6346,0x3467,0x7347,0x3555,0x3556,0x3557, 251 0x6356,0x3567,0x7357,0x3666,0x3667,0x7367,0x3777, 252 0x4445,0x4446,0x4447,0x5445,0x5446,0x5447,0x6446,0x6447, 253 0x7447,0x4555,0x4556,0x4557,0x6456,0x4567,0x7457,0x4666, 254 0x4667,0x7467,0x4777, 0x5556,0x5557,0x6556,0x6557, 255 0x7557,0x5666,0x5667,0x7567,0x5777, 0x6667,0x7667, 256 0x6777}; 257 258 /* 259 * The 3 tables below contain the red, green, and blue values (on a scale of 260 * 0..255) of each of the 330 PaintJet colors. These values are based on data 261 * generously provided by HP customer service. 262 * 11 <- changed black's value from this, seemed wrong 263 * 135 <- changed red's value from this 264 * 11 <- changed blue's value from this 265 */ 266 #ifndef XFRACT 267 static BFCODE pj_reds[] = { 268 229, 2,145, 7,227, 9,136, 5, 269 17, 10, 17, 10, 16, 10, 16, 29, 16, 32, 15, 30, 15, 31, 9, 270 15, 10, 15, 9, 13, 37, 15, 32, 16, 36, 10, 15, 9, 13, 30, 15, 271 31, 8, 13, 38, 62, 26, 68, 26, 63, 26, 68, 16, 35, 16, 33, 16, 272 33, 77, 26, 69, 29, 77, 16, 31, 16, 31, 64, 27, 71, 16, 36, 81, 273 9, 15, 10, 15, 8, 13, 37, 15, 31, 15, 33, 10, 15, 9, 13, 29, 274 15, 28, 8, 12, 28, 98, 28, 79, 32, 94, 16, 34, 17, 35, 73, 30, 275 82, 17, 43,101, 11, 15, 10, 13, 29, 15, 27, 9, 13, 25, 65, 27, 276 71, 16, 35, 88, 7, 12, 39,110, 54,146, 53,136, 58,144, 29, 277 57, 28, 53, 29, 56,159, 54,144, 61,160, 27, 51, 28, 52,135, 55, 278 144, 30, 60,159, 14, 23, 15, 22, 14, 21, 64, 30, 58, 32, 64, 15, 279 22, 15, 21, 54, 31, 56, 14, 22, 64,185, 59,160, 69,185, 29, 57, 280 31, 60,145, 63,162, 33, 71,186, 15, 22, 16, 21, 50, 30, 52, 15, 281 21, 54,134, 58,145, 30, 60,161, 15, 22, 69,187, 13, 9, 14, 282 6, 11, 31, 14, 27, 12, 27, 10, 14, 9, 12, 24, 9, 23, 6, 9, 283 22, 76, 23, 61, 25, 74, 15, 29, 14, 28, 55, 23, 62, 12, 30, 73, 284 11, 15, 10, 12, 25, 14, 23, 8, 11, 20, 50, 22, 53, 13, 26, 61, 285 5, 8, 21, 71, 71,189, 87,227, 30, 63, 32, 69,164, 76,190, 286 37, 89,227, 15, 22, 14, 20, 54, 31, 57, 14, 21, 63,147, 67,163, 287 33, 72,191, 13, 24, 94,228, 15, 10, 13, 26, 14, 23, 10, 13, 288 20, 50, 23, 50, 15, 26, 52, 8, 11, 23, 65, 60,147, 32, 67, 289 166, 14, 24, 77,194, 8, 32, 97}; 290 291 /* 292 * 11 <- changed black's value from this, seemed wrong 293 * 65 <- changed green from this 294 */ 295 296 static BFCODE pj_greens[] = { 297 224, 2, 20, 72,211, 10, 11, 55, 298 12, 15, 19, 11, 11, 14, 17, 14, 18, 22, 12, 13, 16, 19, 24, 299 29, 16, 17, 23, 27, 41, 17, 22, 29, 39, 11, 10, 14, 14, 11, 14, 300 17, 21, 25, 40, 16, 21, 28, 14, 16, 19, 25, 28, 37, 18, 20, 26, 301 33, 48, 20, 26, 33, 46, 13, 12, 16, 18, 14, 18, 22, 24, 30, 42, 302 40, 49, 25, 27, 39, 50, 69, 27, 33, 48, 66, 17, 17, 24, 27, 19, 303 28, 35, 38, 48, 68,100, 32, 46, 65, 98, 18, 22, 29, 36, 27, 39, 304 54, 49, 71,105, 11, 10, 14, 12, 10, 14, 13, 20, 20, 25, 11, 15, 305 18, 22, 29, 49, 36, 46, 69,111, 23, 31, 16, 19, 22, 28, 30, 306 37, 20, 22, 28, 34, 54, 22, 29, 36, 53, 14, 15, 17, 19, 17, 19, 307 26, 25, 32, 46, 43, 50, 27, 28, 41, 49, 68, 29, 37, 51, 68, 19, 308 19, 25, 28, 22, 30, 36, 40, 47, 66,104, 35, 51, 68,105, 20, 24, 309 31, 37, 30, 38, 56, 50, 69,103, 13, 12, 15, 14, 13, 15, 16, 21, 310 21, 26, 14, 16, 22, 23, 28, 44, 35, 42, 62,102, 78, 40, 44, 311 65, 78, 98, 43, 53, 76, 99, 26, 27, 36, 40, 29, 43, 50, 63, 75, 312 99,136, 49, 69, 98,142, 28, 32, 42, 51, 39, 52, 73, 77,103,145, 313 17, 17, 21, 21, 18, 22, 24, 34, 37, 43, 19, 23, 30, 40, 48, 69, 314 62, 76,101,147, 72,113,145,218, 33, 42, 52, 71, 61, 77,116, 315 105,148,221, 18, 17, 21, 23, 21, 26, 30, 37, 43, 64, 30, 35, 48, 316 50, 69,115, 77, 99,149,224, 10, 13, 11, 10, 12, 11, 17, 16, 317 15, 9, 11, 12, 17, 17, 22, 26, 27, 36, 61, 14, 18, 21, 26, 318 48, 34, 41, 68,115, 69, 99,149}; 319 320 /* 15 <- changed black's value from this, seemed wrong 321 * 56 <- changed green from this 322 * 163 <- changed cyan from this 323 */ 324 static BFCODE pj_blues[] = { 325 216, 2, 34, 48, 33, 73, 64,168, 326 18, 19, 18, 20, 19, 22, 21, 22, 24, 22, 26, 24, 27, 24, 27, 327 24, 29, 27, 31, 29, 22, 27, 25, 30, 28, 31, 29, 33, 33, 28, 32, 328 32, 41, 40, 46, 28, 32, 28, 34, 30, 36, 31, 35, 32, 38, 34, 41, 329 35, 27, 35, 31, 39, 34, 40, 37, 44, 40, 34, 42, 37, 49, 47, 45, 330 40, 36, 43, 40, 47, 43, 33, 40, 36, 45, 41, 44, 41, 49, 46, 40, 331 49, 45, 58, 56, 58, 30, 38, 34, 44, 40, 42, 39, 49, 46, 38, 49, 332 46, 59, 62, 67, 49, 46, 55, 52, 44, 55, 52, 64, 64, 66, 43, 55, 333 53, 66, 70, 78, 87, 91,101,115, 39, 34, 42, 37, 43, 36, 45, 334 38, 47, 42, 49, 43, 34, 41, 36, 44, 38, 49, 45, 52, 46, 40, 47, 335 42, 56, 51, 45, 49, 45, 52, 48, 56, 50, 40, 47, 44, 52, 47, 54, 336 51, 59, 55, 47, 58, 50, 66, 60, 56, 34, 44, 38, 48, 42, 52, 47, 337 56, 50, 42, 51, 46, 64, 59, 57, 60, 56, 64, 61, 52, 61, 57, 72, 338 67, 64, 48, 58, 53, 69, 65, 65, 87, 83, 87, 94, 53, 59, 55, 339 64, 60, 46, 53, 49, 59, 54, 60, 56, 65, 62, 53, 62, 58, 76, 71, 340 68, 41, 50, 45, 56, 51, 58, 53, 63, 59, 49, 60, 56, 74, 71, 71, 341 66, 63, 73, 70, 60, 69, 67, 84, 81, 79, 55, 67, 64, 84, 81, 83, 342 104,104,106,116, 32, 40, 53, 48, 54, 50, 61, 57, 46, 59, 56, 343 76, 75, 80, 64, 59, 70, 67, 57, 69, 65, 83, 81, 85, 54, 68, 66, 344 86, 88, 96,110,114,125,137, 71, 81, 78, 68, 77, 76, 93, 92, 345 90, 65, 77, 75, 92, 93, 96,117,119,126,138, 78, 79, 98,102, 346 110,124,131,143,157, 173,185,200}; 347 #endif 348 349 static void putitem(void); 350 static void rleputxelval(int); 351 static void rleflush(void); 352 static void rleputrest(void); 353 354 static int LPTn; /* printer number we're gonna use */ 355 356 static FILE *PRFILE; 357 358 #define TONES 17 /* Number of PostScript halftone styles */ 359 360 #if 1 361 static FCODE ht00[] = {"D mul exch D mul add 1 exch sub"}; 362 static FCODE ht01[] = {"abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse"}; 363 static FCODE ht02[] = {"D mul exch D mul add 1 sub"}; 364 static FCODE ht03[] = {"D mul exch D mul add 0.6 exch sub abs -0.5 mul"}; 365 static FCODE ht04[] = {"D mul exch D mul add 0.6 exch sub abs 0.5 mul"}; 366 static FCODE ht05[] = {"add 2 div"}; 367 static FCODE ht06[] = {"2 exch sub exch abs 2 mul sub 3 div"}; 368 static FCODE ht07[] = {"2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div"}; 369 static FCODE ht08[] = {"abs exch abs add 1 exch sub"}; 370 static FCODE ht09[] = {"pop"}; 371 static FCODE ht10[] = {"/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos"}; 372 static FCODE ht11[] = {"D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub"}; 373 static FCODE ht12[] = {"D mul D mul exch D mul D mul add 1 exch sub"}; 374 static FCODE ht13[] = {"D mul exch D mul add sqrt 1 exch sub"}; 375 static FCODE ht14[] = {"abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div"}; 376 static FCODE ht15[] = {"pop pop rand 1 add 10240 mod 5120 div 1 exch sub"}; 377 static FCODE ht16[] = {"pop abs 2 mul 1 exch sub"}; 378 #endif 379 380 static FCODE *HalfTone[TONES]= {ht00,ht01,ht02,ht03,ht04,ht05,ht06,ht07, 381 ht08,ht09,ht10,ht11,ht12,ht13,ht14,ht15,ht16}; 382 383 #if 0
384 "D mul exch D mul add 1 exch sub", 385 "abs exch abs 2 copy add 1 gt {1 sub D mul exch 1 sub D mul add 1 sub} {D mul exch D mul add 1 exch sub} ifelse", 386 "D mul exch D mul add 1 sub", 387 "D mul exch D mul add 0.6 exch sub abs -0.5 mul", 388 "D mul exch D mul add 0.6 exch sub abs 0.5 mul", 389 "add 2 div", 390 "2 exch sub exch abs 2 mul sub 3 div", 391 "2 copy abs exch abs gt {exch} if pop 2 mul 1 exch sub 3.5 div", 392 "abs exch abs add 1 exch sub", 393 "pop", 394 "/wy exch def 180 mul cos 2 div wy D D D mul mul sub mul wy add 180 mul cos", 395 "D 5 mul 8 div mul exch D mul exch add sqrt 1 exch sub", 396 "D mul D mul exch D mul D mul add 1 exch sub", 397 "D mul exch D mul add sqrt 1 exch sub", 398 "abs exch abs 2 copy gt {exch} if 1 sub D 0 eq {0.01 add} if atan 360 div", 399 "pop pop rand 1 add 10240 mod 5120 div 1 exch sub", 400 "pop abs 2 mul 1 exch sub" 401 };
402 #endif 403 404 #ifdef __BORLANDC__
405 #if(__BORLANDC__ > 2) 406 #pragma warn -eff 407 #endif
408 #endif 409 410 static char EndOfLine[3]; 411 412 /* workaround for the old illicit decflaration of dstack */ 413 414 typedef int (*TRIPLE)[2][3][400]; 415 #define triple (*((TRIPLE)dstack)) 416 417 void 418 Print_Screen (void) 419 { 420 int y,j; 421 char buff[192]; /* buffer for 192 sets of pixels */ 422 /* This is very large so that we can*/ 423 /* get reasonable times printing */ 424 /* from modes like MAXPIXELSxMAXPIXELS disk-*/ 425 /* video. When this was 24, a MAXPIXELS*/ 426 /* by MAXPIXELS pic took over 2 hours to*/ 427 /* print. It takes about 15 min now*/ 428 int BuffSiz; /* how much of buff[] we'll use */ 429 char far *es; /* pointer to extraseg for buffer */ 430 int i,x,k, /* more indices */ 431 imax, /* maximum i value (ydots/8) */ 432 res, /* resolution we're gonna' use */ 433 high, /* if LPTn>10 COM == com port to use*/ 434 low, /* misc */ 435 /************************************/ 436 ptrid; /* Printer Id code. */ 437 /* Currently, the following are */ 438 /* assigned: */ 439 /* 1. HPLJ (all) */ 440 /* Toshiba PageLaser*/ 441 /* 2. IBM Graphics */ 442 /* 3. Color Printer */ 443 /* 4. HP PaintJet */ 444 /* 5. PostScript */ 445 /************************************/ 446 int pj_color_ptr[256]; /* Paintjet color translation */ 447 448 /******** SETUP VARIABLES ********/ 449 memset(buff,0,192); 450 i = 0; 451 452 EndOfLine[0]=(char)(((Printer_CRLF==1) || (Printer_CRLF==0)) ? 0x0D : 0x0A); 453 EndOfLine[1]=(char)((Printer_CRLF==0) ? 0x0A : 0x00); 454 EndOfLine[2]=0x00; 455 456 if (Print_To_File>0) 457 { 458 while ((PRFILE = fopen(PrintName,"r")) != NULL) { 459 j = fgetc(PRFILE); 460 fclose(PRFILE); 461 if (j == EOF) break; 462 updatesavename((char *)PrintName); 463 } 464 if ((PRFILE = fopen(PrintName,"wb")) == NULL) Print_To_File = 0; 465 } 466 467 #ifdef XFRACT
468 putstring(3,0,0,"Printing to:"); 469 putstring(4,0,0,PrintName); 470 putstring(5,0,0," ");
471 #endif 472 473 es=MK_FP(extraseg,0); 474 475 LPTn=LPTNumber-1; 476 if (((LPTn>2)&&(LPTn<10))|| 477 ((LPTn>13)&&(LPTn<20))|| 478 ((LPTn>21)&&(LPTn<30))|| 479 (LPTn<0)||(LPTn>31)) LPTn=0; /* default of LPT1 (==0) */ 480 ptrid=Printer_Type; 481 if ((ptrid<1)||(ptrid>7)) ptrid=2; /* default of IBM/EPSON */ 482 res=Printer_Resolution; 483 #ifndef XFRACT 484 if ((LPTn==20)||(LPTn==21)) 485 { 486 k = (inp((LPTn==20) ? 0x37A : 0x27A)) & 0xF7; 487 outp((LPTn==20) ? 0x37A : 0x27A,k); 488 k = k & 0xFB; 489 outp((LPTn==20) ? 0x37A : 0x27A,k); 490 k = k | 0x0C; 491 outp((LPTn==20) ? 0x37A : 0x27A,k); 492 } 493 if ((LPTn==30)||(LPTn==31)) 494 { 495 outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00); 496 outp((LPTn==30) ? 0x3FC : 0x2FC,0x00); 497 outp((LPTn==30) ? 0x3FC : 0x2FC,0x03); 498 } 499 #endif 500 501 switch (ptrid) { 502 503 case 1: 504 if (res<75) res=75; 505 if ( (res<= 75)&&(ydots> 600)) res=100; 506 if ( (res<=100)&&(ydots> 800)) res=150; 507 if (((res<=150)&&(ydots>1200))||(res>300)) res=300; 508 break; 509 510 case 2: 511 case 3: 512 if (res<60) res=60; 513 if ((res<=60)&&(ydots>480)) res=120; 514 if (((res<=120)&&(ydots>960))||(res>240)) res=240; 515 break; 516 517 case 4: /****** PaintJet *****/ 518 { 519 #ifndef XFRACT 520 /* Pieter Branderhorst: 521 My apologies if the numbers and approach here seem to be 522 picked out of a hat. They were. They happen to result in 523 a tolerable mapping of screen colors to printer colors on 524 my machine. There are two sources of error in getting colors 525 to come out right. 526 1) Must match some dacbox values to the 330 PaintJet dithered 527 colors so that they look the same. For this we use HP's 528 color values in printera.asm and modify by gamma separately 529 for each of red/green/blue. This mapping is ok if the 530 preview shown on screen is a fairly close match to what 531 gets printed. The defaults are what work for me. 532 2) Must find nearest color in HP palette to each color in 533 current image. For this we use Lee Crocker's least sum of 534 differences squared approach, modified to spread the 535 values using gamma 1.7. This mods was arrived at by 536 trial and error, just because it improves the mapping. 537 */ 538 long ldist; 539 int r,g,b; 540 double gamma_val,gammadiv; 541 BYTE convert[256]; 542 BYTE scale[64]; 543 544 BYTE far *table_ptr = NULL; 545 res = (res < 150) ? 90 : 180; /* 90 or 180 dpi */ 546 if (Printer_SetScreen == 0) { 547 Printer_SFrequency = 21; /* default red gamma */ 548 Printer_SAngle = 19; /* green gamma */ 549 Printer_SStyle = 16; /* blue gamma */ 550 } 551 /* Convert the values in printera.asm. We might do this just */ 552 /* once per run, but we'd need separate memory for that - can't */ 553 /* just convert table in-place cause it could be in an overlay, */ 554 /* might be paged out and then back in in original form. Also, */ 555 /* user might change gammas with a .par file entry mid-run. */ 556 for (j = 0; j < 3; ++j) { 557 switch (j) { 558 case 0: table_ptr = pj_reds; 559 i = Printer_SFrequency; 560 break; 561 case 1: table_ptr = pj_greens; 562 i = Printer_SAngle; 563 break; 564 case 2: table_ptr = pj_blues; 565 i = Printer_SStyle; 566 } 567 gamma_val = 10.0 / i; 568 gammadiv = pow(255,gamma_val) / 255; 569 for (i = 0; i < 256; ++i) { /* build gamma conversion table */ 570 static FCODE msg[]={"Calculating color translation"}; 571 if ((i & 15) == 15) 572 thinking(1,msg); 573 convert[i] = (BYTE)((pow((double)i,gamma_val) / gammadiv) + 0.5); 574 } 575 for (i = 0; i < 330; ++i) { 576 k = convert[table_ptr[i]]; 577 if (k > 252) k = 252; 578 triple[0][j][i] = (k + 2) >> 2; 579 } 580 } 581 /* build comparison lookup table */ 582 gamma_val = 1.7; 583 gammadiv = pow(63,gamma_val) / 63; 584 for (i = 0; i < 64; ++i) { 585 if ((j = (int)((pow((double)i,gamma_val) / gammadiv) * 4 + 0.5)) < i) 586 j = i; 587 scale[i] = (char)j; 588 } 589 for (i = 0; i < 3; ++i) /* convert values via lookup */ 590 for (j = 0; j < 330; ++j) 591 triple[1][i][j] = scale[triple[0][i][j]]; 592 /* Following code and the later code which writes to Paintjet */ 593 /* using pj_patterns was adapted from Lee Crocker's PGIF program */ 594 for (i = 0; i < colors; ++i) { /* find nearest match colors */ 595 r = scale[dacbox[i][0]]; 596 g = scale[dacbox[i][1]]; 597 b = scale[dacbox[i][2]]; 598 ldist = 9999999L; 599 /* check variance vs each PaintJet color */ 600 /* if high-res 8 color mode, consider only 1st 8 colors */ 601 j = (res == 90) ? 330 : 8; 602 while (--j >= 0) { 603 long dist; 604 dist = (unsigned)(r-triple[1][0][j]) * (r-triple[1][0][j]); 605 dist += (unsigned)(g-triple[1][1][j]) * (g-triple[1][1][j]); 606 dist += (unsigned)(b-triple[1][2][j]) * (b-triple[1][2][j]); 607 if (dist < ldist) { 608 ldist = dist; 609 k = j; 610 } 611 } 612 pj_color_ptr[i] = k; /* remember best fit */ 613 } 614 thinking(0,NULL); 615 /* if (debugflag == 900 || debugflag == 902) { 616 color_test(); 617 return; 618 } */ 619 if (dotmode != 11) { /* preview */ 620 static char far msg[] = {"Preview. Enter=go, Esc=cancel, k=keep"}; 621 memcpy(triple[1],dacbox,768); 622 for (i = 0; i < colors; ++i) 623 for (j = 0; j < 3; ++j) 624 dacbox[i][j] = (BYTE)triple[0][j][pj_color_ptr[i]]; 625 spindac(0,1); 626 texttempmsg(msg); 627 i = getakeynohelp(); 628 if (i == 'K' || i == 'k') { 629 return; 630 } 631 memcpy(dacbox,triple[1],768); 632 spindac(0,1); 633 if (i == 0x1B) { 634 return; 635 } 636 } 637 break; 638 #endif 639 } 640 641 case 5: 642 case 6: /***** PostScript *****/ 643 if ( res < 10 && res != 0 ) res = 10; /* PostScript scales... */ 644 if ( res > 600 ) res = 600; /* it can handle any range! */ 645 if ((Printer_SStyle < 0) || (Printer_SStyle >= TONES)) 646 Printer_SStyle = 0; 647 break; 648 } 649 650 /***** Set up buffer size for immediate user gratification *****/ 651 /***** AKA, if we don't have to, don't buffer the data *****/ 652 BuffSiz=8; 653 if (xdots>1024) BuffSiz=192; 654 655 /***** Initialize printer *****/ 656 if (Print_To_File < 1) { 657 printer_reset(); 658 /* wait a bit, some printers need time after reset */ 659 delay((ptrid == 4) ? 2000 : 500); 660 } 661 662 /****** INITIALIZE GRAPHICS MODES ******/ 663 664 graphics_init(ptrid,res,EndOfLine); 665 666 if (keypressed()) { /* one last chance before we start...*/ 667 return; 668 } 669 670 memset(buff,0,192); 671 672 /***** Get And Print Screen **** */ 673 switch (ptrid) { 674 675 case 1: /* HP LaserJet (et al) */ 676 imax=(ydots/8)-1; 677 for (x=0;((x<xdots)&&(!keypressed()));x+=BuffSiz) { 678 for (i=imax;((i>=0)&&(!keypressed()));i--) { 679 for (y=7;((y>=0)&&(!keypressed()));y--) { 680 for (j=0;j<BuffSiz;j++) { 681 if ((x+j)<xdots) { 682 buff[j]<<=1; 683 buff[j]=(char)(buff[j]+(char)(getcolor(x+j,i*8+y)&1)); 684 } 685 } 686 } 687 for (j=0;j<BuffSiz;j++) { 688 *(es+j+BuffSiz*i)=buff[j]; 689 buff[j]=0; 690 } 691 } 692 for (j=0;((j<BuffSiz)&&(!keypressed()));j++) { 693 if ((x+j)<xdots) { 694 PRINTER_PRINTF2("\033*b%iW",imax+1); 695 for (i=imax;((i>=0)&&(!keypressed()));i--) { 696 printer(*(es+j+BuffSiz*i)); 697 } 698 } 699 } 700 } 701 if (!keypressed()) PRINTER_PRINTF1("\033*rB\014"); 702 break; 703 704 case 2: /* IBM Graphics/Epson */ 705 for (x=0;((x<xdots)&&(!keypressed()));x+=8) { 706 switch (res) { 707 case 60: Printer_printf("\033K"); break; 708 case 120: Printer_printf("\033L"); break; 709 case 240: Printer_printf("\033Z"); break; 710 } 711 high=ydots/256; 712 low=ydots-(high*256); 713 printer(low); 714 printer(high); 715 for (y=ydots-1;(y>=0);y--) { 716 buff[0]=0; 717 for (i=0;i<8;i++) { 718 buff[0]<<=1; 719 buff[0]=(char)(buff[0]+(char)(getcolor(x+i,y)&1)); 720 } 721 printer(buff[0]); 722 } 723 if (keypressed()) break; 724 Printer_printf(EndOfLine); 725 } 726 if (!keypressed()) printer(12); 727 break; 728 729 case 3: /* IBM Graphics/Epson Color */ 730 high=ydots/256; 731 low=ydots%256; 732 for (x=0;((x<xdots)&&(!keypressed()));x+=8) 733 { 734 for (k=0; k<8; k++) /* colors */ 735 { 736 Printer_printf("\033r%d",k); /* set printer color */ 737 switch (res) 738 { 739 case 60: Printer_printf("\033K"); break; 740 case 120: Printer_printf("\033L"); break; 741 case 240: Printer_printf("\033Z"); break; 742 } 743 printer(low); 744 printer(high); 745 for (y=ydots-1;y>=0;y--) 746 { 747 buff[0]=0; 748 for (i=0;i<8;i++) 749 { 750 buff[0]<<=1; 751 if ((getcolor(x+i,y)%8)==k) 752 buff[0]++; 753 } 754 printer(buff[0]); 755 } 756 if (Printer_CRLF<2) printer(13); 757 } 758 if ((Printer_CRLF==0) || (Printer_CRLF==2)) printer(10); 759 } 760 printer(12); 761 printer(12); 762 printer_reset(); 763 break; 764 765 case 4: /* HP PaintJet */ 766 { 767 unsigned int fetchrows,fetched; 768 BYTE far *pixels = NULL, far *nextpixel = NULL; 769 /* for reasonable speed when using disk video, try to fetch 770 and store the info for 8 columns at a time instead of 771 doing getcolor calls down each column in separate passes */ 772 fetchrows = 16; 773 for(;;) { 774 if ((pixels = (BYTE far *)farmemalloc((long)(fetchrows)*ydots)) != NULL) 775 break; 776 if ((fetchrows >>= 1) == 0) { 777 static char far msg[]={"insufficient memory"}; 778 stopmsg(0,msg); 779 break; 780 } 781 } 782 if (!pixels) break; 783 fetched = 0; 784 for (x = 0; (x < xdots && !keypressed()); ++x) { 785 if (fetched == 0) { 786 if ((fetched = xdots-x) > fetchrows) 787 fetched = fetchrows; 788 for (y = ydots-1; y >= 0; --y) { 789 if (debugflag == 602) /* flip image */ 790 nextpixel = pixels + y; 791 else /* reverse order for unflipped */ 792 nextpixel = pixels + ydots-1 - y; 793 for (i = 0; i < (int)fetched; ++i) { 794 *nextpixel = (BYTE)getcolor(x+i,y); 795 nextpixel += ydots; 796 } 797 } 798 nextpixel = pixels; 799 } 800 --fetched; 801 if (res == 180) { /* high-res 8 color mode */ 802 int offset; 803 BYTE bitmask; 804 offset = -1; 805 bitmask = 0; 806 for (y = ydots - 1; y >= 0; --y) { 807 BYTE color; 808 if ((bitmask >>= 1) == 0) { 809 ++offset; 810 triple[0][0][offset] = triple[0][1][offset] 811 = triple[0][2][offset] = 0; 812 bitmask = 0x80; 813 } 814 /* translate 01234567 to 70123456 */ 815 color = (BYTE)(pj_color_ptr[*(nextpixel++)] - 1); 816 if ((color & 1)) triple[0][0][offset] += bitmask; 817 if ((color & 2)) triple[0][1][offset] += bitmask; 818 if ((color & 4)) triple[0][2][offset] += bitmask; 819 } 820 } 821 else { /* 90 dpi, build 2 lines, 2 dots per pixel */ 822 int bitct,offset; 823 bitct = offset = 0; 824 for (y = ydots - 1; y >= 0; --y) { 825 unsigned int color; 826 color = pj_patterns[pj_color_ptr[*(nextpixel++)]]; 827 for (i = 0; i < 3; ++i) { 828 BYTE *bufptr; 829 bufptr = (BYTE *)&triple[0][i][offset]; 830 *bufptr <<= 2; 831 if ((color & 0x1000)) *bufptr += 2; 832 if ((color & 0x0100)) ++*bufptr; 833 bufptr = (BYTE *)&triple[1][i][offset]; 834 *bufptr <<= 2; 835 if ((color & 0x0010)) *bufptr += 2; 836 if ((color & 0x0001)) ++*bufptr; 837 color >>= 1; 838 } 839 if (++bitct == 4) { 840 bitct = 0; 841 ++offset; 842 } 843 } 844 } 845 for (i = 0; i < ((res == 90) ? 2 : 1); ++i) { 846 for (j = 0; j < 3; ++j) { 847 BYTE *bufptr,*bufend; 848 Printer_printf((j < 2) ? "\033*b%dV" : "\033*b%dW", 849 pj_width); 850 bufend = pj_width + (bufptr = (BYTE *)(triple[i][j])); 851 do { 852 while (printer(*bufptr)) { } 853 } while (++bufptr < bufend); 854 } 855 } 856 } 857 PRINTER_PRINTF1("\033*r0B"); /* end raster graphics */ 858 if (!keypressed()) { 859 if (debugflag != 600) 860 printer(12); /* form feed */ 861 else 862 Printer_printf("\n\n"); 863 } 864 farmemfree(pixels); 865 break; 866 } 867 868 case 5: 869 case 6: /***** PostScript Portrait & Landscape *****/ 870 { 871 char convert[513]; 872 if (!ColorPS) { 873 for (i=0; i<256; ++i) 874 if (Printer_Compress) { 875 convert[i] = (char)((.3*255./63. * (double)dacbox[i][0])+ 876 (.59*255./63. * (double)dacbox[i][1])+ 877 (.11*255./63. * (double)dacbox[i][2])); 878 } else 879 { 880 sprintf(&convert[2*i], "%02X", 881 (int)((.3*255./63. * (double)dacbox[i][0])+ 882 (.59*255./63. * (double)dacbox[i][1])+ 883 (.11*255./63. * (double)dacbox[i][2]))); 884 } 885 } 886 i=0; 887 j=0; 888 for (y=0;((y<ydots)&&(!keypressed()));y++) 889 { unsigned char bit8 = 0; 890 if (Printer_Compress) { 891 if (ColorPS) { 892 for (x=0;x<xdots;x++) { 893 k=getcolor(x,y); 894 rleputxelval((int)dacbox[k][0]<<2); 895 } 896 rleflush(); 897 for (x=0;x<xdots;x++) { 898 k=getcolor(x,y); 899 rleputxelval((int)dacbox[k][1]<<2); 900 } 901 rleflush(); 902 for (x=0;x<xdots;x++) { 903 k=getcolor(x,y); 904 rleputxelval((int)dacbox[k][2]<<2); 905 } 906 rleflush(); 907 } else { 908 if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) { 909 for (x=0;x<xdots;x++) { 910 k=getcolor(x,y); 911 k=getcolor(x,y) & 1; 912 if (x % 8 == 0) { 913 if (x) rleputxelval((int)bit8); 914 if (k) bit8 = 1; else bit8 = 0; 915 } 916 else 917 bit8 = (unsigned char)((bit8 << 1) + ((k) ? 1 : 0)); 918 } 919 if (xdots % 8) bit8 <<= (8 - (xdots % 8)); 920 rleputxelval((int)bit8); 921 rleflush(); 922 } else { 923 for (x=0;x<xdots;x++) { 924 k=getcolor(x,y); 925 rleputxelval((int)(unsigned char)convert[k]); 926 } 927 rleflush(); 928 } 929 } 930 } else 931 { 932 for (x=0;x<xdots;x++) 933 { 934 k=getcolor(x,y); 935 if (ColorPS) 936 { 937 sprintf(&buff[i], "%02X%02X%02X", dacbox[k][0]<<2, 938 dacbox[k][1]<<2, 939 dacbox[k][2]<<2); 940 i+=6; 941 } 942 else 943 { 944 k*=2; 945 buff[i++]=convert[k]; 946 buff[i++]=convert[k+1]; 947 } 948 if (i>=64) 949 { 950 strcpy(&buff[i]," "); 951 Printer_printf("%s%s",buff,EndOfLine); 952 i=0; 953 j++; 954 if (j>9) 955 { 956 j=0; 957 Printer_printf(EndOfLine); 958 } 959 } 960 } 961 } 962 } 963 if (Printer_Compress) { 964 rleputrest(); 965 } else { 966 strcpy(&buff[i]," "); 967 Printer_printf("%s%s",buff,EndOfLine); 968 i=0; 969 j++; 970 if (j>9) 971 { 972 j=0; 973 Printer_printf(EndOfLine); 974 } 975 } 976 if ( (EPSFileType > 0) && (EPSFileType <3) ) 977 { 978 PRINTER_PRINTF4("%s%%%%Trailer%sEPSFsave restore%s",EndOfLine, 979 EndOfLine,EndOfLine); 980 } 981 else 982 { 983 #ifndef XFRACT 984 PRINTER_PRINTF4("%sshowpage%s%c",EndOfLine,EndOfLine,4);
985 #else 986 PRINTER_PRINTF3("%sshowpage%s",EndOfLine,EndOfLine);
987 #endif 988 } 989 break; 990 } 991 992 case 7: /* HP Plotter */ 993 { 994 double parm1=0,parm2=0; 995 for (i=0;i<3;i++) 996 { 997 PRINTER_PRINTF4("%sSP %d;%s\0",EndOfLine,(i+1),EndOfLine); 998 for (y=0;(y<ydots)&&(!keypressed());y++) 999 { 1000 for (x=0;x<xdots;x++) 1001 { 1002 j=dacbox[getcolor(x,y)][i]; 1003 if (j>0) 1004 { 1005 switch(Printer_SStyle) 1006 { 1007 case 0: 1008 ci=0.004582144*(double)j; 1009 ck= -.007936057*(double)j; 1010 parm1 = (double)x+.5+ci+(((double)i-1.0)/3); 1011 parm2 = (double)y+.5+ck; 1012 break; 1013 case 1: 1014 ci= -.004582144*(double)j+(((double)i+1.0)/8.0); 1015 ck= -.007936057*(double)j; 1016 parm1 = (double)x+.5+ci; 1017 parm2 = (double)y+.5+ck; 1018 break; 1019 case 2: 1020 ci= -.0078125*(double)j+(((double)i+1.0)*.003906250); 1021 ck= -.0078125*(double)j; 1022 parm1 = (double)x+.5+ci; 1023 parm2 = (double)y+.5+ck; 1024 break; 1025 } 1026 PRINTER_PRINTF5("PA %f,%f;PD;PR %f,%f;PU;\0", 1027 parm1,parm2, ci*((double)-2), ck*((double)-2)); 1028 } 1029 } 1030 } 1031 } 1032 PRINTER_PRINTF3("%s;SC;PA 0,0;SP0;%s\0",EndOfLine,EndOfLine); 1033 PRINTER_PRINTF2(";;SP 0;%s\0",EndOfLine); 1034 break; 1035 } 1036 } 1037 1038 if (Print_To_File > 0) fclose(PRFILE); 1039 #ifndef XFRACT 1040 if ((LPTn==30)||(LPTn==31)) 1041 { 1042 for (x=0;x<2000;x++); 1043 outp((LPTn==30) ? 0x3FC : 0x2FC,0x00); 1044 outp((LPTn==30) ? 0x3F9 : 0x2F9,0x00); 1045 }
1046 #else 1047 putstring(5,0,0,"Printing done\n");
1048 #endif 1049 } 1050 1051 1052 static void _fastcall graphics_init(int ptrid,int res,char *EndOfLine) 1053 { 1054 int i,j; 1055 1056 switch (ptrid) { 1057 1058 case 1: 1059 print_title(ptrid,res,EndOfLine); 1060 PRINTER_PRINTF2("\033*t%iR\033*r0A",res);/* HP */ 1061 break; 1062 1063 case 2: 1064 case 3: 1065 print_title(ptrid,res,EndOfLine); 1066 PRINTER_PRINTF1("\033\063\030");/* IBM */ 1067 break; 1068 1069 case 4: /****** PaintJet *****/ 1070 print_title(ptrid,res,EndOfLine); 1071 pj_width = ydots; 1072 if (res == 90) pj_width <<= 1; 1073 PRINTER_PRINTF2("\033*r0B\033*t180R\033*r3U\033*r%dS\033*b0M\033*r0A", 1074 pj_width); 1075 pj_width >>= 3; 1076 break; 1077 1078 case 5: /***** PostScript *****/ 1079 case 6: /***** PostScript Landscape *****/ 1080 if (!((EPSFileType > 0) && (ptrid==5))) 1081 PRINTER_PRINTF2("%%!PS-Adobe%s",EndOfLine); 1082 if ((EPSFileType > 0) && /* Only needed if saving to .EPS */ 1083 (ptrid == 5)) 1084 { 1085 PRINTER_PRINTF2("%%!PS-Adobe-1.0 EPSF-2.0%s",EndOfLine); 1086 1087 if (EPSFileType==1) 1088 i=xdots+78; 1089 else 1090 i=(int)((double)xdots * (72.0 / (double)res))+78; 1091 1092 if (Printer_Titleblock==0) 1093 { 1094 if (EPSFileType==1) { j = ydots + 78; } 1095 else { j = (int)(((double)ydots * (72.0 / (double)res) / (double)finalaspectratio)+78); } 1096 } 1097 else 1098 { 1099 if (EPSFileType==1) { j = ydots + 123; } 1100 else { j = (int)(((double)ydots * (72.0 / (double)res))+123); } 1101 } 1102 PRINTER_PRINTF4("%%%%TemplateBox: 12 12 %d %d%s",i,j,EndOfLine); 1103 PRINTER_PRINTF4("%%%%BoundingBox: 12 12 %d %d%s",i,j,EndOfLine); 1104 PRINTER_PRINTF4("%%%%PrinterRect: 12 12 %d %d%s",i,j,EndOfLine); 1105 PRINTER_PRINTF2("%%%%Creator: Fractint PostScript%s",EndOfLine); 1106 PRINTER_PRINTF5("%%%%Title: A %s fractal - %s - Fractint EPSF Type %d%s", 1107 curfractalspecific->name[0]=='*' ? 1108 &curfractalspecific->name[1] : 1109 curfractalspecific->name, 1110 PrintName, 1111 EPSFileType, 1112 EndOfLine); 1113 if (Printer_Titleblock==1) 1114 PRINTER_PRINTF2("%%%%DocumentFonts: Helvetica%s",EndOfLine); 1115 PRINTER_PRINTF2("%%%%EndComments%s",EndOfLine); 1116 PRINTER_PRINTF2("/EPSFsave save def%s",EndOfLine); 1117 PRINTER_PRINTF2("0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin%s",EndOfLine); 1118 PRINTER_PRINTF2("10 setmiterlimit [] 0 setdash newpath%s",EndOfLine); 1119 } 1120 1121 /* Common code for all PostScript */ 1122 PRINTER_PRINTF2("/Tr {translate} def%s",EndOfLine); 1123 PRINTER_PRINTF2("/Mv {moveto} def%s",EndOfLine); 1124 PRINTER_PRINTF2("/D {dup} def%s",EndOfLine); 1125 PRINTER_PRINTF2("/Rh {readhexstring} def%s",EndOfLine); 1126 PRINTER_PRINTF2("/Cf {currentfile} def%s",EndOfLine); 1127 PRINTER_PRINTF2("/Rs {readstring} def%s",EndOfLine); 1128 1129 if (Printer_Compress) { 1130 rleprolog(xdots,ydots); 1131 } else 1132 { 1133 PRINTER_PRINTF3("/picstr %d string def%s", 1134 ColorPS?xdots*3:xdots,EndOfLine); 1135 PRINTER_PRINTF7("/dopic { gsave %d %d 8 [%d 0 0 %d 0 %d]%s", 1136 xdots, ydots, xdots, -ydots, ydots, 1137 EndOfLine); 1138 PRINTER_PRINTF2("{ Cf picstr Rh pop }%s", EndOfLine); 1139 if (ColorPS) 1140 { 1141 PRINTER_PRINTF2(" false 3 colorimage grestore } def%s", 1142 EndOfLine); 1143 } 1144 else 1145 { 1146 PRINTER_PRINTF2(" image grestore } def%s", EndOfLine); 1147 } 1148 } 1149 if (Printer_Titleblock==1) 1150 { 1151 PRINTER_PRINTF2("/Helvetica findfont 8 scalefont setfont%s",EndOfLine); 1152 if (ptrid==5) {PRINTER_PRINTF1("30 60 Mv ");} 1153 else {PRINTER_PRINTF1("552 30 Mv 90 rotate ");} 1154 print_title(ptrid,res,EndOfLine); 1155 if (ptrid==6) {PRINTER_PRINTF1("-90 rotate ");} 1156 } 1157 1158 if (EPSFileType != 1) /* Do not use on a WELL BEHAVED .EPS */ 1159 { 1160 if (ptrid == 5 && EPSFileType==2 1161 && (Printer_ColorXlat || Printer_SetScreen)) 1162 PRINTER_PRINTF2("%%%%BeginFeature%s",EndOfLine); 1163 if (ColorPS) 1164 { 1165 if (Printer_ColorXlat==1) 1166 PRINTER_PRINTF2("{1 exch sub} D D D setcolortransfer%s",EndOfLine); 1167 if (Printer_ColorXlat>1) 1168 PRINTER_PRINTF4("{%d mul round %d div} D D D setcolortransfer%s", 1169 Printer_ColorXlat,Printer_ColorXlat,EndOfLine); 1170 if (Printer_ColorXlat<-1) 1171 PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} D D D setcolortransfer", 1172 Printer_ColorXlat,Printer_ColorXlat,EndOfLine); 1173 1174 if (Printer_SetScreen==1) 1175 { 1176 #ifndef XFRACT 1177 static char far fmt_str[] = "%d %d {%Fs}%s";
1178 #else 1179 static char fmt_str[] = "%d %d {%s}%s";
1180 #endif 1181 Printer_printf(fmt_str, 1182 Printer_RFrequency, 1183 Printer_RAngle, 1184 (char far *)HalfTone[Printer_RStyle], 1185 EndOfLine); 1186 Printer_printf(fmt_str, 1187 Printer_GFrequency, 1188 Printer_GAngle, 1189 (char far *)HalfTone[Printer_GStyle], 1190 EndOfLine); 1191 Printer_printf(fmt_str, 1192 Printer_BFrequency, 1193 Printer_BAngle, 1194 (char far *)HalfTone[Printer_BStyle], 1195 EndOfLine); 1196 Printer_printf(fmt_str, 1197 Printer_SFrequency, 1198 Printer_SAngle, 1199 (char far *)HalfTone[Printer_SStyle], 1200 EndOfLine); 1201 PRINTER_PRINTF2("setcolorscreen%s", EndOfLine); 1202 } 1203 } 1204 else 1205 { 1206 if (Printer_ColorXlat!=-2 && Printer_ColorXlat!=2) { 1207 /* b&w case requires no mask building */ 1208 if (Printer_ColorXlat==1) 1209 PRINTER_PRINTF2("{1 exch sub} settransfer%s",EndOfLine); 1210 if (Printer_ColorXlat>1) 1211 PRINTER_PRINTF4("{%d mul round %d div} settransfer%s", 1212 Printer_ColorXlat,Printer_ColorXlat,EndOfLine); 1213 if (Printer_ColorXlat<-1) 1214 PRINTER_PRINTF4("{%d mul round %d div 1 exch sub} settransfer", 1215 Printer_ColorXlat,Printer_ColorXlat,EndOfLine); 1216 1217 if (Printer_SetScreen==1) 1218 { 1219 #ifndef XFRACT 1220 PRINTER_PRINTF5("%d %d {%Fs} setscreen%s", 1221 Printer_SFrequency, 1222 Printer_SAngle, 1223 (char far *)HalfTone[Printer_SStyle], 1224 EndOfLine);
1225 #else 1226 Printer_printf("%d %d {%s} setscreen%s", 1227 Printer_SFrequency, 1228 Printer_SAngle, 1229 (char far *)HalfTone[Printer_SStyle], 1230 EndOfLine);
1231 #endif 1232 } 1233 } 1234 } 1235 1236 if (ptrid == 5) 1237 { 1238 if ((EPSFileType==2) && (Printer_ColorXlat || Printer_SetScreen)) 1239 PRINTER_PRINTF2("%%%%EndFeature%s",EndOfLine); 1240 if (res == 0) 1241 { 1242 PRINTER_PRINTF2("30 191.5 Tr 552 %4.1f", 1243 (552.0*(double)finalaspectratio)); 1244 } 1245 else 1246 { 1247 PRINTER_PRINTF4("30 %d Tr %f %f", 1248 75 - ((Printer_Titleblock==1) ? 0 : 45), 1249 ((double)xdots*(72.0/(double)res)), 1250 ((double)xdots*(72.0/(double)res)*(double)finalaspectratio)); 1251 } 1252 } 1253 else /* For Horizontal PostScript */ 1254 { 1255 if (res == 0) 1256 { 1257 PRINTER_PRINTF2("582 30 Tr 90 rotate 732 %4.1f", 1258 (732.0*(double)finalaspectratio)); 1259 } 1260 else 1261 { 1262 PRINTER_PRINTF4("%d 30 Tr 90 rotate %f %f", 1263 537 + ((Printer_Titleblock==1) ? 0 : 45), 1264 ((double)xdots*(72.0/(double)res)), 1265 ((double)xdots*(72.0/(double)res)*(double)finalaspectratio)); 1266 } 1267 } 1268 PRINTER_PRINTF2(" scale%s",EndOfLine); 1269 } 1270 1271 else if (ptrid == 5) /* To be used on WELL-BEHAVED .EPS */ 1272 PRINTER_PRINTF5("30 %d Tr %d %d scale%s", 1273 75 - ((Printer_Titleblock==1) ? 0 : 45), 1274 xdots,ydots,EndOfLine); 1275 1276 PRINTER_PRINTF2("dopic%s",EndOfLine); 1277 break; 1278 1279 case 7: /* HP Plotter */ 1280 if (res<1) res=1; 1281 if (res>10) res=10; 1282 ci = (((double)xdots*((double)res-1.0))/2.0); 1283 ck = (((double)ydots*((double)res-1.0))/2.0); 1284 PRINTER_PRINTF6(";IN;SP0;SC%d,%d,%d,%d;%s\0", 1285 (int)(-ci),(int)((double)xdots+ci), 1286 (int)((double)ydots+ck),(int)(-ck),EndOfLine); 1287 break; 1288 } 1289 } 1290 1291 1292 static void _fastcall print_title(int ptrid,int res,char *EndOfLine) 1293 { 1294 char buff[80]; 1295 int postscript; 1296 if (Printer_Titleblock == 0) 1297 return; 1298 postscript = (ptrid == 5 || ptrid ==6); 1299 if (!postscript) 1300 Printer_printf(EndOfLine); 1301 else 1302 Printer_printf("("); 1303 Printer_printf((curfractalspecific->name[0]=='*') 1304 ? &curfractalspecific->name[1] 1305 : curfractalspecific->name); 1306 if (fractype == FORMULA || fractype == FFORMULA) 1307 Printer_printf(" %s",FormName); 1308 if (fractype == LSYSTEM) 1309 Printer_printf(" %s",LName); 1310 if (fractype == IFS || fractype == IFS3D) 1311 Printer_printf(" %s",IFSName); 1312 PRINTER_PRINTF4(" - %dx%d - %d DPI", xdots, ydots, res); 1313 if (!postscript) 1314 Printer_printf(EndOfLine); 1315 else { 1316 PRINTER_PRINTF2(") show%s",EndOfLine); 1317 if (ptrid==5) {PRINTER_PRINTF1("30 50 moveto (");} 1318 else PRINTER_PRINTF1("-90 rotate 562 30 moveto 90 rotate ("); 1319 } 1320 PRINTER_PRINTF5("Corners: Top-Left=%.16g/%.16g Bottom-Right=%.16g/%.16g", 1321 xxmin,yymax,xxmax,yymin); 1322 if (xx3rd != xxmin || yy3rd != yymin) { 1323 if (!postscript) 1324 Printer_printf("%s ",EndOfLine); 1325 PRINTER_PRINTF3(" Bottom-Left=%4.4f/%4.4f",xx3rd,yy3rd); 1326 } 1327 if (!postscript) 1328 Printer_printf(EndOfLine); 1329 else { 1330 PRINTER_PRINTF2(") show%s",EndOfLine); 1331 if (ptrid==5) {PRINTER_PRINTF1("30 40 moveto (");} 1332 else PRINTER_PRINTF1("-90 rotate 572 30 moveto 90 rotate ("); 1333 } 1334 showtrig(buff); 1335 PRINTER_PRINTF6("Parameters: %4.4f/%4.4f/%4.4f/%4.4f %s", 1336 param[0],param[1],param[2],param[3],buff); 1337 if (!postscript) 1338 Printer_printf(EndOfLine); 1339 else 1340 PRINTER_PRINTF2(") show%s",EndOfLine); 1341 } 1342 1343 /* This function prints a string to the the printer with BIOS calls. */ 1344 1345 #ifndef USE_VARARGS 1346 static void Printer_printf(char far *fmt,...)
1347 #else 1348 static void Printer_printf(va_alist) 1349 va_dcl
1350 #endif 1351 { 1352 int i; 1353 char s[500]; 1354 int x=0; 1355 va_list arg; 1356 1357 #ifndef USE_VARARGS 1358 va_start(arg,fmt);
1359 #else 1360 char far *fmt; 1361 va_start(arg); 1362 fmt = va_arg(arg,char far *);
1363 #endif 1364 1365 { 1366 /* copy far to near string */ 1367 char fmt1[100]; 1368 i=0; 1369 while(fmt[i]) { 1370 fmt1[i] = fmt[i]; 1371 i++; 1372 } 1373 fmt1[i] = '\0'; 1374 vsprintf(s,fmt1,arg); 1375 } 1376 1377 if (Print_To_File>0) /* This is for printing to file */ 1378 fprintf(PRFILE,"%s",s); 1379 else /* And this is for printing to printer */ 1380 while (s[x]) 1381 if (printer(s[x++]) != 0) 1382 while (!keypressed()) { if (printer(s[x-1])==0) break; } 1383 } 1384 1385 /* This function standardizes both _bios_printer and _bios_serialcom 1386 * in one function. It takes its arguments and rearranges them and calls 1387 * the appropriate bios call. If it then returns result !=0, there is a 1388 * problem with the printer. 1389 */ 1390 static int _fastcall printer(int c) 1391 { 1392 if (Print_To_File>0) return ((fprintf(PRFILE,"%c",c))<1); 1393 #ifndef XFRACT 1394 if (LPTn<9) return (((_bios_printer(0,LPTn,c))+0x0010)&0x0010); 1395 if (LPTn<19) return ((_bios_serialcom(1,(LPTn-10),c))&0x9E00); 1396 if ((LPTn==20)||(LPTn==21)) 1397 { 1398 int PS=0; 1399 while ((PS & 0xF8) != 0xD8) 1400 { PS = inp((LPTn==20) ? 0x379 : 0x279); 1401 if (keypressed()) return(1); } 1402 outp((LPTn==20) ? 0x37C : 0x27C,c); 1403 PS = inp((LPTn==20) ? 0x37A : 0x27A); 1404 outp((LPTn==20) ? 0x37A : 0x27A,(PS | 0x01)); 1405 outp((LPTn==20) ? 0x37A : 0x27A,PS); 1406 return(0); 1407 } 1408 if ((LPTn==30)||(LPTn==31)) 1409 { 1410 while (((inp((LPTn==30) ? 0x3FE : 0x2FE)&0x30)!=0x30) || 1411 ((inp((LPTn==30) ? 0x3FD : 0x2FD)&0x60)!=0x60)) 1412 { if (keypressed()) return (1); } 1413 outp((LPTn==30) ? 0x3F8 : 0x2F8,c); 1414 return(0); 1415 } 1416 #endif 1417 1418 /* MCP 7-7-91, If we made it down to here, we may as well error out. */ 1419 return(-1); 1420 } 1421 1422 #ifdef __BORLANDC__
1423 #if(__BORLANDC__ > 2) 1424 #pragma warn +eff 1425 #endif
1426 #endif 1427 1428 static void printer_reset(void) 1429 { 1430 #ifndef XFRACT 1431 if (Print_To_File < 1) 1432 if (LPTn<9) _bios_printer(1,LPTn,0); 1433 else if (LPTn<19) _bios_serialcom(3,(LPTn-10),0); 1434 #endif 1435 } 1436 1437 1438 /** debug code for pj_ color table checkout 1439 color_test() 1440 { 1441 int x,y,color,i,j,xx,yy; 1442 int bw,cw,bh,ch; 1443 setvideomode(videoentry.videomodeax, 1444 videoentry.videomodebx, 1445 videoentry.videomodecx, 1446 videoentry.videomodedx); 1447 bw = xdots/25; cw = bw * 2 / 3; 1448 bh = ydots/10; ch = bh * 2 / 3; 1449 dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 60; 1450 if (debugflag == 902) 1451 dacbox[0][0] = dacbox[0][1] = dacbox[0][2] = 0; 1452 for (x = 0; x < 25; ++x) 1453 for (y = 0; y < 10; ++y) { 1454 if (x < 11) i = (32 - x) * 10 + y; 1455 else i = (24 - x) * 10 + y; 1456 color = x * 10 + y + 1; 1457 dacbox[color][0] = triple[0][0][i]; 1458 dacbox[color][1] = triple[0][1][i]; 1459 dacbox[color][2] = triple[0][2][i]; 1460 for (i = 0; i < cw; ++i) { 1461 xx = x * bw + bw / 6 + i; 1462 yy = y * bh + bh / 6; 1463 for (j = 0; j < ch; ++j) 1464 putcolor(xx,yy++,color); 1465 } 1466 } 1467 spindac(0,1); 1468 getakey(); 1469 } 1470 **/ 1471 1472 1473 /* 1474 * The following code for compressed PostScript is based on pnmtops.c. It is 1475 * copyright (C) 1989 by Jef Poskanzer, and carries the following notice: 1476 * "Permission to use, copy, modify, and distribute this software and its 1477 * documentation for any purpose and without fee is hereby granted, provided 1478 * that the above copyright notice appear in all copies and that both that 1479 * copyright notice and this permission notice appear in supporting 1480 * documentation. This software is provided "as is" without express or 1481 * implied warranty." 1482 */ 1483 1484 1485 static void rleprolog(int x,int y) 1486 { 1487 itemsperline = 0; 1488 items = 0; 1489 bitspersample = 8; 1490 repeat = 1; 1491 rlebitsperitem = 0; 1492 rlebitshift = 0; 1493 count = 0; 1494 1495 PRINTER_PRINTF2( "/rlestr1 1 string def%s", EndOfLine ); 1496 PRINTER_PRINTF2( "/rdrlestr {%s", EndOfLine ); /* s -- nr */ 1497 PRINTER_PRINTF2( " /rlestr exch def%s", EndOfLine ); /* - */ 1498 PRINTER_PRINTF2( " Cf rlestr1 Rh pop%s", EndOfLine ); /* s1 */ 1499 PRINTER_PRINTF2( " 0 get%s", EndOfLine ); /* c */ 1500 PRINTER_PRINTF2( " D 127 le {%s", EndOfLine ); /* c */ 1501 PRINTER_PRINTF2( " Cf rlestr 0%s", EndOfLine ); /* c f s 0 */ 1502 PRINTER_PRINTF2( " 4 3 roll%s", EndOfLine ); /* f s 0 c */ 1503 PRINTER_PRINTF2( " 1 add getinterval%s", EndOfLine ); /* f s */ 1504 PRINTER_PRINTF2( " Rh pop%s", EndOfLine ); /* s */ 1505 PRINTER_PRINTF2( " length%s", EndOfLine ); /* nr */ 1506 PRINTER_PRINTF2( " } {%s", EndOfLine ); /* c */ 1507 PRINTER_PRINTF2( " 256 exch sub D%s", EndOfLine ); /* n n */ 1508 PRINTER_PRINTF2( " Cf rlestr1 Rh pop%s", EndOfLine );/* n n s1 */ 1509 PRINTER_PRINTF2( " 0 get%s", EndOfLine ); /* n n c */ 1510 PRINTER_PRINTF2( " exch 0 exch 1 exch 1 sub {%s", EndOfLine ); /* n c 0 1 n-1*/ 1511 PRINTER_PRINTF2( " rlestr exch 2 index put%s", EndOfLine ); 1512 PRINTER_PRINTF2( " } for%s", EndOfLine ); /* n c */ 1513 PRINTER_PRINTF2( " pop%s", EndOfLine ); /* nr */ 1514 PRINTER_PRINTF2( " } ifelse%s", EndOfLine ); /* nr */ 1515 PRINTER_PRINTF2( "} bind def%s", EndOfLine ); 1516 PRINTER_PRINTF2( "/Rs {%s", EndOfLine ); /* s -- s */ 1517 PRINTER_PRINTF2( " D length 0 {%s", EndOfLine ); /* s l 0 */ 1518 PRINTER_PRINTF2( " 3 copy exch%s", EndOfLine ); /* s l n s n l*/ 1519 PRINTER_PRINTF2( " 1 index sub%s", EndOfLine ); /* s l n s n r*/ 1520 PRINTER_PRINTF2( " getinterval%s", EndOfLine ); /* s l n ss */ 1521 PRINTER_PRINTF2( " rdrlestr%s", EndOfLine ); /* s l n nr */ 1522 PRINTER_PRINTF2( " add%s", EndOfLine ); /* s l n */ 1523 PRINTER_PRINTF2( " 2 copy le { exit } if%s", EndOfLine ); /* s l n */ 1524 PRINTER_PRINTF2( " } loop%s", EndOfLine ); /* s l l */ 1525 PRINTER_PRINTF2( " pop pop%s", EndOfLine ); /* s */ 1526 PRINTER_PRINTF2( "} bind def%s", EndOfLine ); 1527 if (ColorPS) { 1528 PRINTER_PRINTF3( "/rpicstr %d string def%s", x,EndOfLine ); 1529 PRINTER_PRINTF3( "/gpicstr %d string def%s", x,EndOfLine ); 1530 PRINTER_PRINTF3( "/bpicstr %d string def%s", x,EndOfLine ); 1531 } else { 1532 PRINTER_PRINTF3( "/picstr %d string def%s", x,EndOfLine ); 1533 } 1534 PRINTER_PRINTF2( "/dopic {%s", EndOfLine); 1535 PRINTER_PRINTF2( "/gsave%s", EndOfLine); 1536 if (ColorPS) { 1537 PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine); 1538 } else { /* b&w */ 1539 if (Printer_ColorXlat==-2) { 1540 PRINTER_PRINTF4( "%d %d true%s", x, y, EndOfLine); 1541 } else if (Printer_ColorXlat==2) { 1542 PRINTER_PRINTF4( "%d %d false%s", x, y, EndOfLine); 1543 } else { 1544 PRINTER_PRINTF4( "%d %d 8%s", x, y, EndOfLine); 1545 } 1546 } 1547 PRINTER_PRINTF5( "[%d 0 0 %d 0 %d]%s", x, -y, y, EndOfLine); 1548 if (ColorPS) { 1549 PRINTER_PRINTF2( "{rpicstr Rs}%s", EndOfLine); 1550 PRINTER_PRINTF2( "{gpicstr Rs}%s", EndOfLine); 1551 PRINTER_PRINTF2( "{bpicstr Rs}%s", EndOfLine); 1552 PRINTER_PRINTF2( "true 3 colorimage%s", EndOfLine); 1553 } else { 1554 if (Printer_ColorXlat==-2 || Printer_ColorXlat==2) { 1555 /* save file space and printing time (if scaling is right) */ 1556 PRINTER_PRINTF2( "{picstr Rs} imagemask%s", EndOfLine); 1557 } else { 1558 PRINTER_PRINTF2( "{picstr Rs} image%s", EndOfLine); 1559 } 1560 } 1561 PRINTER_PRINTF2( "} def%s", EndOfLine); 1562 } 1563 1564 static void 1565 rleputbuffer(void) 1566 { 1567 int i; 1568 1569 if ( repeat ) 1570 { 1571 item = 256 - count; 1572 putitem(); 1573 item = repeatitem; 1574 putitem(); 1575 } 1576 else 1577 { 1578 item = count - 1; 1579 putitem(); 1580 for ( i = 0; i < count; ++i ) 1581 { 1582 item = itembuf[i]; 1583 putitem(); 1584 } 1585 } 1586 repeat = 1; 1587 count = 0; 1588 } 1589 1590 static void 1591 rleputitem(void) 1592 { 1593 int i; 1594 1595 if ( count == 128 ) 1596 rleputbuffer(); 1597 1598 if ( repeat && count == 0 ) 1599 { /* Still initializing a repeat buf. */ 1600 itembuf[count] = repeatitem = rleitem; 1601 ++count; 1602 } 1603 else if ( repeat ) 1604 { /* Repeating - watch for end of run. */ 1605 if ( rleitem == repeatitem ) 1606 { /* Run continues. */ 1607 itembuf[count] = rleitem; 1608 ++count; 1609 } 1610 else 1611 { /* Run ended - is it long enough to dump? */ 1612 if ( count > 2 ) 1613 { /* Yes, dump a repeat-mode buffer and start a new one. */ 1614 rleputbuffer(); 1615 itembuf[count] = repeatitem = rleitem; 1616 ++count; 1617 } 1618 else 1619 { /* Not long enough - convert to non-repeat mode. */ 1620 repeat = 0; 1621 itembuf[count] = repeatitem = rleitem; 1622 ++count; 1623 repeatcount = 1; 1624 } 1625 } 1626 } 1627 else 1628 { /* Not repeating - watch for a run worth repeating. */ 1629 if ( rleitem == repeatitem ) 1630 { /* Possible run continues. */ 1631 ++repeatcount; 1632 if ( repeatcount > 3 ) 1633 { /* Long enough - dump non-repeat part and start repeat. */ 1634 count = count - ( repeatcount - 1 ); 1635 rleputbuffer(); 1636 count = repeatcount; 1637 for ( i = 0; i < count; ++i ) 1638 itembuf[i] = rleitem; 1639 } 1640 else 1641 { /* Not long enough yet - continue as non-repeat buf. */ 1642 itembuf[count] = rleitem; 1643 ++count; 1644 } 1645 } 1646 else 1647 { /* Broken run. */ 1648 itembuf[count] = repeatitem = rleitem; 1649 ++count; 1650 repeatcount = 1; 1651 } 1652 } 1653 1654 rleitem = 0; 1655 rlebitsperitem = 0; 1656 } 1657 1658 static void 1659 putitem (void) 1660 { 1661 char* hexits = "0123456789abcdef"; 1662 1663 if ( itemsperline == 30 ) 1664 { 1665 Printer_printf("%s",EndOfLine); 1666 itemsperline = 0; 1667 } 1668 Printer_printf("%c%c", hexits[item >> 4], hexits[item & 15] ); 1669 ++itemsperline; 1670 ++items; 1671 item = 0; 1672 /* bitsperitem = 0; */ 1673 bitshift2 = 8 - bitspersample; 1674 } 1675 1676 static void 1677 rleputxelval( int xv ) 1678 { 1679 if ( rlebitsperitem == 8 ) 1680 rleputitem(); 1681 rleitem += xv<<bitshift2; 1682 rlebitsperitem += bitspersample; 1683 rlebitshift -= bitspersample; 1684 } 1685 1686 static void 1687 rleflush(void) 1688 { 1689 if ( rlebitsperitem > 0 ) 1690 rleputitem(); 1691 if ( count > 0 ) 1692 rleputbuffer(); 1693 } 1694 1695 static void 1696 rleputrest(void) 1697 { 1698 rleflush(); 1699 Printer_printf( "%s",EndOfLine ); 1700 Printer_printf( "grestore%s",EndOfLine ); 1701 } 1702