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