Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
output language from troff:
3
all numbers are character strings
4
 
5
sn	size in points
6
fn	font as number from 1-n
7
cx	ascii character x
8
Cxyz	funny char xyz. terminated by white space
9
Nn	absolute character number n on this font.  ditto
10
Hn	go to absolute horizontal position n
11
Vn	go to absolute vertical position n (down is positive)
12
hn	go n units horizontally (relative)
13
vn	ditto vertically
14
nnc	move right nn, then print c (exactly 2 digits!)
15
		(this wart is an optimization that shrinks output file size
16
		 about 35% and run-time about 15% while preserving ascii-ness)
17
Dt ...\n	draw operation 't':
18
	Dl x y		line from here by x,y
19
	Dc d		circle of diameter d with left side here
20
	De x y		ellipse of axes x,y with left side here
21
	Da dx dy dx dy	arc counter-clockwise, center at dx,dx, end at dx,dy
22
	D~ x y x y ...	wiggly line by x,y then x,y ...
23
nb a	end of line (information only -- no action needed)
24
w	paddable word space -- no action needed
25
	b = space before line, a = after
26
p	new page begins -- set v to 0
27
#...\n	comment
28
x ...\n	device control functions:
29
	x i	init
30
	x T s	name of device is s
31
	x r n h v	resolution is n/inch
32
		h = min horizontal motion, v = min vert
33
	x p	pause (can restart)
34
	x s	stop -- done for ever
35
	x t	generate trailer
36
	x f n s	font position n contains font s
37
	x H n	set character height to n
38
	x S n	set slant to N
39
 
40
	Subcommands like "i" are often spelled out like "init".
41
*/
42
 
43
#include <u.h>
44
#include <libc.h>
45
#include <draw.h>
46
#include <bio.h>
47
 
48
#define hmot(n)	hpos += n
49
#define hgoto(n)	hpos = n
50
#define vmot(n)	vgoto(vpos + n)
51
#define vgoto(n)	vpos = n
52
 
53
#define	putchar(x)	Bprint(&bout, "%C", x)
54
 
55
int	hpos;	/* horizontal position where we are supposed to be next (left = 0) */
56
int	vpos;	/* current vertical position (down positive) */
57
char	*fontfile	= "/lib/font/bit/pelm/unicode.9x24.font";
58
 
59
char	*pschar(char *, char *hex, int *wid, int *ht);
60
int	kanji(char *);
61
void	Bgetstr(Biobuf *bp, char *s);
62
void	Bgetline(Biobuf *bp, char *s);
63
void	Bgetint(Biobuf *bp, int *n);
64
 
65
Biobuf bin, bout;
66
 
67
void
68
main(void)
69
{
70
	int c, n;
71
	char str[100], *args[10];
72
	int jfont, curfont;
73
 
74
	if(initdraw(0, fontfile, 0) < 0){
75
		fprint(2, "mnihongo: can't initialize display: %r\n");
76
		exits("open");
77
	}
78
	Binit(&bin, 0, OREAD);
79
	Binit(&bout, 1, OWRITE);
80
 
81
	jfont = -1;
82
	curfont = 1;
83
	while ((c = Bgetc(&bin)) >= 0) {
84
		switch (c) {
85
		case '\n':	/* when input is text */
86
		case ' ':
87
		case '\0':		/* occasional noise creeps in */
88
			putchar(c);
89
			break;
90
		case '0': case '1': case '2': case '3': case '4':
91
		case '5': case '6': case '7': case '8': case '9':
92
			/* two motion digits plus a character */
93
			putchar(c);	/* digit 1 */
94
			n = (c-'0')*10;
95
			c = Bgetc(&bin);
96
			putchar(c);	/* digit 2 */
97
			n += c - '0';
98
			hmot(n);
99
			putchar(Bgetc(&bin));	/* char itself */
100
			break;
101
		case 'c':	/* single character */
102
			c = Bgetrune(&bin);
103
			if(c==' ')	/* why does this happen? it's troff - bwk */
104
				break;
105
			else if(jfont == curfont){
106
				Bungetrune(&bin);
107
				Bgetstr(&bin, str);
108
				kanji(str);
109
			}else{
110
				putchar('c');
111
				putchar(c);
112
			}
113
			break;
114
		case 'C':
115
			Bgetstr(&bin, str);
116
			Bprint(&bout, "C%s", str);
117
			break;
118
		case 'f':
119
			Bgetstr(&bin, str);
120
			curfont = atoi(str);
121
			if(curfont < 0 || curfont > 20)
122
				curfont = 1;	/* sanity */
123
			Bprint(&bout, "%c%s", c, str);
124
			break;
125
		case 'N':	/* absolute character number */
126
		case 's':
127
		case 'p':	/* new page */
128
			Bgetint(&bin, &n);
129
			Bprint(&bout, "%c%d", c, n);
130
			break;
131
		case 'H':	/* absolute horizontal motion */
132
			Bgetint(&bin, &n);
133
			Bprint(&bout, "%c%d", c, n);
134
			hgoto(n);
135
			break;
136
		case 'h':	/* relative horizontal motion */
137
			Bgetint(&bin, &n);
138
			Bprint(&bout, "%c%d", c, n);
139
			hmot(n);
140
			break;
141
		case 'V':
142
			Bgetint(&bin, &n);
143
			Bprint(&bout, "%c%d", c, n);
144
			vgoto(n);
145
			break;
146
		case 'v':
147
			Bgetint(&bin, &n);
148
			Bprint(&bout, "%c%d", c, n);
149
			vmot(n);
150
			break;
151
 
152
		case 'w':	/* word space */
153
			putchar(c);
154
			break;
155
 
156
		case 'x':	/* device control */
157
			Bgetline(&bin, str);
158
			Bprint(&bout, "%c%s", c, str);
159
			if(tokenize(str, args, 10)>2 && args[0][0]=='f' && ('0'<=args[1][0] && args[1][0]<='9')){
160
				if(strncmp(args[2], "Jp", 2) == 0)
161
					jfont = atoi(args[1]);
162
				else if(atoi(args[1]) == jfont)
163
					jfont = -1;
164
			}
165
			break;
166
 
167
		case 'D':	/* draw function */
168
		case 'n':	/* end of line */
169
		case '#':	/* comment */
170
			Bgetline(&bin, str);
171
			Bprint(&bout, "%c%s", c, str);
172
			break;
173
		default:
174
			fprint(2, "mnihongo: unknown input character %o %c\n", c, c);
175
			exits("error");
176
		}
177
	}
178
}
179
 
180
int kanji(char *s)	/* very special pleading */
181
{			/* dump as kanji char if looks like one */
182
	Rune r;
183
	char hex[500];
184
	int size = 10, ht, wid;
185
 
186
	chartorune(&r, s);
187
	pschar(s, hex, &wid, &ht);
188
	Bprint(&bout, "x X PS save %d %d m\n", hpos, vpos);
189
	Bprint(&bout, "x X PS currentpoint translate %d %d scale ptsize dup scale\n", size, size);
190
	Bprint(&bout, "x X PS %d %d true [%d 0 0 -%d 0 %d]\n",
191
		wid, ht, wid, wid, ht-2);	/* kludge; ought to use ->ascent */
192
	Bprint(&bout, "x X PS {<%s>}\n", hex);
193
	Bprint(&bout, "x X PS imagemask restore\n");
194
	return 1;
195
}
196
 
197
char *pschar(char *s, char *hex, int *wid, int *ht)
198
{
199
	Point chpt, spt;
200
	Image *b;
201
	uchar rowdata[100];
202
	char *hp = hex;
203
	int y, i;
204
 
205
	chpt = stringsize(font, s);		/* bounding box of char */
206
	*wid = ((chpt.x+7) / 8) * 8;
207
	*ht = chpt.y;
208
	/* postscript is backwards to video, so draw white (ones) on black (zeros) */
209
	b = allocimage(display, Rpt(ZP, chpt), GREY1, 0, DBlack);	/* place to put it */
210
	spt = string(b, Pt(0,0), display->white, ZP, font, s);	/* put it there */
211
/* Bprint(&bout, "chpt %P, spt %P, wid,ht %d,%d\n", chpt, spt, *wid, *ht);
212
/* Bflush(&bout); */
213
	for (y = 0; y < chpt.y; y++) {	/* read bits a row at a time */
214
		memset(rowdata, 0, sizeof rowdata);
215
		unloadimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata);
216
		for (i = 0; i < spt.x; i += 8) {	/* 8 == byte */
217
			sprint(hp, "%2.2x", rowdata[i/8]);
218
			hp += 2;
219
		}
220
	}
221
	*hp = 0;
222
	freeimage(b);
223
	return hex;
224
}
225
 
226
 
227
void	Bgetstr(Biobuf *bp, char *s)	/* get a string */
228
{
229
	int c;
230
 
231
	while ((c = Bgetc(bp)) >= 0) {
232
		if (c == ' ' || c == '\t' || c == '\n') {
233
			Bungetc(bp);
234
			break;
235
		}
236
		*s++ = c;
237
	}
238
	*s = 0;
239
}
240
 
241
void	Bgetline(Biobuf *bp, char *s)	/* get a line, including newline */
242
{
243
	int c;
244
 
245
	while ((c = Bgetc(bp)) >= 0) {
246
		*s++ = c;
247
		if (c == '\n')
248
			break;
249
	}
250
	*s = 0;
251
}
252
 
253
void	Bgetint(Biobuf *bp, int *n)	/* get an integer */
254
{
255
	double d;
256
 
257
	Bgetd(bp, &d);
258
	*n = d;
259
}