2 output language from troff:
3 all numbers are character strings
6 fn font as number from 1-n
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)
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
28 x ...\n device control functions:
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
36 x f n s font position n contains font s
37 x H n set character height to n
40 Subcommands like "i" are often spelled out like "init".
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
53 #define putchar(x) Bprint(&bout, "%C", x)
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";
59 char *pschar(char *, char *hex, int *wid, int *ht);
61 void Bgetstr(Biobuf *bp, char *s);
62 void Bgetline(Biobuf *bp, char *s);
63 void Bgetint(Biobuf *bp, int *n);
71 char str[100], *args[10];
74 if(initdraw(0, fontfile, 0) < 0){
75 fprint(2, "mnihongo: can't initialize display: %r\n");
78 Binit(&bin, 0, OREAD);
79 Binit(&bout, 1, OWRITE);
83 while ((c = Bgetc(&bin)) >= 0) {
85 case '\n': /* when input is text */
87 case '\0': /* occasional noise creeps in */
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 */
96 putchar(c); /* digit 2 */
99 putchar(Bgetc(&bin)); /* char itself */
101 case 'c': /* single character */
103 if(c==' ') /* why does this happen? it's troff - bwk */
105 else if(jfont == curfont){
116 Bprint(&bout, "C%s", str);
121 if(curfont < 0 || curfont > 20)
122 curfont = 1; /* sanity */
123 Bprint(&bout, "%c%s", c, str);
125 case 'N': /* absolute character number */
127 case 'p': /* new page */
129 Bprint(&bout, "%c%d", c, n);
131 case 'H': /* absolute horizontal motion */
133 Bprint(&bout, "%c%d", c, n);
136 case 'h': /* relative horizontal motion */
138 Bprint(&bout, "%c%d", c, n);
143 Bprint(&bout, "%c%d", c, n);
148 Bprint(&bout, "%c%d", c, n);
152 case 'w': /* word space */
156 case 'x': /* device control */
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)
167 case 'D': /* draw function */
168 case 'n': /* end of line */
169 case '#': /* comment */
171 Bprint(&bout, "%c%s", c, str);
174 fprint(2, "mnihongo: unknown input character %o %c\n", c, c);
180 int kanji(char *s) /* very special pleading */
181 { /* dump as kanji char if looks like one */
184 int size = 10, ht, wid;
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");
197 char *pschar(char *s, char *hex, int *wid, int *ht)
205 chpt = stringsize(font, s); /* bounding box of char */
206 *wid = ((chpt.x+7) / 8) * 8;
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);
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]);
227 void Bgetstr(Biobuf *bp, char *s) /* get a string */
231 while ((c = Bgetc(bp)) >= 0) {
232 if (c == ' ' || c == '\t' || c == '\n') {
241 void Bgetline(Biobuf *bp, char *s) /* get a line, including newline */
245 while ((c = Bgetc(bp)) >= 0) {
253 void Bgetint(Biobuf *bp, int *n) /* get an integer */