xref: /plan9-contrib/sys/src/cmd/postscript/p9bitpost/p9bitpost.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1*219b2ee8SDavid du Colombier #include <u.h>
2*219b2ee8SDavid du Colombier #include <libc.h>
3*219b2ee8SDavid du Colombier #include <libg.h>
4*219b2ee8SDavid du Colombier #include <stdio.h>
5*219b2ee8SDavid du Colombier #include "comments.h"
6*219b2ee8SDavid du Colombier #include "gen.h"
7*219b2ee8SDavid du Colombier #include "path.h"
8*219b2ee8SDavid du Colombier 
9*219b2ee8SDavid du Colombier int debug = 0;
10*219b2ee8SDavid du Colombier 
11*219b2ee8SDavid du Colombier /* predefine
12*219b2ee8SDavid du Colombier int cat(char *);
13*219b2ee8SDavid du Colombier void error(int, char *, ...);
14*219b2ee8SDavid du Colombier  */
15*219b2ee8SDavid du Colombier 
16*219b2ee8SDavid du Colombier #define HDLEN	60
17*219b2ee8SDavid du Colombier char header[HDLEN];
18*219b2ee8SDavid du Colombier char *screenbits;
19*219b2ee8SDavid du Colombier char hex[] = { 'f', 'e', 'd', 'c', 'b', 'a', '9', '8',
20*219b2ee8SDavid du Colombier 		'7', '6', '5', '4', '3', '2', '1', '0' };	/* black on gnot is not
21*219b2ee8SDavid du Colombier 								 * black on printer.
22*219b2ee8SDavid du Colombier 								 */
23*219b2ee8SDavid du Colombier #define LETTERWIDTH	8.5
24*219b2ee8SDavid du Colombier #define	LETTERHEIGHT	11.0
25*219b2ee8SDavid du Colombier int landscape = 0;
26*219b2ee8SDavid du Colombier 
27*219b2ee8SDavid du Colombier #define XOFF	(int)((landscape)?((LETTERWIDTH/2 + (float)height * yscale / (2 * 100.)) * 72.):((LETTERWIDTH/2 - (float)width * pixperbyte * xscale / (2 * 100.)) * 72.))
28*219b2ee8SDavid du Colombier #define YOFF	(int)((landscape)?((LETTERHEIGHT/2 - (float)width * pixperbyte * xscale / (2 * 100.)) * 72.):((LETTERHEIGHT/2 - (float)height * yscale / (2 * 100.)) * 72.))
29*219b2ee8SDavid du Colombier 
30*219b2ee8SDavid du Colombier char *prologue = POSTDMD;
31*219b2ee8SDavid du Colombier 
32*219b2ee8SDavid du Colombier void
33*219b2ee8SDavid du Colombier preamble(void) {
34*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s", CONFORMING);
35*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s %s\n", VERSION, PROGRAMVERSION);
36*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s %s\n", DOCUMENTFONTS, ATEND);
37*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s %s\n", PAGES, ATEND);
38*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s", ENDCOMMENTS);
39*219b2ee8SDavid du Colombier 
40*219b2ee8SDavid du Colombier /*	if (cat(prologue) == FALSE) {
41*219b2ee8SDavid du Colombier 		fprintf(2, "can't read %s", prologue);
42*219b2ee8SDavid du Colombier 		exits("copying prologue");
43*219b2ee8SDavid du Colombier 	}
44*219b2ee8SDavid du Colombier  */
45*219b2ee8SDavid du Colombier 
46*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s", ENDPROLOG);
47*219b2ee8SDavid du Colombier 	fprintf(stdout, "%s", BEGINSETUP);
48*219b2ee8SDavid du Colombier 	fprintf(stdout, "mark\n");
49*219b2ee8SDavid du Colombier }
50*219b2ee8SDavid du Colombier 
51*219b2ee8SDavid du Colombier void
52*219b2ee8SDavid du Colombier main(int argc, char *argv[])
53*219b2ee8SDavid du Colombier {
54*219b2ee8SDavid du Colombier 	FILE *screenfd = stdin;
55*219b2ee8SDavid du Colombier 	int i, j, bcnt;
56*219b2ee8SDavid du Colombier 	int width, height, ldepth, bitsperpix, pixperbyte;
57*219b2ee8SDavid du Colombier 	float xscale = 1.0, yscale = 1.0;
58*219b2ee8SDavid du Colombier 	Rectangle r;
59*219b2ee8SDavid du Colombier 	int ;
60*219b2ee8SDavid du Colombier 	char *bp, *optstr, *patch = 0;
61*219b2ee8SDavid du Colombier 
62*219b2ee8SDavid du Colombier 	for (i=1; i<argc; i++) {
63*219b2ee8SDavid du Colombier 		if (*argv[i] == '-') {
64*219b2ee8SDavid du Colombier 			switch(argv[i][1]) {
65*219b2ee8SDavid du Colombier 			case 'L':
66*219b2ee8SDavid du Colombier 				landscape = 1;
67*219b2ee8SDavid du Colombier 				break;
68*219b2ee8SDavid du Colombier 			case 'P':
69*219b2ee8SDavid du Colombier 				if (argv[i][2] == '\0')
70*219b2ee8SDavid du Colombier 					patch = argv[++i];
71*219b2ee8SDavid du Colombier 				else
72*219b2ee8SDavid du Colombier 					patch = &(argv[i][2]);
73*219b2ee8SDavid du Colombier 				break;
74*219b2ee8SDavid du Colombier 			case 'd':
75*219b2ee8SDavid du Colombier 				debug = 1;
76*219b2ee8SDavid du Colombier 				break;
77*219b2ee8SDavid du Colombier 			case 'm':
78*219b2ee8SDavid du Colombier 				if (argv[i][2] == '\0')
79*219b2ee8SDavid du Colombier 					optstr = argv[++i];
80*219b2ee8SDavid du Colombier 				else
81*219b2ee8SDavid du Colombier 					optstr = &(argv[i][2]);
82*219b2ee8SDavid du Colombier 				if ((optstr=strtok(optstr, " ,")) != 0)
83*219b2ee8SDavid du Colombier 					xscale = yscale = atof(optstr);
84*219b2ee8SDavid du Colombier 				 if ((optstr=strtok(0, " ,")) != 0)
85*219b2ee8SDavid du Colombier 					yscale = atof(optstr);
86*219b2ee8SDavid du Colombier 				break;
87*219b2ee8SDavid du Colombier 			default:
88*219b2ee8SDavid du Colombier 				fprintf(stderr, "usage: %s [-m mag] [file]\n");
89*219b2ee8SDavid du Colombier 				exits("incorrect usage");
90*219b2ee8SDavid du Colombier 			}
91*219b2ee8SDavid du Colombier 		} else if (argv[i][0] != '\0')
92*219b2ee8SDavid du Colombier 			screenfd = fopen(argv[i], "r");
93*219b2ee8SDavid du Colombier 	}
94*219b2ee8SDavid du Colombier 	if (screenfd == NULL) {
95*219b2ee8SDavid du Colombier 		fprintf(stderr, "cannot open /dev/screen.\n");
96*219b2ee8SDavid du Colombier 		fprintf(stderr, "try: bind -a /mnt/term/dev /dev\n");
97*219b2ee8SDavid du Colombier 		exits("open failed");
98*219b2ee8SDavid du Colombier 	}
99*219b2ee8SDavid du Colombier 	if (fread(header, 1, HDLEN, screenfd)!=HDLEN) {
100*219b2ee8SDavid du Colombier 		fprintf(stderr, "cannot read bitmap header.\n");
101*219b2ee8SDavid du Colombier 		exits("read failed");
102*219b2ee8SDavid du Colombier 	}
103*219b2ee8SDavid du Colombier 	if (sscanf(header, " %d %d %d %d %d ", &ldepth, &r.min.x, &r.min.y, &r.max.x, &r.max.y)!=5) {
104*219b2ee8SDavid du Colombier 		fprintf(stderr, "bad header format.\n");
105*219b2ee8SDavid du Colombier 		exits("bad format");
106*219b2ee8SDavid du Colombier 	}
107*219b2ee8SDavid du Colombier 	bitsperpix  = 1<<ldepth;
108*219b2ee8SDavid du Colombier 	pixperbyte = 8 / bitsperpix;
109*219b2ee8SDavid du Colombier 	width = ((r.max.x - r.min.x + (r.min.x % pixperbyte)) * (1<<ldepth) + 7) / 8;
110*219b2ee8SDavid du Colombier 	height = r.max.y - r.min.y;
111*219b2ee8SDavid du Colombier 	bcnt = height * width;
112*219b2ee8SDavid du Colombier 	if (debug) fprintf(stderr, "width=%d height=%d bcnt=%d\n", width, height, bcnt);
113*219b2ee8SDavid du Colombier 	screenbits = malloc(bcnt);
114*219b2ee8SDavid du Colombier 	if (screenbits == 0) {
115*219b2ee8SDavid du Colombier 		fprintf(stderr, "cannot allocate bitmap.\n");
116*219b2ee8SDavid du Colombier 		exits("malloc failed");
117*219b2ee8SDavid du Colombier 	}
118*219b2ee8SDavid du Colombier 	if ((i=fread(screenbits, 1, bcnt, screenfd)) != bcnt) {
119*219b2ee8SDavid du Colombier 		fprintf(stderr, "read failed: read %d bytes out of %d.\n", i, bcnt);
120*219b2ee8SDavid du Colombier 		exits("read failed");
121*219b2ee8SDavid du Colombier 	}
122*219b2ee8SDavid du Colombier 	preamble();
123*219b2ee8SDavid du Colombier 	if (patch) fprintf(stdout, "%s\n", patch);
124*219b2ee8SDavid du Colombier 	fprintf(stdout, "/picstr %d string def\n", width);
125*219b2ee8SDavid du Colombier 	fprintf(stdout, "%d %d translate\n", XOFF, YOFF);
126*219b2ee8SDavid du Colombier 	if (landscape) fprintf(stdout, "90 rotate\n");
127*219b2ee8SDavid du Colombier 	fprintf(stdout, "%6.2f %6.2f scale\n\n", (float)width * pixperbyte * .72 * xscale,
128*219b2ee8SDavid du Colombier 						(float)height * .72 * yscale);
129*219b2ee8SDavid du Colombier 	fprintf(stdout, "%d %d %d [%d 0 0 %d 0 %d]\n", width*pixperbyte, height,
130*219b2ee8SDavid du Colombier 		1<<ldepth, width*pixperbyte, -height, height);
131*219b2ee8SDavid du Colombier 	fprintf(stdout, "{currentfile picstr readhexstring pop} image\n\n");
132*219b2ee8SDavid du Colombier 	bp = screenbits;
133*219b2ee8SDavid du Colombier 	for (i=0; i<height; i++) {
134*219b2ee8SDavid du Colombier 		for(j=0;j<width;j++) {
135*219b2ee8SDavid du Colombier 			/* (8 - (2        )) - ((2        ) * (128       % 4         )) */
136*219b2ee8SDavid du Colombier 			/* (8 - bitsperpix - (bitsperpix * (r.min.x+j % pixperbyte)) */
137*219b2ee8SDavid du Colombier 			fprintf(stdout, "%c%c", hex[(*bp&0xf0)>>4], hex[(*bp++&0xf)]);
138*219b2ee8SDavid du Colombier 			if (j%32 == 31) fprintf(stdout, "\n");
139*219b2ee8SDavid du Colombier 		}
140*219b2ee8SDavid du Colombier 		fprintf(stdout, "\n");
141*219b2ee8SDavid du Colombier 	}
142*219b2ee8SDavid du Colombier 	fprintf(stdout, "showpage\n");
143*219b2ee8SDavid du Colombier 	fprintf(stdout, "%%%%BoundingBox: %d %d %6.2f %6.2f\n", XOFF, YOFF,
144*219b2ee8SDavid du Colombier 			(float)width * pixperbyte * .72 * xscale + XOFF,
145*219b2ee8SDavid du Colombier 			(float)height * .72 * yscale + YOFF);
146*219b2ee8SDavid du Colombier 	exits("");
147*219b2ee8SDavid du Colombier }
148