[unix-pc.sources] UNIXpc bitblit routines from MGR

wjc@ho5cad.ATT.COM (Bill Carpenter) (11/19/89)

This is a set of bitblit routines that can be used with the "crabs"
code I posted about a week ago.

excerpted from "README.wjc"...

DO YOU WANT THIS?

If there is any chance you will someday want to play around with MGR
on your UNIXpc and/or if there is any chance that you will be using
Botton's "vidpal" video ram access board, you probably want this.
Even it you don't use it right now, it will be handy to have a copy
tucked away.

WHAT'S NEXT?

Besides waiting for the MGR and/or X ports, it would be nice if
someone wrote a little compatibility routine that use the same kind of
arguments as ioctl(WIOCRASTOP) but called this instead if there is no
window involved.  That would make porting code pretty easy.  (I was
too lazy to do this for "crabs", but I wouldn't be too lazy to grab a
copy if someone wrote it and posted it.)

------------------<snip>-----------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README.wjc Makefile README bitmap.c bitmap.h blit.C line.c
#   pixel.c rops.c test_line.c test_pixel.c test_rop.c
# Wrapped by wjc@ho5cad on Sat Nov 18 16:33:40 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README.wjc -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.wjc\"
else
echo shar: Extracting \"README.wjc\" \(4436 characters\)
sed "s/^X//" >README.wjc <<'END_OF_README.wjc'
XDO YOU WANT THIS?
X
XIf there is any chance you will someday want to play around with MGR
Xon your UNIXpc and/or if there is any chance that you will be using
XBotton's "vidpal" video ram access board, you probably want this.
XEven it you don't use it right now, it will be handy to have a copy
Xtucked away.
X
XWHAT IS THIS?
X
XThis is the C version of the bitblit code from the MGR window system.
X(MGR was written by Stephen A Uhler and posted to comp.sources.unix
Xseveral months ago.)  This code is not the stuff from the
Xmgr/src/oblit directory that was part of the c.s.unix posting; rather
Xit is based on newer portable routines developed by SAU for a port to
Xthe DEC 3100.  It is my understanding that the complete latest MGR
Xsource is always available via anonymous FTP from Bellcore.  I know
Xthat a version containing the DEC 3100 mods is available via FTP and
XUUCP from osu-cis.  Before using this code, take a second to read the
Xcopyright notice in "Makefile".
X
XThe stuff here was reconfigured for the UNIXpc by Brad Bosch
X(brad@i88.isc.com) and Brian Botton (botton@i88.isc.com).  They also
Xfixed some bugs, but I don't have the details.  They did that as part
Xof their not-yet-complete port of MGR for the UNIXpc.  If you are
Xinterested in that, especially if you are interested in helping with
Xit, contact them.  Their plans are to make MGR available when it is
Xready, but they are not sure yet when/how they will do that.  So, you
Xshould save a copy of this code just in case they decide to save space
Xby leaving it out (because it was already posted).  There is some
Xpossibility that they will make more changes to it to gain
Xperformance, so if they later post it, you should take a copy and
Xdiscard this one.
X
XMy role in this code is minimal.  I merely begged them for a copy with
Xtheir changes and asked them to let me post it.  I wanted it because I
Xwanted to make a direct video access version of the "crabs" program
X(posted about a week ago to unix-pc.sources and comp.sys.att).  For
Xthat, I needed a freely distributable set of bitblit routines that
Xwould work in user space.  Voila.  The only change I have made is
Xadding this file and making a small mod to the Makefile.
X
XCOMPILING IT
X
XThe main file, blit.C, uses macro expansion to generate a fairly large
Xfile (blit.c) containing a single function.  The best speed in the
Xobject code ought to be obtained by using the option to UNROLL loops
Xand then using "-O" on the compilation.  Alas, due to the size of the
Xfunction involved, it's not that simple.
X
X(1) As posted, you will find in the Makefile both "-O" and
X"-DUNROLLED".  If you just type "make" and have a little bit of luck,
Xyou'll end up with "blitlib.a" when you're done.  See the files
X"test_*.c" and the "crabs" code for examples of how to use it; sorry,
Xno man page.  There are 16 bitblit operations available.
X
X(2) With "cc", it compiles as posted, but I'm not sure it will if you
Xhave limited RAM (the optimization is RAM-hungry).  If it doesn't
Xcompile and blows off with "memory exhausted", try taking off the "-O"
X(don't change it to "-g").  You can also leave the "-O" in and change
X"-DUNROLLED" to "-UUNROLLED".  I'm not sure which hurts performance
Xmore.  If it still won't compile for you, change them both.  If it
Xdoesn't compile then, you're out of luck.  Find a helpful neighbor.
X
X(3)  With "gcc" on a machine with 2.5 MB of RAM, I couldn't get it to
Xcompile without both taking out "-O" and changing it to "-UUNROLLED".
XI don't know what you can do if you have more RAM.  If you compile it
Xwith "gcc", I recommend that you use the "-fpcc-struct-return",
Xespecially if you mix "cc" and "gcc" object code.
X
X(4)  With either "cc" or "gcc" it can take anywhere from 15 minutes to
Xover an hour to compile "blit.c", depending on how much RAM you have
Xand how fast your disk drive is (this will warm it up a little :-).
X
XWHAT'S NEXT?
X
XBesides waiting for the MGR and/or X ports, it would be nice if
Xsomeone wrote a little compatibility routine that use the same kind of
Xarguments as ioctl(WIOCRASTOP) but called this instead if there is no
Xwindow involved.  That would make porting code pretty easy.  (I was
Xtoo lazy to do this for "crabs", but I wouldn't be too lazy to grab a
Xcopy if someone wrote it and posted it.)
X
XTHANKS
X
XTo the original author and to those who worked on it later for making
Xit available.
X--
X   Bill Carpenter     william_j_carpenter@ATT.COM  or  attmail!bill
X   18 November 1989
END_OF_README.wjc
if test 4436 -ne `wc -c <README.wjc`; then
    echo shar: \"README.wjc\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(1784 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#                        Copyright (c) 1988,1989 Bellcore
X#                            All Rights Reserved
X#       Permission is granted to copy or use this program, EXCEPT that it
X#       may not be sold for profit, the copyright notice must be reproduced
X#       on copies, and credit should be given to Bellcore where it is due.
X#       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X
X#	$Header: Makefile,v 1.2 89/05/23 08:33:45 sau Exp $
X#	$Source: /mnt/sau/bitblt/DEC/RCS/Makefile,v $
X
X#	makefile for portable blit library
X
XSTART=.
XCFLAGS= -O -I. -DBBB1 -DUNROLL
X#CC=gcc
XCPP=/lib/cpp -P -C
X#CPP=/usr/local/lib/gcc-cpp -P -C
X
X#	The template expansion level is specified here for building blit.c
X#	0			leave all the templates intact
X#	1			expand the switches
X#	12			expand the bitblt templates
X#	123		expand the inner loops
X#	1234		expand the bit shifts
X#	12345		expand the bitwise operators
X#	%			Normal CPP defines/includes
X#	#			These always get expanded on the first pass
XPASS1=0
XINDENT=indent -st
X#	Indent doesn't always generate valid C code
XINDENT = cat
X
Xblitlib.a:		bitmap.o blit.o line.o pixel.o
X#					ar r blitlib.a bitmap.o blit.o line.o pixel.o
X#					ranlib blitlib.a
X					ar rv blitlib.a `lorder bitmap.o blit.o line.o pixel.o | tsort`
X
Xrops:		rops.o bitmap.o blit.o
X					$(CC) $(CFLAGS) -o rops rops.o blit.o bitmap.o
X
Xtest_rop:		test_rop.o bitmap.o blit.o
X					$(CC) $(CFLAGS) -o test_rop test_rop.o blit.o bitmap.o
X
Xblit.c:		blit.C
X				< blit.C sed "s/^[$(PASS1)]/#/" | \
X					$(CPP) | \
X					sed 's/^[1-9%]/#/' | \
X					$(INDENT) | \
X					cat -s \
X				> blit.c
X
Xbitmap.o blit.o line.o pixel.o:	bitmap.h
X
Xlist:
X	@for i in blit.C bitmap.h bitmap.c rops.c test_rop.c Makefile line.c \
X			 pixel.c README ; do \
X		echo "${START}/$$i"; \
X	done	
X
END_OF_Makefile
if test 1784 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(321 characters\)
sed "s/^X//" >README <<'END_OF_README'
XThis is the preliminary version of the MGR portable bit-blit library.
XIt has been tested on a DEC3100, and a SUN3/60.
X
XIt is still missing multi plane (color) support
X
XStephen A. Uhler (6/18/89)
X
X* rops <min_size> <max_size> <count>
X  runs a bunch of random bit-blts
X
X* test_rop <size>
X  tests the 16 transfer functions
X
END_OF_README
if test 321 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bitmap.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bitmap.c\"
else
echo shar: Extracting \"bitmap.c\" \(6563 characters\)
sed "s/^X//" >bitmap.c <<'END_OF_bitmap.c'
X/*  68020 bitblit code  (requires 32 bit alignment) */
X
X#ifdef sun
X#  include <sys/ioctl.h>
X#  include <sun/fbio.h>
X#  include <sys/file.h>
X#  include <sys/mman.h>
X#endif
X#include <stdio.h>
X#include "bitmap.h"
X
X#define dprintf	if(bit_debug)fprintf
Xint bit_debug;
Xstatic int _s_start;
Xstatic _s_len;
X
X/* open the screen; it looks like memory */
X
XBITMAP *
Xbit_open(name)
Xchar *name;			/* name of frame buffer */
X{
X   BITMAP *result = BIT_NULL;
X#ifdef sun
X   int fd;
X   char *malloc();
X   register DATA *addr;
X   struct fbtype buff;
X   int pagesize;
X
X   dprintf(stderr,"bit_open:(%s)\n", name);
X	dprintf(stderr,"  BITS:0x%x LOGBITS:0x%x: MSB:0x%x LSB:0x%x\n",
X			BITS,LOGBITS,MSB,LSB);
X
X   /* open the SUN screen */
X
X   if ((fd = open(name, O_RDWR)) < 0)
X      return (BIT_NULL);
X
X   /* get the frame buffer size */
X
X   if (ioctl(fd, FBIOGTYPE, &buff) < 0)
X      return (BIT_NULL);
X
X   /* malloc space for frame buffer */
X
X   pagesize = getpagesize();
X   if ((_s_start = (int) malloc(buff.fb_size + pagesize)) == 0)
X      return (BIT_NULL);
X
X   /* align space on a page boundary */
X
X   buff.fb_size = (buff.fb_size+pagesize-1) &~ (pagesize-1);
X   addr = (DATA *) ((_s_start + pagesize - 1) & ~(pagesize - 1));
X
X   /* map the frame buffer into malloc'd space */
X
X   if (mmap(addr, _s_len = buff.fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0) < 0)
X      return (BIT_NULL);
X
X   if ((result = (BITMAP *) malloc(sizeof(BITMAP))) == (BITMAP *) 0)
X      return (BIT_NULL);
X
X   result->primary = result;
X   result->data = addr;
X   result->x0 = 0,
X   result->y0 = 0,
X   result->wide = buff.fb_width;
X   result->high = buff.fb_height;
X   result->type = _SCREEN;
X   dprintf(stderr,"  O.K.(0x%lx)\n (%d x %d)",
X	       (long) result->data, result->wide, result->high);
X#endif
X#ifdef BBB1
X   char *malloc();
X
X   dprintf(stderr,"bit_open:(%s)\n", name);
X	dprintf(stderr,"  BITS:0x%x LOGBITS:0x%x: MSB:0x%x LSB:0x%x\n",
X			BITS,LOGBITS,MSB,LSB);
X
X   if ((result = (BITMAP *) malloc(sizeof(BITMAP))) == (BITMAP *) 0)
X      return (BIT_NULL);
X
X   result->primary = result;
X   result->data = (unsigned short *) 0x420000;
X   result->x0 = 0,
X   result->y0 = 0,
X   result->wide = 720;
X   result->high = 348;
X   result->type = _SCREEN;
X   dprintf(stderr,"  O.K.(0x%lx)\n (%d x %d)",
X	       (long) result->data, result->wide, result->high);
X#endif
X   return (result);
X}
X
X/* destroy a bitmap, free up space */
X
Xint
Xbit_destroy(bitmap)
XBITMAP *bitmap;
X{
X   dprintf(stderr,"bit_destroy:\n");
X   if (bitmap == (BITMAP *) 0)
X      return (-1);
X   if (IS_MEMORY(bitmap) && IS_PRIMARY(bitmap))
X      free(bitmap->data);
X#ifdef sun
X   else if (IS_SCREEN(bitmap) && IS_PRIMARY(bitmap)) {
X      munmap(BIT_DATA(bitmap), _s_len);
X      free(_s_start);
X		}
X#endif
X   free(bitmap);
X   return (0);
X}
X
X/* create a bitmap as a sub-rectangle of another bitmap */
X
XBITMAP *
Xbit_create(map, x, y, wide, high)
XBITMAP *map;
Xint x, y, wide, high;
X{
X   char *malloc();
X   register BITMAP *result;
X
X   dprintf(stderr,"bit_create:\n");
X   if (x + wide > map->wide)
X      wide = map->wide - x;
X   if (y + high > map->high)
X      high = map->high - y;
X   if (wide < 1 || high < 1)
X      return (BIT_NULL);
X
X   if ((result = (BITMAP *) malloc(sizeof(BITMAP))) == (BITMAP *) 0)
X      return (BIT_NULL);
X
X   result->data = map->data;
X   result->x0 = map->x0 + x;
X   result->y0 = map->y0 + y;
X   result->wide = wide;
X   result->high = high;
X   result->primary = map->primary;
X   result->type = map->type;
X   dprintf(stderr,"  Created %d,%d %d,%d\n", result->x0, result->y0,
X	       result->wide, result->high);
X   return (result);
X}
X
X/* allocate space for, and create a memory bitmap */
X
XBITMAP *
Xbit_alloc(wide, high, data, bits)
Xunsigned short wide, high;
XDATA *data;
Xint bits;	/* in preparation for color */
X{
X   char *malloc();
X   register BITMAP *result;
X   register int size;
X
X   dprintf(stderr,"bit_alloc:\n");
X   if ((result = (BITMAP *) malloc(sizeof(BITMAP))) == (BITMAP *) 0)
X      return (result);
X
X   result->x0 = 0;
X   result->y0 = 0;
X   result->high = high;
X   result->wide = wide;
X
X   size = ((wide+BITS)/8) * high;
X
X   if (data != (DATA *) 0) {
X      result->data = data;
X      if (MSB==1) {
X         flip(data,size/sizeof(DATA));
X         }
X		}
X   else {
X		if ((result->data = (DATA *) malloc(size)) == (DATA *) 0) {
X      	free(result);
X      	return ((BITMAP *) 0);
X   		}
X		bzero(result->data,size);
X		}
X
X	if ((int) result->data &3)
X      fprintf(stderr,"bit_alloc(): boundary alignment error\n");
X   result->primary = result;
X   result->type = _MEMORY;
X   dprintf(stderr,"  Created %d,%d %d,%d (%d)\n", result->x0, result->y0,
X	       result->wide, result->high, size);
X   return (result);
X	}
X
X/* flip the bit order on count elements of s */
X
Xstatic unsigned char flp[256] = {
X	0x00,	0x80,	0x40,	0xc0,	0x20,	0xa0,	0x60,	0xe0,
X	0x10,	0x90,	0x50,	0xd0,	0x30,	0xb0,	0x70,	0xf0,
X	0x08,	0x88,	0x48,	0xc8,	0x28,	0xa8,	0x68,	0xe8,
X	0x18,	0x98,	0x58,	0xd8,	0x38,	0xb8,	0x78,	0xf8,
X	0x04,	0x84,	0x44,	0xc4,	0x24,	0xa4,	0x64,	0xe4,
X	0x14,	0x94,	0x54,	0xd4,	0x34,	0xb4,	0x74,	0xf4,
X	0x0c,	0x8c,	0x4c,	0xcc,	0x2c,	0xac,	0x6c,	0xec,
X	0x1c,	0x9c,	0x5c,	0xdc,	0x3c,	0xbc,	0x7c,	0xfc,
X	0x02,	0x82,	0x42,	0xc2,	0x22,	0xa2,	0x62,	0xe2,
X	0x12,	0x92,	0x52,	0xd2,	0x32,	0xb2,	0x72,	0xf2,
X	0x0a,	0x8a,	0x4a,	0xca,	0x2a,	0xaa,	0x6a,	0xea,
X	0x1a,	0x9a,	0x5a,	0xda,	0x3a,	0xba,	0x7a,	0xfa,
X	0x06,	0x86,	0x46,	0xc6,	0x26,	0xa6,	0x66,	0xe6,
X	0x16,	0x96,	0x56,	0xd6,	0x36,	0xb6,	0x76,	0xf6,
X	0x0e,	0x8e,	0x4e,	0xce,	0x2e,	0xae,	0x6e,	0xee,
X	0x1e,	0x9e,	0x5e,	0xde,	0x3e,	0xbe,	0x7e,	0xfe,
X	0x01,	0x81,	0x41,	0xc1,	0x21,	0xa1,	0x61,	0xe1,
X	0x11,	0x91,	0x51,	0xd1,	0x31,	0xb1,	0x71,	0xf1,
X	0x09,	0x89,	0x49,	0xc9,	0x29,	0xa9,	0x69,	0xe9,
X	0x19,	0x99,	0x59,	0xd9,	0x39,	0xb9,	0x79,	0xf9,
X	0x05,	0x85,	0x45,	0xc5,	0x25,	0xa5,	0x65,	0xe5,
X	0x15,	0x95,	0x55,	0xd5,	0x35,	0xb5,	0x75,	0xf5,
X	0x0d,	0x8d,	0x4d,	0xcd,	0x2d,	0xad,	0x6d,	0xed,
X	0x1d,	0x9d,	0x5d,	0xdd,	0x3d,	0xbd,	0x7d,	0xfd,
X	0x03,	0x83,	0x43,	0xc3,	0x23,	0xa3,	0x63,	0xe3,
X	0x13,	0x93,	0x53,	0xd3,	0x33,	0xb3,	0x73,	0xf3,
X	0x0b,	0x8b,	0x4b,	0xcb,	0x2b,	0xab,	0x6b,	0xeb,
X	0x1b,	0x9b,	0x5b,	0xdb,	0x3b,	0xbb,	0x7b,	0xfb,
X	0x07,	0x87,	0x47,	0xc7,	0x27,	0xa7,	0x67,	0xe7,
X	0x17,	0x97,	0x57,	0xd7,	0x37,	0xb7,	0x77,	0xf7,
X	0x0f,	0x8f,	0x4f,	0xcf,	0x2f,	0xaf,	0x6f,	0xef,
X	0x1f,	0x9f,	0x5f,	0xdf,	0x3f,	0xbf,	0x7f,	0xff,
X	};
X
Xint
Xflip(s,count,how)
Xregister DATA *s;
Xregister int count;
Xint how;						/* number of chars is data type */
X	{
X	while (count-- > 0) 
X		*s++ = ~((flp[*s&0xff]) | (flp[*s>>8&0xff]<<8) |
X				 (flp[*s>>16&0xff]<<16) | (flp[*s>>24&0xff]<<24));
X	}
X
END_OF_bitmap.c
if test 6563 -ne `wc -c <bitmap.c`; then
    echo shar: \"bitmap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bitmap.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"bitmap.h\"
else
echo shar: Extracting \"bitmap.h\" \(3923 characters\)
sed "s/^X//" >bitmap.h <<'END_OF_bitmap.h'
X/*                        Copyright (c) 1987,1989 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: bitmap.h,v 4.2 88/07/19 14:19:23 sau Exp $
X	$Source: /tmp/mgrsrc/src/oblit/RCS/bitmap.h,v $
X*/
Xstatic char	h_bitmap_[] = "$Source: /tmp/mgrsrc/src/oblit/RCS/bitmap.h,v $$Revision: 4.2 $";
X
X/* header file for SUN version of portable bitblit code */
X
X#define bzero(b1, n) memset(b1, 0, n)
X#define random rand
X
X#ifndef Min
X#define Min(x,y)	((x)>(y)?y:x)
X#endif
X
Xtypedef unsigned short DATA;				/* basic frame buffer word size */
X
X/****************************/
X/* Machine configurations go here */
X
X/* this defines how bits get shifted out of each word */
X
X#define GETMSB(word,shift)	\
X	(DATA) (word >> shift)					/* get left bits in word */
X#define GETLSB(word,shift) \
X	(DATA) (word << shift)					/* get right bits in word */
X
X#define LOGBITS	4						/* Log2 of bits in type DATA */
X#define BITS	(~(~0 << LOGBITS))	/* mask for bit# within word */
X#define MSB		((DATA)~GETLSB((DATA)~0,1))		/* most sig bit set */
X#define LSB		((DATA)~GETMSB((DATA)~0,1))		/* most sig bit set */
X#define DOFLIP (MSB==1)								/* need to flip bytes */
X
X/****************************/
X
X#define ROP_INVERT(x) (x)							/* punt for now */
X
X#define bit_blit(dest,dx,dy,width,height,func,source,sx,sy)  \
X	mem_rop(dest,dx,dy,width,height,func,source,sx,sy) 
X
X#define bit_static(name,wide,high,data,n)	\
X	BITMAP name = {(DATA *) data, &name, 0, 0, wide, high, _STATIC};
X
X#define NULL_DATA	((DATA *) 0)
X#define BIT_NULL	((BITMAP *) 0)
X
X#define IS_SCREEN(x)	(3&(x)->type==_SCREEN)
X#define IS_MEMORY(x)	(3&(x)->type==_MEMORY)
X#define IS_PRIMARY(x)	((x)->primary == (x))
X#define SET_FLIP(x)     ((x)->primary->type |= DOFLIP ? _FLIP : 0)
X
X/*
X * OPCODE(expr), where expr is boolean expression involving SRC and DST,
X * is one of sixteen numbers encoding a rasterop opcode.
X */
X
X#define			DST 	0xA	/* 1010 */
X#define			SRC	0xC	/* 1100 */
X#define OPCODE(expr)	(0xF&(expr))
X
X/* names for common bitblit functions */
X
X#ifndef BIT_NOT
X#   define BIT_NOT(x)	(~(x))
X#endif
X#define BIT_SRC		SRC
X#define BIT_DST		DST
X#define BIT_SET		(BIT_SRC|BIT_NOT(BIT_SRC))
X#define BIT_CLR		(BIT_SRC&BIT_NOT(BIT_SRC))
X#define BIT_XOR		(BIT_SRC^BIT_DST)
X#define BIT_INVERT	(BIT_NOT(DST))
X#define GET_OP(x)	((x)&0xf)
X
X/* bitmap types */
X
X#define _SCREEN		1		/* frame buffer */
X#define _MEMORY		2		/* malloc'd space */
X#define _STATIC		3		/* don't free space at destroy time */
X#define _FLIP			4		/* flip the bits?? */
X
X/* member access macros */
X
X#define BIT_X(x)	x->x0
X#define BIT_Y(x)	x->y0
X#define BIT_DATA(x)	x->data
X#define BIT_WIDE(x)	x->wide
X#define BIT_HIGH(x)	x->high
X#define BIT_DEPTH(x)	1		/* no color support for now */
X
X#define BIT_SIZE(m) BIT_Size(BIT_WIDE(m), BIT_HIGH(m), BIT_DEPTH(m)) /* bytes */
X#define BIT_Size(wide,high,d)     (((d)*((wide+BITS)&~BITS)*high)>>3) /* bytes*/
X#define BIT_LINE(x)	((x->primary->wide+BITS)>>LOGBITS)/* words on scan line */
X
X/* structure and type definitions */
X
Xtypedef struct bitmap {
X   DATA	*data;		/* bitmap data */
X   struct bitmap	*primary;	/* pointer to primary bitmap */
X   short		x0, y0;				/* starting coordinates, in bits */
X   short		wide, high;			/* bitmap size, in bits */
X   unsigned short	type;			/* bitmap type */
X   } BITMAP;
X
X/* function declarations */
X
Xint mem_rop();
Xint bit_destroy();
Xint bit_line();
XBITMAP * bit_create();
XBITMAP * bit_alloc();
XBITMAP * bit_open();
X
X/* for non existant color support */
X
X#define DEPTH				1			/* bits per pixel */
X#define NOCOLOR         0xF
X#define GETCOLOR(x)     0
X#define PUTCOLOR(x)     0
X
X/* other */
X
X#define Bprintf(x)	/* gone */
X
END_OF_bitmap.h
if test 3923 -ne `wc -c <bitmap.h`; then
    echo shar: \"bitmap.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f blit.C -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"blit.C\"
else
echo shar: Extracting \"blit.C\" \(12909 characters\)
sed "s/^X//" >blit.C <<'END_OF_blit.C'
X/*                        Copyright (c) 1989 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*
X  	$Header:
X	$Source:
X*/
Xstatic char	RCSid_[] = "$Source:";
X
X/* bitblit code template generator for portable bitblt code */
X
X%include <stdio.h>
X%include "bitmap.h"
X
X%define RIGHT		0x0	/* direction right -> left */
X%define DOWN		0x0	/* direction top->bottom */
X%define UP			0x10	/* direction bottom up */
X%define LEFT		0x20	/* direction right to left */
X%define SMALL		0x40	/* less than 1 full word */
X%define ALIGNED	0x80	/* src & dst aligned, no shifts */
X%define NSRC	1		/* no source required */
X
Xextern int bit_debug;
Xextern BITMAP *screen;
X
X%define dprintf	if(bit_debug)fprintf
X
Xstatic char nsrc[16] = {		/* fold no source cases */
X	0,0,0,0,
X	0xf&~DST, 0xf&~DST, 0xf&~DST, 0xf&~DST,
X	0xf&DST, 0xf&DST, 0xf&DST, 0xf&DST, 
X	0xf, 0xf, 0xf, 0xf
X	};
X
Xstatic char zsrc[16] = {		/* no source req'd cases */
X	1,0,0,0,0,
X	1,0,0,0,0,
X	1,0,0,0,0,
X	1 };	
X
X/* table of inverted bitblts (changes the sense of black and white) */
X
Xchar op_invert[16] = {
X	15, 7, 11, 3, 13, 5, 9, 1, 14, 6, 10, 2, 12, 4, 8, 0
X	};
X
X/* the 16 bit-blit functions */
X
X5define ZERO(d,s)	(0)
X5define NOR(d,s)	(~((d)|(s)))
X5define AND2(d,s)	((d)&~(s))
X5define NPROJ2(d,s)	(~(s))
X5define AND1(d,s)	(~(d)&(s))
X5define NPROJ1(d,s)	(~(d))
X5define XOR(d,s)	((d)^(s))
X5define NAND(d,s)	(~((d)&(s)))
X5define AND(d,s)	((d)&(s))
X5define NXOR(d,s)	(~((d)^(s)))
X5define PROJ1(d,s)	((d))
X5define OR2(d,s)	((d)|~(s))
X5define PROJ2(d,s)	(s)
X5define OR1(d,s)	(~(d)|(s))
X5define OR(d,s)		((d)|(s))
X5define ONE(d,s)	(~0)
X
X/* The templates go here.  I could combine right->left and left-> right
X   into a single template, but its probably not worth the bother.
X   The src & dst aligned cases are needed because 32 bit shifts are
X   undefined (and wrong on the 3100).
X*/
X
X/* single word bitblt */
X
X2define Rop_s(op) \
X   for (i=count; i>0; i--) {			\
X      osrc = src;  src++;					\
X      *dst = op(*dst,((GETLSB(lmask,lshift) ? GETMSB(*osrc,lshift) : 0) \
X		 | GETLSB(*src,rshift))) & lmask | (*dst & ~lmask);\
X      src += s_skip;  dst += d_skip;				\
X      }
X
X/* single word bitblt (src and dst aligned) */
X
X2define Rop_sa(op) \
X   for (i=count; i>0; i--) {			\
X      *dst++ = op(*dst,*src++) & lmask | (*dst & ~lmask);\
X      src += s_skip;  dst += d_skip;				\
X      }
X
X/* multiword left to right bitblt (src and dst aligned) */
X
X2define Rop_incr_a(op) \
X   for (i=count; i>0; i--) {			\
X      *dst++ = op(*dst,*src++) & lmask | (*dst & ~lmask);\
X      LOOP(words-2,*dst++ = op(*dst,*src++)); \
X      *dst++ = op(*dst,*src++) & rmask | (*dst & ~rmask);\
X      src += s_skip;  dst += d_skip;				\
X      }
X
X/* multiword right to left bitblt (source and dest aligned) */
X
X2define Rop_decr_a(op) \
X   for (i=count; i>0; i--) {			\
X      *dst-- = op(*dst,*src--) & rmask | (*dst & ~rmask);\
X      LOOP(words-2,*dst-- = op(*dst,*src--)); \
X      *dst-- = op(*dst,*src--) & lmask | (*dst & ~lmask);\
X      src += s_skip;  dst += d_skip;				\
X      }
X
X/* multiword left to right bitblt */
X
X2define Rop_incr_m(op) \
X   for (i=count; i>0; i--) {			\
X      osrc = src;  src++;					\
X      *dst++ = op(*dst,((GETLSB(lmask,lshift) ? GETMSB(*osrc,lshift) : 0) \
X		 | GETLSB(*src++,rshift))) & lmask | (*dst & ~lmask);\
X      osrc++; \
X      LOOP(words-2,*dst++ = \
X			op(*dst,GETMSB(*osrc++,lshift) | GETLSB(*src++,rshift)) \
X			); \
X      *dst++ = op(*dst,(GETMSB(*osrc++,lshift) | GETLSB(*src++,rshift))) \
X					& rmask | (*dst & ~rmask);\
X      src += s_skip;  dst += d_skip;				\
X      }
X
X/* multiword right to left bitblt */
X
X2define Rop_decr_m(op) \
X   for (i=count; i>0; i--) {			\
X      osrc = src;  osrc--;					\
X      *dst-- = op(*dst,(GETMSB(*osrc--,lshift) | GETLSB(*src--,rshift))) \
X					& rmask | (*dst & ~rmask);\
X      LOOP(words-2,*dst-- = \
X			op(*dst,GETMSB(*osrc--,lshift) | GETLSB(*src--,rshift)) \
X			); \
X      *dst-- = op(*dst,((GETLSB(lmask,lshift) ? GETMSB(*osrc--,lshift) : 0) \
X		 | GETLSB(*src--,rshift))) & lmask | (*dst & ~lmask);\
X      osrc--; \
X      src += s_skip;  dst += d_skip;				\
X      }
X
X#ifdef UNROLL
X
X/* an unrolled loop (some compilers -i.e. DEC3100 can't unroll 16 at a time) */
X
X3define LOOP(n,s) {					\
X    register int cnt;					\
X    for (cnt=(n); cnt>=8; cnt-=8) {		\
X       s;s;s;s;s;s;s;s;			\
X       }						\
X    switch (cnt) {					\
X       case  7: s; case  6: s; case  5: s; case  4: s;	\
X       case  3: s; case  2: s; case  1: s; 		\
X       }						\
X    }
X#else
X3define LOOP(n,s) {\
X    register int cnt;\
X    for (cnt=(n); cnt>0; cnt--) {\
X       s;\
X		} \
X    }
X#endif
X
X/* do all 16 cases */
X
X1define SWITCH(op,func) \
X		switch(op&0xf) { \
X			case OPCODE(ZERO(DST,SRC)):	func(ZERO);		break; \
X			case OPCODE(NOR(DST,SRC)):		func(NOR);		break; \
X			case OPCODE(AND2(DST,SRC)):	func(AND2);		break; \
X			case OPCODE(NPROJ2(DST,SRC)):	func(NPROJ2);	break; \
X			case OPCODE(AND1(DST,SRC)):	func(AND1);		break; \
X			case OPCODE(NPROJ1(DST,SRC)):	func(NPROJ1);	break; \
X			case OPCODE(XOR(DST,SRC)):	 	func(XOR);		break; \
X			case OPCODE(NAND(DST,SRC)):	func(NAND);		break; \
X			case OPCODE(AND(DST,SRC)):		func(AND);		break; \
X			case OPCODE(NXOR(DST,SRC)):	func(NXOR);		break; \
X			case OPCODE(PROJ1(DST,SRC)):	func(PROJ1);	break; \
X			case OPCODE(OR2(DST,SRC)):		func(OR2);		break; \
X			case OPCODE(PROJ2(DST,SRC)):	func(PROJ2);	break; \
X			case OPCODE(OR1(DST,SRC)):	 	func(OR1);		break; \
X			case OPCODE(OR(DST,SRC)):		func(OR);		break; \
X			case OPCODE(ONE(DST,SRC)):		func(ONE);		break; \
X			}
X
X1define XWITCH(op,func)		/* use to turn off cases for debugging */
X
Xmem_rop(dst_map,x_dst,y_dst,wide,high,op,src_map,x_src,y_src)
XBITMAP *dst_map;				/* source bitmap */
XBITMAP *src_map;				/* destination bitmap */
Xint x_dst,y_dst;				/* destination coords */
Xint x_src,y_src;				/* source coords */
Xint wide,high;					/* bitmap size */
Xint op;							/* bitmap function */
X   {
X	register DATA *dst;		/* dest bitmap base addresses */
X	register DATA *src;		/* source bitmap base addresses */
X	register DATA *osrc;		/* previous source addr */
X
X	register int s_offset;			/* source bit offset */
X	register int d_skip;				/* words to next line in dst_map */
X	register int s_skip;				/* words to next line in src_map */
X	register int count=high;		/* # of rows */
X   register int words;				/* words across in inner loop (>32 bits) */
X   register DATA lmask;		/* bits on left to next long boundary */
X   register DATA rmask;		/* bits from last long on right */
X	register int lshift;				/* bits to shift left on next word */
X	register int rshift;				/* bits to shift right on previous word */
X	register int i;
X
X	/* clipping and argument checking */
X
X	if (!src_map) {
X      if (bit_debug && op&0xf != 0xf&nsrc[op&0xf])
X		   fprintf(stderr,"no src_map, setting op %d->%d\n",op&0xf,nsrc[op&0xf]);
X      op = 0xf&nsrc[op&0xf];						/* a NULL src_map sources 1's */
X		}
X
X	else if (zsrc[op&0xf])					 {
X      if (bit_debug && src_map)
X		   fprintf(stderr,"op=%d, setting src_map->NULL\n",op&0xf);
X		src_map == BIT_NULL;							/* don't check no src_map cases */
X		}
X
X#ifdef INVERT
X	/* invert all raster ops */
X	op = op_invert[15&op];
X#endif
X
X%ifndef NOCLIP
X	
X	if (wide<0) {
X		dprintf(stderr,"Clip: w<0 (%d)\n",wide);
X		x_dst += wide;
X		wide = - wide;
X		}
X
X	if (count<0) {
X		y_dst += count;
X		count = - count;
X		dprintf(stderr,"Clip: h<0 (%d)\n",count);
X		}
X
X   if (x_dst < 0) {
X		dprintf(stderr,"Clip: x_dst<0 (%d)\n",x_dst);
X		if (src_map)
X			x_src -= x_dst;
X		wide += x_dst;
X		x_dst = 0;
X		}
X
X   if (y_dst < 0) {
X		dprintf(stderr,"Clip: y_dst<0 (%d)\n",y_dst);
X		if (src_map)
X			y_src -= y_dst;
X		count += y_dst;
X		y_dst = 0;
X		}
X
X	if (src_map) {
X		if (x_src < 0) {
X			dprintf(stderr,"Clip: x_src<0 (%d)\n",x_src);
X			x_dst -= x_src;
X			wide += x_src;
X			x_src = 0;
X			}
X
X		if (y_src < 0) {
X			dprintf(stderr,"Clip: y_src<0 (%d)\n",y_src);
X			y_dst-=y_src;
X			count+=y_src;
X			y_src=0;
X			}
X			
X		if ((i = x_src+wide - src_map->wide) > 0) {
X			dprintf(stderr,"Clip: wide too big for src (%d->%d)\n",wide,wide-i);
X			wide -= i;
X			}
X
X		if ((i = y_src+count - src_map->high) > 0) {
X			dprintf(stderr,"Clip: high too big for src (%d->%d)\n",count,count-i);
X			count -= i;
X			}
X		}
X
X	if ((i = x_dst + wide - dst_map->wide) > 0) {
X		dprintf(stderr,"Clip: wide too big for dst_map (%d->%d)\n",wide,wide-i);
X		wide -= i;
X		}
X	if ((i = y_dst + count - dst_map->high) > 0) {
X		dprintf(stderr,"Clip: high too big for dst_map (%d->%d)\n",count,count-i);
X		count -= i;
X		}
X
X	if (wide<1 || count < 1) {
X		dprintf(stderr,"Clip: high or wide < 1 (%d,%d)\n",wide,count);
X		return(-1);
X		}
X
X	/* end of clipping code */
X
X%endif
X
X	x_dst += dst_map->x0;
X	y_dst += dst_map->y0;
X	i=0;
X
X	/* set initial conditions */
X
X	if (DOFLIP && dst_map->primary->type&_FLIP) {
X		flip(dst_map->data,BIT_LINE(dst_map)*dst_map->primary->high);
X		dst_map->primary->type &= 3;
X		}
X
X	words = ((x_dst+wide-1)>>LOGBITS) - (x_dst>>LOGBITS) + 1;
X	lmask = GETLSB((DATA) ~0, (x_dst&BITS));
X	rmask = GETMSB((DATA) ~0, (BITS - ((x_dst+wide-1)&BITS)));
X	dst = dst_map->data + BIT_LINE(dst_map)*y_dst + (x_dst>>LOGBITS);
X	d_skip = BIT_LINE(dst_map);		/* longs to next row */
X
X
X   if (src_map) {
X
X		if (DOFLIP && src_map->primary->type&_FLIP) {
X			flip(src_map->data,BIT_LINE(src_map)*src_map->primary->high);
X			src_map->primary->type &= 3;
X			}
X
X		x_src += src_map->x0;
X		y_src += src_map->y0;
X		src = src_map->data + BIT_LINE(src_map)*y_src + (x_src>>LOGBITS);
X		s_skip = BIT_LINE(src_map);
X		lshift = (x_src&BITS) - (x_dst&BITS);
X		if (lshift > 0) {
X			rshift = (BITS+1) - lshift;
X			}
X		else  if (lshift < 0){
X			rshift = -lshift;
X			lshift = (BITS+1) - rshift;
X			src --;
X			}
X		else {
X			i |= ALIGNED;
X			}
X
X		/* set blit direction */
X
X		if (src_map->data == dst_map->data) {
X			if (y_dst>y_src)
X				i |= UP;
X			if (x_dst>x_src)
X				i |= LEFT;
X			}
X
X		}
X
X	if (words <=1 ) {
X		i |= SMALL;
X		lmask &= rmask;
X		}
X
X	/* do the bitblt */
X
X/*
X	dprintf(stderr,"DIR(%x) %dx%d %d,%d->%d,%d (0x%x->0x%x)\n",
X			i,count,wide,x_src,y_src,x_dst,y_dst,src,dst);
X*/
X
X   switch(i) {
X	case RIGHT|DOWN:					/* top->bottom		left->right */
X		d_skip -= words;
X		s_skip -= (words + 1);
X		SWITCH(op,Rop_incr_m);
X      break;
X
X	case RIGHT|DOWN|SMALL:					/* top->bottom		small */
X	case LEFT|DOWN|SMALL:
X		d_skip -= words - 1;
X		s_skip -= words;
X		SWITCH(op,Rop_s);
X      break;
X
X	case RIGHT|DOWN|ALIGNED:		/* top->bottom		left->right */
X		d_skip -= words;
X		s_skip -= words;
X		SWITCH(op,Rop_incr_a);
X      break;
X
X	case RIGHT|DOWN|SMALL|ALIGNED:		/* top->bottom		small */
X	case LEFT|DOWN|SMALL|ALIGNED:	
X		d_skip -= words;
X		s_skip -= words;
X		SWITCH(op,Rop_sa);
X      break;
X
X	case RIGHT|UP:						/* bottom->top		left->right */
X		dst += d_skip*(count-1);
X		d_skip = - (d_skip + words);
X		if (src_map) {
X			src += s_skip*(count-1);
X			s_skip = - (s_skip + words + 1);
X			}
X		SWITCH(op,Rop_incr_m);
X      break;
X
X	case RIGHT|UP|SMALL:						/* bottom->top		small */
X	case LEFT|UP|SMALL:						/* bottom->top		small */
X		dst += d_skip*(count-1);
X		d_skip = - (d_skip + words - 1);
X		if (src_map) {
X			src += s_skip*(count-1);
X			s_skip = - (s_skip + words);
X			}
X		SWITCH(op,Rop_s);
X      break;
X
X	case RIGHT|UP|ALIGNED:					/* bottom->top		left->right */
X		dst += d_skip*(count-1);
X		d_skip = - (d_skip + words);
X		if (src_map) {
X			src += s_skip*(count-1);
X			s_skip = - (s_skip + words);
X			}
X		SWITCH(op,Rop_incr_a);
X      break;
X
X	case RIGHT|UP|SMALL|ALIGNED:					/* bottom->top		left->right */
X	case LEFT|UP|SMALL|ALIGNED:
X		dst += d_skip*(count-1);
X		d_skip = - (d_skip + words);
X		if (src_map) {
X			src += s_skip*(count-1);
X			s_skip = - (s_skip + words);
X			}
X		SWITCH(op,Rop_sa);
X      break;
X
X	case LEFT|DOWN:					/* top->bottom		right->left */
X		dst += words - 1;
X		d_skip += words;
X		if (src_map) {
X			src += words;
X			s_skip += words;
X			}
X		SWITCH(op,Rop_decr_m);
X      break;
X
X	case LEFT|DOWN|ALIGNED:			/* top->bottom		right->left */
X		dst += words - 1;
X		d_skip += words;
X		if (src_map) {
X			src += words - 1;
X			s_skip += words;
X			}
X		SWITCH(op,Rop_decr_a);
X      break;
X
X	case UP|LEFT:						/* bottom->top		right->left */
X		dst += d_skip*(count-1) + words - 1;
X		d_skip = - (d_skip - words);
X		if (src_map) {
X			src += s_skip*(count-1) + words;
X			s_skip = -(s_skip - words);
X			}
X		SWITCH(op,Rop_decr_m);
X      break;
X
X	case UP|LEFT|ALIGNED:					/* bottom->top		right->left */
X		dst += d_skip*(count-1) + words - 1;
X		d_skip = - (d_skip - words);
X		if (src_map) {
X			src += s_skip*count + words - 1;
X			s_skip = -(s_skip - words );
X			}
X		SWITCH(op,Rop_decr_a);
X      break;
X
X	default:
X		dprintf(stderr,"Invalid direction: 0x%x\n",i);
X		break;
X		}
X	return(0);
X  	}
X
END_OF_blit.C
if test 12909 -ne `wc -c <blit.C`; then
    echo shar: \"blit.C\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f line.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"line.c\"
else
echo shar: Extracting \"line.c\" \(4843 characters\)
sed "s/^X//" >line.c <<'END_OF_line.c'
X/*                        Copyright (c) 1989 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: line.c,v 1.3 89/05/25 07:51:36 sau Locked $
X	$Source: /usr/u/sau/mgr/src/dec/RCS/line.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /usr/u/sau/mgr/src/dec/RCS/line.c,v $$Revision: 1.3 $";
X
X#include "bitmap.h"
X
X/*  Draw a line  - Bresenham method , portable Bitblt version
X */
X
Xbit_line(dest, x0, y0, x1, y1, func)
Xregister BITMAP *dest;				/* destination bitmap */	
Xint x0, y0, x1, y1;					/* line coordinates */
Xint func;								/* set, clear, or invert */
X   {
X   register DATA bit;			/* bit offset in current word */
X   register DATA *dst;				/* current word in bitmap */
X	register int count;				/* current x position in loop */
X	register int err;					/* accumulated error */
X   register int d_incr;				/* words to next scan line */
X   register int rincr, rdecr;
X   int dx, dy;							/* # of pixels in x and y */
X   int temp;
X
X   /* clip here */
X
X#ifndef NOCLIP
X
X#define TOP	001
X#define BOTTOM	002
X#define LEFT	004
X#define RIGHT	010
X#define CROSS(x,y) \
X	  (x<0 ? LEFT : x>= (dest->wide) ? RIGHT : 0) + \
X	  (y < 0 ? TOP : y >=  (dest -> high) ? BOTTOM : 0)
X
X      {
X
X      /* The classic line clipping algorithm */
X
X      register int cross0 = CROSS(x0, y0);
X      register int cross1 = CROSS(x1, y1);
X
X      while (cross0 || cross1) {
X	      int cross, x, y;
X	      if (cross0 & cross1)
X	         return;
X	      if (cross0 != 0)
X	         cross = cross0;
X	      else
X	         cross = cross1;
X	      if (cross & (LEFT | RIGHT)) {
X	         int edge = (cross & LEFT) ? 0 : dest->wide - 1;
X	         y = y0 + (y1 - y0) * (edge - x0) / (x1 - x0);
X	         x = edge;
X	         }
X	      else if (cross & (TOP | BOTTOM)) {
X	         int edge = (cross & TOP) ? 0 : dest->high - 1;
X	         x = x0 + (x1 - x0) * (edge - y0) / (y1 - y0);
X	         y = edge;
X	         }
X	      if (cross == cross0) {
X	         x0 = x;
X	         y0 = y;
X	         cross0 = CROSS(x, y);
X	         }
X	      else {
X	         x1 = x;
X	         y1 = y;
X	         cross1 = CROSS(x, y);
X	         }
X         }
X      }
X
X   /* end of clipping */
X
X#endif
X
X   x0 += dest->x0;
X   y0 += dest->y0;
X   x1 += dest->x0;
X   y1 += dest->y0;
X
X   /* always draw left to right */
X
X   if (x1 < x0) {
X      temp = x1, x1 = x0, x0 = temp;
X      temp = y1, y1 = y0, y0 = temp;
X      }
X   dx = x1 - x0;
X   dy = y1 - y0;
X
X   d_incr = BIT_LINE(dest);
X   dst = y0 * d_incr + (x0>>LOGBITS) +  (dest->data);
X   bit = GETLSB(MSB,(x0&BITS));
X
X   if (dy <= 0)
X      d_incr = -d_incr, dy = -dy;
X
X#ifdef INVERT
X	/* invert all raster ops */
X
X	func = op_invert[15&func];
X#endif
X
X#define XMOVE if ((bit=GETLSB(bit,1))==0) {bit = MSB; dst++;}
X#define YMOVE dst += d_incr
X
X#define STEP(dx,dy,xmove,ymove,op) {		\
X    rincr = (dx - dy)<<1;			\
X    rdecr = -(dy<<1);				\
X    err = dx + rdecr;				\
X    for (count = dx; count >= 0; count--) {	\
X        op;	    				\
X        xmove;	    				\
X        if (err < 0) {				\
X            ymove;				\
X            err += rincr;				\
X            }					\
X        else {					\
X            err += rdecr;				\
X            }					\
X        } 					\
X    }
X
X   if (dx > dy) {			/* gentle slope (this could be made faster) */
X      switch (OPCODE(func)) {
X	      case OPCODE(SRC):
X	      case OPCODE(SRC | DST):
X	      case OPCODE(SRC | ~DST):
X	      case OPCODE(~0):
X    	      STEP(dx, dy, XMOVE, YMOVE, *dst |= bit);				/* set */
X	         break;
X	      case OPCODE(~SRC):
X	      case OPCODE(~(SRC|DST)):
X	      case OPCODE(DST & ~SRC):
X	      case OPCODE(0):
X    	      STEP(dx, dy, XMOVE, YMOVE, *dst &= ~bit);			/* clear */
X	         break;
X	      case OPCODE(SRC ^ DST):
X	      case OPCODE(~DST):
X	      case OPCODE(SRC & ~DST):
X	      case OPCODE(~(SRC&DST)):
X    	      STEP(dx, dy, XMOVE, YMOVE, *dst ^= bit);				/* invert */
X	         break;
X         }
X      }
X   else	{			/* steep slope */
X      switch (OPCODE(func)) {
X	      case OPCODE(SRC):
X	      case OPCODE(SRC | DST):
X	      case OPCODE(SRC | ~DST):
X	      case OPCODE(~0):
X    	      STEP(dy, dx, YMOVE, XMOVE, *dst |= bit);				/* set */
X	         break;
X	      case OPCODE(~SRC):
X	      case OPCODE(~(SRC|DST)):
X	      case OPCODE(DST & ~SRC):
X	      case OPCODE(0):
X    	      STEP(dy, dx, YMOVE, XMOVE, *dst &= ~bit);			/* clear */
X	         break;
X	      case OPCODE(SRC ^ DST):
X	      case OPCODE(~DST):
X	      case OPCODE(SRC & ~DST):
X	      case OPCODE(~(SRC&DST)):
X    	      STEP(dy, dx, YMOVE, XMOVE, *dst ^= bit);				/* invert */
X	         break;
X         }
X	   }
X   }
X
END_OF_line.c
if test 4843 -ne `wc -c <line.c`; then
    echo shar: \"line.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pixel.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pixel.c\"
else
echo shar: Extracting \"pixel.c\" \(1614 characters\)
sed "s/^X//" >pixel.c <<'END_OF_pixel.c'
X/*                        Copyright (c) 1989 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: pixel.c,v 1.1 89/05/10 18:21:32 sau Locked $
X	$Source: /usr/u/sau/mgr/src/dec/RCS/pixel.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /usr/u/sau/mgr/src/dec/RCS/pixel.c,v $$Revision: 1.1 $";
X
X/* set/clear/ or invert a pixel (Portable version) */
X
X#include "bitmap.h"
X
Xbit_point(map,x,y,op)
Xregister BITMAP *map;
Xregister int x,y;
Xint op;
X   {
X   register int bit;							/* dst bit */
X	register DATA *base;							/* dst word */
X
X   /* clipping */
X
X#ifndef NOCLIP
X   if (x<0 || x>BIT_WIDE(map) || y<0 || y>BIT_HIGH(map))
X      return(-1);
X#endif
X
X#ifdef INVERT
X	/* invert all raster ops */
X
X	op = op_invert[15&op];
X#endif
X
X	x += map->x0;
X	y += map->y0;
X   base = y * BIT_LINE(map) + (x>>LOGBITS) + (map->data);
X   bit = GETLSB(MSB,(x & BITS));
X  
X   switch(OPCODE(op)) {
X		case OPCODE(SRC):
X		case OPCODE(SRC | DST):
X		case OPCODE(SRC | ~DST):
X		case OPCODE(~0):
X			*base |= bit;
X         break;
X		case OPCODE(~SRC):
X		case OPCODE(~(SRC|DST)):
X		case OPCODE(DST & ~SRC):
X		case OPCODE(0):
X			*base &= ~bit;
X         break;
X		case OPCODE(SRC ^ DST):
X		case OPCODE(~DST):
X		case OPCODE(SRC & ~DST):
X		case OPCODE(~(SRC&DST)):
X			*base ^= bit;
X         break;
X      }
X   return(*base&bit);
X   }
X
END_OF_pixel.c
if test 1614 -ne `wc -c <pixel.c`; then
    echo shar: \"pixel.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rops.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rops.c\"
else
echo shar: Extracting \"rops.c\" \(975 characters\)
sed "s/^X//" >rops.c <<'END_OF_rops.c'
X
X/* test random bitblit functions */
X
X#include <stdio.h>
X#include "bitmap.h"
X
X#define message(x) \
X	if(bit_debug){printf("%s\n",x);fflush(stdout);}
X
X#define FRACTION		850				/* maximum blit size (parts/1000)*/
X
Xint bit_debug = 0;
X
Xmain(argc,argv)
Xchar **argv;
X   {
X   register BITMAP *screen;
X   register int x,y,w,h,op,xs,ys;
X	int maxx, maxy;
X	int min,max;
X	int count;
X
X   bit_debug = getenv("DEBUG");
X
X   screen = bit_open("/dev/bwtwo0");
X	
X	if (argc < 3) {
X		printf("usage: %s min_size max_size count\n",*argv);
X		exit(1);
X		}
X
X	min = atoi(argv[1]);
X	max = atoi(argv[2]);
X	count = atoi(argv[3]);
X
X	if (min >= max)
X		max = min +1;
X	maxx = max-min;
X	maxy = max-min;
X
X	while (count-- > 0) {
X		op = random()&15;
X		w = min + random()%maxx;
X		h = min + random()%maxy;
X		x = random()%(BIT_WIDE(screen)-w);
X		y = random()%(BIT_HIGH(screen)-h);
X		xs = random()%(BIT_WIDE(screen)-w);
X		ys= random()%(BIT_HIGH(screen)-h);
X      mem_rop(screen,x,y,w,h,op,screen,xs,ys);
X      }
X   }
X
END_OF_rops.c
if test 975 -ne `wc -c <rops.c`; then
    echo shar: \"rops.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f test_line.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"test_line.c\"
else
echo shar: Extracting \"test_line.c\" \(633 characters\)
sed "s/^X//" >test_line.c <<'END_OF_test_line.c'
X
X/* test small bitblit functions */
X
X
X#include <stdio.h>
X#include "bitmap.h"
X
Xextern int bit_debug;
X
X#define message(x) \
X	if(bit_debug){printf("%s\n",x);fflush(stdout);}
X
X#define SIZE		32				/* basic size */
X
Xint bit_debug = 0;
X
Xmain(argc,argv)
Xchar **argv;
X   {
X   register BITMAP *screen;
X   BITMAP *src,*dst;
X   int wait=1;
X	int size;
X	int x0;
X   register int i,j,x;
X
X   if (argc>1) 
X		size = atoi(argv[1]);
X	else
X		size=SIZE;
X   bit_debug = getenv("DEBUG");
X
X   screen = bit_open("/dev/bwtwo0");
X
X   message("16 bits");
X   for(i=0;i<16;i++) {
X		x0 = i*(size+10);
X      bit_line(screen, x0, x0, 320, 100, BIT_SET);
X      }
X   }
X
END_OF_test_line.c
if test 633 -ne `wc -c <test_line.c`; then
    echo shar: \"test_line.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f test_pixel.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"test_pixel.c\"
else
echo shar: Extracting \"test_pixel.c\" \(624 characters\)
sed "s/^X//" >test_pixel.c <<'END_OF_test_pixel.c'
X
X/* test small bitblit functions */
X
X
X#include <stdio.h>
X#include "bitmap.h"
X
Xextern int bit_debug;
X
X#define message(x) \
X	if(bit_debug){printf("%s\n",x);fflush(stdout);}
X
X#define SIZE		32				/* basic size */
X
Xint bit_debug = 0;
X
Xmain(argc,argv)
Xchar **argv;
X   {
X   register BITMAP *screen;
X   BITMAP *src,*dst;
X   int wait=1;
X	int size;
X	int x0;
X   register int i,j,x;
X
X   if (argc>1) 
X		size = atoi(argv[1]);
X	else
X		size=SIZE;
X   bit_debug = getenv("DEBUG");
X
X   screen = bit_open("/dev/bwtwo0");
X
X   message("16 bits");
X   for(i=0;i<16;i++) {
X		x0 = i*(size+10);
X      bit_point(screen, x0, x0, BIT_SET);
X      }
X   }
X
END_OF_test_pixel.c
if test 624 -ne `wc -c <test_pixel.c`; then
    echo shar: \"test_pixel.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f test_rop.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"test_rop.c\"
else
echo shar: Extracting \"test_rop.c\" \(1485 characters\)
sed "s/^X//" >test_rop.c <<'END_OF_test_rop.c'
X
X/* test small bitblit functions */
X
X
X#include <stdio.h>
X#include "bitmap.h"
X
Xextern int bit_debug;
X
X#define message(x) \
X	if(bit_debug){printf("%s\n",x);fflush(stdout);}
X
X#define SIZE		32				/* basic size */
X
Xint bit_debug = 0;
X
Xmain(argc,argv)
Xchar **argv;
X   {
X   register BITMAP *screen;
X   BITMAP *src,*dst;
X   int wait=1;
X	int size;
X	int x0;
X   register int i,j,x;
X
X   if (argc>1) 
X		size = atoi(argv[1]);
X	else
X		size=SIZE;
X   bit_debug = getenv("DEBUG");
X
X   screen = bit_open("/dev/bwtwo0");
X
X   /* make src and dst */
X
X   src = bit_alloc(size,size,0);
X   dst = bit_alloc(size,size,0);
X   
X   message("Make src and dst");
X
X   mem_rop(src,0,0,size/2,size,BIT_CLR,0,0,0);
X   mem_rop(src,size/2,0,size/2,size,BIT_SET,0,0,0);
X
X   mem_rop(dst,0,0,size,size/2,BIT_CLR,0,0,0);
X   mem_rop(dst,0,size/2,size,size/2,BIT_SET,0,0,0);
X
X   /* test 16 bitmem_rop functions */
X
X   message("16 borders");
X   for(i=0;i<16;i++) {
X		x0 = i*(size+10);
X      mem_rop(screen,10+x0%screen->wide,100+(size+10)*(x0/screen->wide),size,size,BIT_SET,0,0,0);
X		if (wait) sleep(1);
X		}
X   message("16 dst patterns");
X   for(i=0;i<16;i++) {
X		x0 = i*(size+10);
X      mem_rop(screen,12+x0%screen->wide,102+(size+10)*(x0/screen->wide),size-4,size-4,BIT_SRC,dst,2,2);
X		if (wait) sleep(1);
X		}
X   message("16 bit-blt functions");
X   for(i=0;i<16;i++) {
X		x0 = i*(size+10);
X      mem_rop(screen,12+x0%screen->wide,102+(size+10)*(x0/screen->wide),size-4,size-4,i,src,2,2);
X      if (wait) sleep(1);
X      }
X   }
X
END_OF_test_rop.c
if test 1485 -ne `wc -c <test_rop.c`; then
    echo shar: \"test_rop.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0