Commit Diff


commit - 943563d53cd0c9ef271a1cf0e62271c1e7c6401e
commit + 4418401f335e22c27206c02a9d9f8c6c51ab1612
blob - /dev/null
blob + 89aaeebf4126de1270d535d2a5c9d7492c9ab797 (mode 644)
--- /dev/null
+++ src/cmd/mnihongo/README
@@ -0,0 +1,13 @@
+mnihongo is a fairly clumsy troff post-processor that 
+catches unicode characters that might be japanese,
+looks them up in a font file (currently
+/lib/font/bit/pelm/unicode.9x24.font) to get the
+bits, converts that to postscript, and dumps that
+in the output.
+
+Widths are taken from troff font Jp, which has at
+best a simple approximation to the truth.
+
+The program itself is normally called implicitly
+by loading the troff macro package -mnihongo, which
+does a .pi command.
blob - /dev/null
blob + 5842de57777f2232252968e6c722db2d9866bbb9 (mode 644)
--- /dev/null
+++ src/cmd/mnihongo/mkfile
@@ -0,0 +1,10 @@
+<$PLAN9/src/mkhdr
+
+SHORTLIB=draw bio 9
+
+TARG=mnihongo
+OFILES=mnihongo.$O
+
+<$PLAN9/src/mkone
+
+LDFLAGS=$LDFLAGS -L$X11/lib -lX11
blob - /dev/null
blob + 0a5f3710dc9978ffb6e6059856c890bd918c1124 (mode 644)
--- /dev/null
+++ src/cmd/mnihongo/mnihongo.c
@@ -0,0 +1,259 @@
+/*
+output language from troff:
+all numbers are character strings
+
+sn	size in points
+fn	font as number from 1-n
+cx	ascii character x
+Cxyz	funny char xyz. terminated by white space
+Nn	absolute character number n on this font.  ditto
+Hn	go to absolute horizontal position n
+Vn	go to absolute vertical position n (down is positive)
+hn	go n units horizontally (relative)
+vn	ditto vertically
+nnc	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 = after
+p	new page begins -- set v to 0
+#...\n	comment
+x ...\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;
+
+void
+main(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;
+}
blob - /dev/null
blob + 552b476a4b671aea509946de4d271c6aaa376829 (mode 644)
--- /dev/null
+++ src/cmd/mnihongo/tmac.nihongo
@@ -0,0 +1 @@
+.pi $PLAN9/bin/mnihongo