1: /*
   2:  *  bitmap - routines that help build a bitmap of a graphical image
   3:  *
   4:  *  These are primarily used to implement all of the drawing primitives
   5:  *  (except for lines)
   6:  *
   7:  *  History:
   8:  *28-aug-85 John Mellor-Crummey	added flush_bitmap which is used instead
   9:  *				of print_bitmap if current page is not outputted
  10:  *
  11:  *	17-jun-85  ed flint	bitmap width(bm_width) must be multiple of 32
  12:  *				bits for print services 12 (?)
  13:  *
  14:  * Copyright (c) 1984, 1985 Xerox Corp.
  15:  *
  16:  */
  17: 
  18: # include <stdio.h>
  19: # include "iptokens.h"
  20: # include "literal.h"
  21: # include "operator.h"
  22: 
  23: # define    local   static
  24: # define    No      0
  25: # define    Yes     1
  26: 
  27: # define    INCH    2540        /* micas per inch */
  28: 
  29: extern int drawidth;
  30: extern double drawscale;
  31: 
  32: char *malloc();
  33: 
  34: local int minx;
  35: local int miny;
  36: local int maxx;
  37: local int maxy;
  38: local int bm_width;     /* in real bytes */
  39: local int bm_size;
  40: local char *bitmap;
  41: local char *bm_prelude;
  42: local char  bm_active = No;
  43: 
  44: # define    scale_x(x)      x = (double)x * drawscale
  45: # define    scale_y(y)      y = (double)y * drawscale
  46: 
  47: /*
  48:  *  new_bitmap(x1, y1, x2, y2) - prepare for a new bitmap, the extreme x and y
  49:  *				 values are x1, y1, x2, and y2.
  50:  */
  51: 
  52: new_bitmap(stroke, x1, y1, x2, y2)
  53: 
  54: int stroke, x1, y1, x2, y2;
  55: 
  56: {
  57:     int new_size;
  58:     register int temp;
  59: 
  60: #ifdef DEBUG
  61:     fprintf(stderr, "new_bitmap(%d, %d, %d, %d, %d)\n", stroke,x1, y1, x2, y2);
  62: #endif
  63:     drawidth = stroke * drawscale;
  64:     scale_x(x1);
  65:     scale_y(y1);
  66:     scale_x(x2);
  67:     scale_y(y2);
  68: #ifdef DEBUG
  69:     fprintf(stderr, "after scaling: width %d: %d, %d and %d, %d\n", drawidth, x1, y1, x2, y2);
  70: #endif
  71: 
  72:     /* insure that x1, y1 is the lower left */
  73:     if (x1 > x2)
  74:     {
  75: #ifdef DEBUG
  76:     fprintf(stderr, "exchanging pairs ... ");
  77: #endif
  78:     temp = x1;  /* exchange x1 and x2 */
  79:     x1   = x2;
  80:     x2   = temp;
  81:     temp = y1;  /* exchange y1 and y2 */
  82:     y1   = y2;
  83:     y2   = temp;
  84: #ifdef DEBUG
  85:     fprintf(stderr, "now %d, %d and %d, %d\n", x1, y1, x2, y2);
  86: #endif
  87:     }
  88: 
  89:     /* adjust the extremes to allow for pen thickness */
  90:     temp = (drawidth + 1) / 2;
  91:     x1 -= temp;
  92:     y1 -= temp;
  93:     x2 += temp;
  94:     y2 += temp;
  95: 
  96:     if (!bm_active || !(x1 >= minx && y1 >= miny && x2 <= maxx && y2 <= maxy))
  97:     {
  98:     /* we need to set up a new map */
  99:     /* but first, print the old one if it is still active */
 100: #ifdef DEBUG
 101:     fprintf(stderr, "setting up new map, bm_active is %d\n", bm_active);
 102: #endif
 103:     print_bitmap();
 104: 
 105:     minx = x1;
 106:     miny = y1;
 107:     maxx = x2;
 108:     maxy = y2;
 109: 
 110:     bm_width = (y2 - y1 + 7) / 8;
 111: 
 112:     /* print services 12 (?) wants packed pixel vectors to produce each */
 113:     /* scan line as a mutliple of 32 bits, this is backward compatible  */
 114:     /* with previous versions of services				    */
 115:     /* (the previous version of bitmap produced 16 bit multiples which  */
 116:     /* will NOT work with services 12 (?) and beyond)		    */
 117: 
 118:     if ( bm_width%4 != 0 )
 119:     {
 120:         bm_width= bm_width + (4 - bm_width%4);
 121:     }
 122:     new_size = (x2 - x1) * bm_width;
 123:     if (new_size > bm_size)
 124:     {
 125:         /* need to allocate a larger area for the bitmap */
 126:         if (bitmap != NULL)
 127:         {
 128:         free(bitmap);
 129:         }
 130:         /* leave space for the ppv prelude (leading 4 bytes) */
 131:         bm_prelude = malloc((unsigned)(new_size + 4));
 132:         bitmap = bm_prelude + 4;
 133:         bm_size = new_size;
 134:     }
 135: #ifdef DEBUG
 136:     fprintf(stderr, "bm_width %d, bm_size %d\n", bm_width, bm_size);
 137: #endif
 138: 
 139:     bzero(bitmap, bm_size);
 140:     }
 141: }
 142: 
 143: set_pixel(x, y)
 144: 
 145: int x;
 146: int y;
 147: 
 148: {
 149:     int mask;
 150:     int half_drawidth;
 151:     register int i;
 152:     register int ybit, temp;
 153:     register char *ptr;
 154: 
 155:     scale_x(x);
 156:     scale_y(y);
 157: 
 158:     bm_active = Yes;
 159: 
 160: #ifdef DEBUG
 161:     if (x < minx || x > maxx || y < miny || y > maxy)
 162:     {
 163:     fprintf(stderr, "point off map: (%d, %d)\n", x, y);
 164:     return;
 165:     }
 166: #endif
 167:     x -= minx;
 168:     y  = maxy - y;  /* yes, it works */
 169:     half_drawidth = drawidth >> 1;
 170: 
 171:     /* Remember the bitmap is built in increasing y */
 172: 
 173:     /* draw the "x" line vertically */
 174:     mask = 0x80 >> (y & 007);
 175:     ptr = (x - half_drawidth) * bm_width + (y >> 3) + bitmap;
 176:     for (i = 0; i < drawidth; i++, ptr += bm_width)
 177:     {
 178:     *ptr |= mask;
 179:     }
 180: 
 181:     /* draw the "y" line horizontally */
 182:     y -= half_drawidth;
 183:     ptr = (x * bm_width) + (y >> 3) + bitmap;
 184:     ybit = y & 007;
 185:     temp = ybit + drawidth;
 186:     if (temp < 8)
 187:     {
 188:     /* special case -- less than one byte */
 189:     *ptr |= (0xff >> ybit) ^ (0xff >> temp);
 190:     }
 191:     else
 192:     {
 193:     *ptr |= (0xff >> ybit);
 194:     for (i = drawidth - 8 + ybit; i > 8; i -= 8)
 195:     {
 196:         *++ptr |= 0xff;
 197:     }
 198:     *++ptr |= ~(0xff >> i);
 199:     }
 200: }
 201: 
 202: flush_bitmap()
 203: {
 204:     bm_active = No;
 205: }
 206: 
 207: print_bitmap()
 208: 
 209: {
 210:     register int bits;
 211:     register char *prelude = bm_prelude;
 212:     int totalbits, size, bm_xdelta, bm_x = minx;
 213: 
 214: #ifdef DEBUG2
 215:     int x;
 216:     int y;
 217:     int i;
 218:     char *ptr;
 219: #endif
 220: 
 221:     if (!bm_active)
 222:     {
 223:     /* don't bother */
 224:     return;
 225:     }
 226: 
 227: #ifdef DEBUG2
 228:     /* debugging version for now */
 229:     ptr = bitmap;
 230:     for (x = minx; x <= maxx; x++)
 231:     {
 232:     for (y = miny; y <= maxy; y += 8, ptr++)
 233:     {
 234:         for (i = 0x80; i != 0; i >>= 1)
 235:         {
 236:         if (*ptr & i)
 237:         {
 238:             putchar('*');
 239:         }
 240:         else
 241:         {
 242:             putchar(' ');
 243:         }
 244:         }
 245:     }
 246:     putchar('\n');
 247:     }
 248: #endif
 249: 
 250: /* The following is conservative (might actually be twice as big) */
 251: #define MAXPPVSAMPS 262144
 252:     bm_xdelta = maxx - minx;
 253:     bits = bm_width << 3;           /* (* 8) */
 254:     totalbits = bits * bm_xdelta;
 255:     if (totalbits > MAXPPVSAMPS) {
 256:     bm_xdelta = MAXPPVSAMPS / bits;
 257:     }
 258:     while (bm_x < maxx) {
 259:     /* Check for last time through loop */
 260:     if (bm_xdelta > (maxx - bm_x)) {
 261:         bm_xdelta = maxx - bm_x;
 262:     }
 263:     size = (bits * bm_xdelta) >> 3;     /* Could hand optimize! */
 264:     /* inside a dosavesimplebody to preserve transform */
 265:     Op(dosavesimplebody);
 266:     Op(beginBody);
 267:     AppendInteger((long) bm_xdelta);    /* xPixels */
 268:     AppendInteger((long) bits);     /* yPixels */
 269:     AppendInteger(1L);          /* samplesPerPixel */
 270:     AppendInteger(1L);          /* maxSampleValue */
 271:     AppendInteger(1L);          /* samplesInterleaved */
 272:     Translate(0.0, 0.0);            /* (null) transform */
 273: 
 274:     /* spew out the packed pixel vector */
 275:     prelude[0] = 0;
 276:     prelude[1] = 1;
 277:     prelude[2] = (char)((bits & 0xff00) >> 8);  /* high order byte */
 278:     prelude[3] = (char) (bits & 0x00ff);        /* low  order byte */
 279:     append_Sequence(sequencePackedPixelVector, size + 4,
 280:                         (unsigned char *) prelude);
 281: 
 282:     /* make the pixel array */
 283:     Op(makepixelarray);
 284: 
 285:     /* set the transform to the right scale and position */
 286:     /* transform must scale back to micas and position bitmap */
 287:     AppendInteger((long) bm_x);
 288:     AppendInteger((long) ((11 * INCH * drawscale) - maxy));
 289:     Op(translate);
 290:     AppendInteger(5L);
 291:     Op(scale);
 292:     Op(concat);
 293:     Op(concatt);
 294: 
 295:     /* mask it and finish the simple-body */
 296:     Op(maskpixel);
 297:     Op(endBody);
 298:     prelude += size;
 299:     bm_x += bm_xdelta;
 300:     }
 301: 
 302:     /* no longer active, now is it? */
 303:     bm_active = No;
 304: }

Defined functions

flush_bitmap defined in line 202; used 1 times
new_bitmap defined in line 52; used 1 times
print_bitmap defined in line 207; used 3 times
set_pixel defined in line 143; used 1 times

Defined variables

bitmap defined in line 40; used 7 times
bm_active defined in line 42; used 6 times
bm_prelude defined in line 41; used 3 times
bm_size defined in line 39; used 4 times
bm_width defined in line 38; used 11 times
maxx defined in line 36; used 8 times
maxy defined in line 37; used 6 times
minx defined in line 34; used 7 times
miny defined in line 35; used 4 times

Defined macros

INCH defined in line 27; used 1 times
MAXPPVSAMPS defined in line 251; used 2 times
No defined in line 24; used 3 times
Yes defined in line 25; used 1 times
local defined in line 23; used 9 times
scale_x defined in line 44; used 3 times
scale_y defined in line 45; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1805
Valid CSS Valid XHTML 1.0 Strict