⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitmap.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1984, 1985, 1986 Xerox Corp. * *  bitmap - routines that help build a bitmap of a graphical image * *  These are primarily used to implement all of the drawing primitives *  (except for lines) * *  HISTORY * 13-Aug-86  Lee Moore (lee) at Xerox Webster Research Center *	Rather than outputing an error message for devices that can't print *	big pixel arrays, the code now breaks up large pixel arrays into *	smaller ones. * * 04-Mar-86  Lee Moore (lee) at Xerox Webster Research Center *	Put in code to check the output device type.  Right now, if *	a bitmap is allocated that won't print then a warning message *	is produced. * *  28-aug-85 John Mellor-Crummey *	added flush_bitmap which is used instead *	of print_bitmap if current page is not outputted * *  17-jun-85  ed flint *	bitmap width(bm_width) must be multiple of 32 *	bits for print services 12 (?) * * */# include <stdio.h># include "iptokens.h"# include "literal.h"# include "operator.h"# include "defs.h"# include "externs.h"# define    local	static# define    No		0# define    Yes		1extern int drawidth;extern double drawscale;char *malloc();local int minx;local int miny;local int maxx;local int maxy;local int bm_width;		/* in real bytes */local int bm_size;local unsigned char *bitmap;local char  bm_active = No;# define    scale_x(x)		x = (double)x * drawscale# define    scale_y(y)		y = (double)y * drawscale/* *  new_bitmap(x1, y1, x2, y2) - prepare for a new bitmap, the extreme x and y *				 values are x1, y1, x2, and y2. */new_bitmap(stroke, x1, y1, x2, y2)int stroke, x1, y1, x2, y2;{    int new_size;    register int temp;#ifdef DEBUG    fprintf(stderr, "new_bitmap(%d, %d, %d, %d, %d)\n", stroke,x1, y1, x2, y2);#endif    drawidth = stroke * drawscale;    scale_x(x1);    scale_y(y1);    scale_x(x2);    scale_y(y2);#ifdef DEBUG    fprintf(stderr, "after scaling: width %d: %d, %d and %d, %d\n", drawidth, x1, y1, x2, y2);#endif    /* insure that x1, y1 is the lower left */    if (x1 > x2)    {#ifdef DEBUG	fprintf(stderr, "exchanging pairs ... ");#endif	temp = x1;	/* exchange x1 and x2 */	x1   = x2;	x2   = temp;	temp = y1;	/* exchange y1 and y2 */	y1   = y2;	y2   = temp;#ifdef DEBUG	fprintf(stderr, "now %d, %d and %d, %d\n", x1, y1, x2, y2);#endif    }    /* adjust the extremes to allow for pen thickness */    temp = (drawidth + 1) / 2;    x1 -= temp;    y1 -= temp;    x2 += temp;    y2 += temp;    if (!bm_active || !(x1 >= minx && y1 >= miny && x2 <= maxx && y2 <= maxy))    {	/* we need to set up a new map */	/* but first, print the old one if it is still active */#ifdef DEBUG	fprintf(stderr, "setting up new map, bm_active is %d\n", bm_active);#endif	print_bitmap();	minx = x1;	miny = y1;	maxx = x2;	maxy = y2;	bm_width = (y2 - y1 + 7) / 8;	/* print services 12 (?) wants packed pixel vectors to produce each */	/* scan line as a mutliple of 32 bits, this is backward compatible  */	/* with previous versions of services				    */	/* (the previous version of bitmap produced 16 bit multiples which  */	/* will NOT work with services 12 (?) and beyond)		    */	if ( bm_width%4 != 0 )	{	    bm_width= bm_width + (4 - bm_width%4);	}	new_size = (x2 - x1) * bm_width;	if (new_size > bm_size)	{	    /* need to allocate a larger area for the bitmap */	    if (bitmap != NULL)		free((char *)bitmap);	    /* check to see that this bitmap is printable */	    if (new_size + 4 >= (1L << 16))	    {#ifdef notdef		if (IPDeviceType == Xerox8044_Services8)		    fprintf(stderr, "dipress: bitmap bigger than 2^16-1 -- won't print on a Xerox 8044 under services 8.0\n");		else if (IPDeviceType == Xerox8044_Services9)		    fprintf(stderr, "dipress: bitmap of %d is bigger than 2^16-1 -- won't print on a Xerox 8044 under services 9.0\n", new_size);		else if (IPDeviceType == Xerox8044_Services10)		    fprintf(stderr, "dipress: bitmap of %d is bigger than 2^16-1 -- won't print on a Xerox 8044 under services 10.0\n", new_size);#endif	    }	    bitmap = (unsigned char *) malloc( (unsigned)(new_size) );	    bm_size = new_size;	}#ifdef DEBUG	fprintf(stderr, "bm_width %d, bm_size %d\n", bm_width, bm_size);#endif    	bzero((char *)bitmap, bm_size);    }}set_pixel(x, y)int x;int y;{    int mask;    int half_drawidth;    register int i;    register int ybit, temp;    register unsigned char *ptr;    scale_x(x);    scale_y(y);    bm_active = Yes;#ifdef DEBUG    if (x < minx || x > maxx || y < miny || y > maxy)    {	fprintf(stderr, "point off map: (%d, %d)\n", x, y);	return;    }#endif    x -= minx;    y  = maxy - y;	/* yes, it works */    half_drawidth = drawidth >> 1;    /* Remember the bitmap is built in increasing y */    /* draw the "x" line vertically */    mask = 0x80 >> (y & 007);    ptr = (x - half_drawidth) * bm_width + (y >> 3) + bitmap;    for (i = 0; i < drawidth; i++, ptr += bm_width)    {	*ptr |= mask;    }    /* draw the "y" line horizontally */    y -= half_drawidth;    ptr = (x * bm_width) + (y >> 3) + bitmap;    ybit = y & 007;    temp = ybit + drawidth;    if (temp < 8)    {	/* special case -- less than one byte */	*ptr |= (0xff >> ybit) ^ (0xff >> temp);    }    else    {	*ptr |= (0xff >> ybit);	for (i = drawidth - 8 + ybit; i > 8; i -= 8)	{	    *++ptr |= 0xff;	}	*++ptr |= ~(0xff >> i);    }}flush_bitmap(){	bm_active = No;}print_bitmap(){    int	bytesPerScanLine;#ifdef DEBUG2    int x;    int y;    int i;    char *ptr;#endif    if (!bm_active)    {	/* don't bother */	return;    }#ifdef DEBUG2    /* debugging version for now */    ptr = bitmap;    for (x = minx; x <= maxx; x++)    {	for (y = miny; y <= maxy; y += 8, ptr++)	{	    for (i = 0x80; i != 0; i >>= 1)	    {		if (*ptr & i)		{		    putchar('*');		}		else		{		    putchar(' ');		}	    }	}	putchar('\n');    }#endif    bytesPerScanLine = bm_width;    /* inside a dosavesimplebody to preserve transform */    AppendOp(OP_dosavesimplebody);    AppendOp(OP_beginBody);    /* set the transform to the right scale and position */    /* transform must scale back to micas and position bitmap */    AppendInteger((long) minx);    AppendInteger((long)((int)(11 * INCH * drawscale) - maxy));    AppendOp(OP_translate);    AppendInteger(5L);    AppendOp(OP_scale);    AppendOp(OP_concat);    AppendOp(OP_concatt);      switch (IPDeviceType) {	case Xerox8044_Services8:	case Xerox8044_Services9:	case Xerox8044_Services10:	    {	    unsigned char *bitmapP;	    int	numberOfScanLines,		pixelsPerScanLine,		scanLinesPerStripe,		bytesPerStripe,		numberOfFullStripes,		scanLinesRemaining,		n;		    numberOfScanLines = maxx - minx;	    pixelsPerScanLine = bytesPerScanLine << 3;	    scanLinesPerStripe = (64*1024 - 4 - 16)/bytesPerScanLine;	    bytesPerStripe = scanLinesPerStripe * bytesPerScanLine;	    numberOfFullStripes = numberOfScanLines / scanLinesPerStripe;	    scanLinesRemaining = numberOfScanLines % scanLinesPerStripe;		    for (n = 0, bitmapP = bitmap; n < numberOfFullStripes; n++, bitmapP += bytesPerStripe) {	    	WritePixelArray(bitmapP, scanLinesPerStripe, pixelsPerScanLine);		/*		 * position the next stripe.  I tried going a setXRel followed		 * by a trans but this cause strange things to happen on		 * an 8044 running services 9.0		 */		AppendInteger((long)scanLinesPerStripe);		AppendInteger(0L);		AppendOp(OP_translate);		AppendOp(OP_concatt);	    }    	    if (scanLinesRemaining != 0)		WritePixelArray(bitmapP, scanLinesRemaining, pixelsPerScanLine);    	    }	    break;	case Xerox9700_V10:	default:	    WritePixelArray(bitmap, maxx - minx, bytesPerScanLine << 3);    }    AppendOp(OP_endBody);    /* no longer active, now is it? */    bm_active = No;}staticWritePixelArray(pixelArray, xPixels, yPixels)unsigned char *pixelArray;int xPixels, yPixels;{    int bytesPerScanLine,	pixelArraySize;		/* in bytes */    bytesPerScanLine = (yPixels + 7)/8;    pixelArraySize = xPixels * bytesPerScanLine;    /* build the pixel array */    AppendInteger((long) xPixels);	/* xPixels */    AppendInteger((long) yPixels);	/* yPixels */    AppendInteger(1L);			/* samplesPerPixel */    AppendInteger(1L);			/* maxSampleValue */    AppendInteger(1L);			/* samplesInterleaved */    Translate(0.0, 0.0);		/* (null) transform */    AppendPPVector(pixelArraySize, 1, yPixels, pixelArray);    /* make the pixel array */    AppendOp(OP_makepixelarray);    /* mask it */    AppendOp(OP_maskpixel);}/*----------------------------------------------------------------------------- *	Gremlin additions:  This should be in a separate file. *---------------------------------------------------------------------------*//*----------------------------------------------------------------------------- *	drawPolygon(buffer, WantBorder) *---------------------------------------------------------------------------*/#include <ctype.h>#include <vfont.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include <errno.h>static StippleDesFD = -1;static StippleChoice = -1;static struct {	int fileDes;	int member;	int maxSize;	struct {		char prelude[4];		short bits[16];	} ppv;		/* In Services <= 10  max sampled black is 					at most 16 x 16 */	struct header header;	struct dispatch dispatch;} curStipple;iPdrawPolygon(s, cmd)char *s;char cmd;{	int x[maxPointsInPolygon],y[maxPointsInPolygon]; 	int stippleMember, strokeWidth = 254;	extern int hor_pos, ver_pos, lineThickness;	int xi,yi,i,j,numPoints;	float temp1,temp2,temp3,t,dis;	float euclidDist();	char more;	/* skip all leading white space */	while(white(*s)) s++;			if(!isdigit(*s)) return; 	if(readNumber(&s, &stippleMember) == NULL)		return;	/* read in the x y pairs of points for the polygon */	for(numPoints = 0; numPoints < maxPointsInPolygon;) {		x[numPoints] = hor_pos;		more = readNumber(&s, &xi);		y[numPoints] = (11 * INCH) - ver_pos;		more *= readNumber(&s, &yi);		hor_pos += xi;		ver_pos += yi;		numPoints++;		if (more == 0) break;	}	getStippleMember(stippleMember);	/* Doit */	if (numPoints < 2)		return;	Op(dosavesimplebody);	Op(beginBody);	/* First, draw outline, if desired */	if (cmd == drawPolygon) {		AppendRational((long) strokeWidth, 10);		AppendInteger((long) I_strokeWidth);		Op(iset);		Moveto((double)x[0], (double)y[0]);		for(j = 1; j < numPoints; j++)			Lineto((double)x[j], (double)y[j]);		Lineto((double)x[0], (double)y[0]);		Op(maskstroke);	}	/* Make Sampled Color */	AppendInteger(16L);			/* xPixels */	AppendInteger(16L);			/* yPixels */	AppendInteger(1L);			/* samplesPerPixel */	AppendInteger(1L);			/* maxSampleValue */	AppendInteger(1L);			/* samplesInterleaved */	/*AppendRational((long) 2*strokeWidth, 10); fails in serv < 11 */	AppendRational((long) strokeWidth, 30); /* 1 bit per 300th inch */	Op(scale);				/* transform for color */			    /* spew out the packed pixel vector */	append_Sequence(sequencePackedPixelVector, 32 + 4,					(char *) &curStipple.ppv);	Op(makepixelarray); /* make the pixel array */	AppendInteger(4L);	Op(iget);	    /* current transformation */	AppendInteger(1L);	Op(makesampledblack);	AppendInteger(13L);	Op(iset);	    /* Set Color */	/* Print Polygon */	Moveto((double)x[0], (double)y[0]);	for(j = 1; j < numPoints; j++)		Lineto((double)x[j], (double)y[j]);	Lineto((double)x[0], (double)y[0]);	AppendInteger(1L);	Op(makeoutline);	Op(maskfill);	AppendInteger(1L); Op(setgray); /* Restore normal black */	Op(endBody);}newStippleFamily(new){	char stippleFilename[80];	if (new == stippleFamily)		return;	if (curStipple.fileDes > 0)		close(curStipple.fileDes);	stippleFamily = new;	(void) sprintf(stippleFilename, "/usr/lib/vfont/%s.0",				stipTypeName[new]);	if ((curStipple.fileDes = open(stippleFilename, O_RDONLY, 0)) < 0) {		(void) sprintf(stippleFilename, "%s/dev%s/%s.0",				fontdirectory, devicename, stipTypeName[new]);		if ((curStipple.fileDes				= open(stippleFilename, O_RDONLY, 0)) < 0) {			reportError(QUIT,			  "can't open file %s for device characteristics (%s)",			    stippleFilename, sys_errlist[errno]);		}	}	read(curStipple.fileDes, (char *)&(curStipple.header),					    sizeof (curStipple.header));	curStipple.member = -1;	getStippleMember(0);			    /* build the packed pixel vector */	curStipple.ppv.prelude[0] = 0;	curStipple.ppv.prelude[1] = 1;	curStipple.ppv.prelude[2] = (char)(0);		/* high order byte */ 	curStipple.ppv.prelude[3] = (char) (16);	/* low  order byte */}int showStip = 0;getStippleMember(member){	register struct dispatch *dp = & curStipple.dispatch;	register int i;	long offset;	short bits[32];	if (curStipple.member == member)		return;	offset = sizeof(struct header) + (member*sizeof(*dp));	lseek(curStipple.fileDes, offset, 0);	read(curStipple.fileDes, (char *)dp, sizeof (*dp));	if (dp->nbytes == 0) {		if (member == 0)  return;		reportError(CONTINUE,			"Stipple Family %s doesn't have member %d",			stipTypeName[stippleFamily], member);		curStipple.member = 0;		return;	}	if ((dp->up + dp->down) != 32 || ((dp->left + dp->right) != 32)) {		if (member == 0)  return;		reportError(CONTINUE,			"Stipple Family %s member %d is not 32x32\n",			stipTypeName[stippleFamily], member);		curStipple.member = 0;		return;	}	offset = sizeof(struct header) + (256*sizeof(*dp)) + dp->addr;	lseek(curStipple.fileDes, offset, 0);	read(curStipple.fileDes, (char *)bits, sizeof (bits));	if (showStip)		    fprintf(stderr, "Stipple Family %s, member %d\n",					stipTypeName[stippleFamily], member);	for (i = 0; i < 16; i++) {		curStipple.ppv.bits[i] = bits[i+i];		if (showStip) {			register int j;			register int mask = bits[i+i];			for (j = 0; j < 16; j++) {				if (mask & 1)					putc('*', stderr);				else					putc(' ', stderr);				mask >>= 1;			}			putc('\n', stderr);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -