URI:
       tmnihongo.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tmnihongo.c (6406B)
       ---
            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 }