📄 mnihongo.c
字号:
/*output language from troff:all numbers are character stringssn size in pointsfn font as number from 1-ncx ascii character xCxyz funny char xyz. terminated by white spaceNn absolute character number n on this font. dittoHn go to absolute horizontal position nVn go to absolute vertical position n (down is positive)hn go n units horizontally (relative)vn ditto verticallynnc move right nn, then print c (exactly 2 digits!) (this wart is an optimization that shrinks output file size about 35% and run-time about 15% while preserving ascii-ness)Dt ...\n draw operation 't': Dl x y line from here by x,y Dc d circle of diameter d with left side here De x y ellipse of axes x,y with left side here Da dx dy dx dy arc counter-clockwise, center at dx,dx, end at dx,dy D~ x y x y ... wiggly line by x,y then x,y ...nb a end of line (information only -- no action needed)w paddable word space -- no action needed b = space before line, a = afterp new page begins -- set v to 0#...\n commentx ...\n device control functions: x i init x T s name of device is s x r n h v resolution is n/inch h = min horizontal motion, v = min vert x p pause (can restart) x s stop -- done for ever x t generate trailer x f n s font position n contains font s x H n set character height to n x S n set slant to N Subcommands like "i" are often spelled out like "init".*/#include <u.h>#include <libc.h>#include <draw.h>#include <bio.h>#define hmot(n) hpos += n#define hgoto(n) hpos = n#define vmot(n) vgoto(vpos + n)#define vgoto(n) vpos = n#define putchar(x) Bprint(&bout, "%C", x)int hpos; /* horizontal position where we are supposed to be next (left = 0) */int vpos; /* current vertical position (down positive) */char *fontfile = "/lib/font/bit/pelm/unicode.9x24.font";char *pschar(char *, char *hex, int *wid, int *ht);int kanji(char *);void Bgetstr(Biobuf *bp, char *s);void Bgetline(Biobuf *bp, char *s);void Bgetint(Biobuf *bp, int *n);Biobuf bin, bout;voidmain(void){ int c, n; char str[100], *args[10]; int jfont, curfont; if(initdraw(0, fontfile, 0) < 0){ fprint(2, "mnihongo: can't initialize display: %r\n"); exits("open"); } Binit(&bin, 0, OREAD); Binit(&bout, 1, OWRITE); jfont = -1; curfont = 1; while ((c = Bgetc(&bin)) >= 0) { switch (c) { case '\n': /* when input is text */ case ' ': case '\0': /* occasional noise creeps in */ putchar(c); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* two motion digits plus a character */ putchar(c); /* digit 1 */ n = (c-'0')*10; c = Bgetc(&bin); putchar(c); /* digit 2 */ n += c - '0'; hmot(n); putchar(Bgetc(&bin)); /* char itself */ break; case 'c': /* single character */ c = Bgetrune(&bin); if(c==' ') /* why does this happen? it's troff - bwk */ break; else if(jfont == curfont){ Bungetrune(&bin); Bgetstr(&bin, str); kanji(str); }else{ putchar('c'); putchar(c); } break; case 'C': Bgetstr(&bin, str); Bprint(&bout, "C%s", str); break; case 'f': Bgetstr(&bin, str); curfont = atoi(str); if(curfont < 0 || curfont > 20) curfont = 1; /* sanity */ Bprint(&bout, "%c%s", c, str); break; case 'N': /* absolute character number */ case 's': case 'p': /* new page */ Bgetint(&bin, &n); Bprint(&bout, "%c%d", c, n); break; case 'H': /* absolute horizontal motion */ Bgetint(&bin, &n); Bprint(&bout, "%c%d", c, n); hgoto(n); break; case 'h': /* relative horizontal motion */ Bgetint(&bin, &n); Bprint(&bout, "%c%d", c, n); hmot(n); break; case 'V': Bgetint(&bin, &n); Bprint(&bout, "%c%d", c, n); vgoto(n); break; case 'v': Bgetint(&bin, &n); Bprint(&bout, "%c%d", c, n); vmot(n); break; case 'w': /* word space */ putchar(c); break; case 'x': /* device control */ Bgetline(&bin, str); Bprint(&bout, "%c%s", c, str); if(tokenize(str, args, 10)>2 && args[0][0]=='f' && ('0'<=args[1][0] && args[1][0]<='9')){ if(strncmp(args[2], "Jp", 2) == 0) jfont = atoi(args[1]); else if(atoi(args[1]) == jfont) jfont = -1; } break; case 'D': /* draw function */ case 'n': /* end of line */ case '#': /* comment */ Bgetline(&bin, str); Bprint(&bout, "%c%s", c, str); break; default: fprint(2, "mnihongo: unknown input character %o %c\n", c, c); exits("error"); } }}int kanji(char *s) /* very special pleading */{ /* dump as kanji char if looks like one */ Rune r; char hex[500]; int size = 10, ht, wid; chartorune(&r, s); pschar(s, hex, &wid, &ht); Bprint(&bout, "x X PS save %d %d m\n", hpos, vpos); Bprint(&bout, "x X PS currentpoint translate %d %d scale ptsize dup scale\n", size, size); Bprint(&bout, "x X PS %d %d true [%d 0 0 -%d 0 %d]\n", wid, ht, wid, wid, ht-2); /* kludge; ought to use ->ascent */ Bprint(&bout, "x X PS {<%s>}\n", hex); Bprint(&bout, "x X PS imagemask restore\n"); return 1;}char *pschar(char *s, char *hex, int *wid, int *ht){ Point chpt, spt; Image *b; uchar rowdata[100]; char *hp = hex; int y, i; chpt = stringsize(font, s); /* bounding box of char */ *wid = ((chpt.x+7) / 8) * 8; *ht = chpt.y; /* postscript is backwards to video, so draw white (ones) on black (zeros) */ b = allocimage(display, Rpt(ZP, chpt), GREY1, 0, DBlack); /* place to put it */ spt = string(b, Pt(0,0), display->white, ZP, font, s); /* put it there *//* Bprint(&bout, "chpt %P, spt %P, wid,ht %d,%d\n", chpt, spt, *wid, *ht);/* Bflush(&bout); */ for (y = 0; y < chpt.y; y++) { /* read bits a row at a time */ memset(rowdata, 0, sizeof rowdata); unloadimage(b, Rect(0, y, chpt.x, y+1), rowdata, sizeof rowdata); for (i = 0; i < spt.x; i += 8) { /* 8 == byte */ sprint(hp, "%2.2x", rowdata[i/8]); hp += 2; } } *hp = 0; freeimage(b); return hex;}void Bgetstr(Biobuf *bp, char *s) /* get a string */{ int c; while ((c = Bgetc(bp)) >= 0) { if (c == ' ' || c == '\t' || c == '\n') { Bungetc(bp); break; } *s++ = c; } *s = 0;}void Bgetline(Biobuf *bp, char *s) /* get a line, including newline */{ int c; while ((c = Bgetc(bp)) >= 0) { *s++ = c; if (c == '\n') break; } *s = 0;}void Bgetint(Biobuf *bp, int *n) /* get an integer */{ double d; Bgetd(bp, &d); *n = d;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -