URI:
       tutils.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
       ---
       tutils.c (7116B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include "../common/common.h"
            5 #include "tr2post.h"
            6 
            7 int hpos = 0, vpos = 0;
            8 int fontsize, fontpos;
            9 
           10 #define MAXSTR        128
           11 int trindex;                        /* index into trofftab of current troff font */
           12 static int expecthmot = 0;
           13 
           14 void
           15 initialize(void) {
           16 }
           17 
           18 void
           19 hgoto(int x) {
           20         hpos = x;
           21         if (pageon()) {
           22                 endstring();
           23 /*                Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
           24         }
           25 }
           26 
           27 void
           28 vgoto(int y) {
           29         vpos = y;
           30         if (pageon()) {
           31                 endstring();
           32 /*                Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
           33         }
           34 }
           35 
           36 void
           37 hmot(int x) {
           38         int delta;
           39 
           40         if ((x<expecthmot-1) || (x>expecthmot+1)) {
           41                 delta = x - expecthmot;
           42                 if (curtrofffontid <0 || curtrofffontid >= troffontcnt) {
           43                         Bprint(Bstderr, "troffontcnt=%d curtrofffontid=%d\n", troffontcnt, curtrofffontid);
           44                         Bflush(Bstderr);
           45                         exits("");
           46                 }
           47                 if (delta == troffontab[curtrofffontid].spacewidth*fontsize/10 && isinstring()) {
           48                         if (pageon()) runeout(' ');
           49                 } else {
           50                         if (pageon()) {
           51                                 endstring();
           52                                 /* Bprint(Bstdout, " %d 0 rmoveto ", delta); */
           53 /*                                Bprint(Bstdout, " %d %d m ", hpos+x, vpos); */
           54                                 if (debug) Bprint(Bstderr, "x=%d expecthmot=%d\n", x, expecthmot);
           55                         }
           56                 }
           57         }
           58         hpos += x;
           59         expecthmot = 0;
           60 }
           61 
           62 void
           63 vmot(int y) {
           64         endstring();
           65 /*        Bprint(Bstdout, " 0 %d rmoveto ", -y); */
           66         vpos += y;
           67 }
           68 
           69 struct charent **
           70 findglyph(int trfid, Rune rune, char *stoken) {
           71         struct charent **cp;
           72 
           73         for (cp = &(troffontab[trfid].charent[RUNEGETGROUP(rune)][RUNEGETCHAR(rune)]); *cp != 0; cp = &((*cp)->next)) {
           74                 if ((*cp)->name) {
           75                         if (debug) Bprint(Bstderr, "looking for <%s>, have <%s> in font %s\n", stoken, (*cp)->name, troffontab[trfid].trfontid);
           76                         if (strcmp((*cp)->name, stoken) == 0)
           77                                 break;
           78                 }
           79         }
           80         return(cp);
           81 }
           82 
           83 /* output glyph.  Use first rune to look up character (hash)
           84  * then use stoken UTF string to find correct glyph in linked
           85  * list of glyphs in bucket.
           86  */
           87 void
           88 glyphout(Rune rune, char *stoken, BOOLEAN specialflag) {
           89         struct charent **cp;
           90         struct troffont *tfp;
           91         struct psfent *psfp = (struct psfent*)0;
           92         int i, t;
           93         int fontid;        /* this is the troff font table index, not the mounted font table index */
           94         int mi, wid;
           95         Rune r;
           96 
           97         mi = 0;
           98         settrfont();
           99 
          100         /* check current font for the character, special or not */
          101         fontid = curtrofffontid;
          102 if (debug) fprint(2, "        looking through current font: trying %s\n", troffontab[fontid].trfontid);
          103         cp = findglyph(fontid, rune, stoken);
          104         if (*cp != 0) goto foundit;
          105 
          106         if (specialflag) {
          107                 if (expecthmot) hmot(0);
          108 
          109                 /* check special fonts for the special character */
          110                 /* cycle through the (troff) mounted fonts starting at the next font */
          111                 for (mi=0; mi<fontmnt; mi++) {
          112                         if (troffontab[fontid].trfontid==0) error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n",
          113                                 fontid, troffontab[fontid].trfontid);
          114                         if (fontmtab[mi]==0) {
          115                                 if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", mi, fontmtab[mi], fontmnt);
          116                                 continue;
          117                         }
          118                         if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0) break;
          119                 }
          120                 if (mi==fontmnt) error(FATAL, "current troff font is not mounted, botch!\n");
          121                 for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
          122                         if (fontmtab[i]==0) {
          123                                 if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", i, fontmtab[i], fontmnt);
          124                                 continue;
          125                         }
          126                         fontid = findtfn(fontmtab[i], TRUE);
          127 if (debug) fprint(2, "        looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
          128                         if (troffontab[fontid].special) {
          129                                 cp = findglyph(fontid, rune, stoken);
          130                                 if (*cp != 0) goto foundit;
          131                         }
          132                 }
          133 
          134                 /* check font 1 (if current font is not font 1) for the special character */
          135                 if (mi != 1) {
          136                                 fontid = findtfn(fontmtab[1], TRUE);;
          137 if (debug) fprint(2, "        looking through font at position 1: trying %s\n", troffontab[fontid].trfontid);
          138                                 cp = findglyph(fontid, rune, stoken);
          139                                 if (*cp != 0) goto foundit;
          140                 }
          141         }
          142 
          143         if (*cp == 0) {
          144                 error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
          145                         troffontab[curtrofffontid].trfontid);
          146                 expecthmot = 0;
          147         }
          148 
          149         /* use the peter face in lieu of the character that we couldn't find */
          150         rune = 'p';        stoken = "pw";
          151         for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
          152                 if (fontmtab[i]==0) {
          153                         if (debug) fprint(2, "fontmtab[%d]=0x%x\n", i, fontmtab[i]);
          154                         continue;
          155                 }
          156                 fontid = findtfn(fontmtab[i], TRUE);
          157 if (debug) fprint(2, "        looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
          158                 if (troffontab[fontid].special) {
          159                         cp = findglyph(fontid, rune, stoken);
          160                         if (*cp != 0) goto foundit;
          161                 }
          162         }
          163 
          164         if (*cp == 0) {
          165                 error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
          166                         troffontab[curtrofffontid].trfontid);
          167                 expecthmot = 0;
          168                 return;
          169         }
          170 
          171 foundit:
          172         t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff);
          173         if (debug) {
          174                 Bprint(Bstderr, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n",
          175                         rune, rune, (*cp)->postfontid, (*cp)->postcharid, (*cp)->troffcharwidth);
          176         }
          177 
          178         tfp = &(troffontab[fontid]);
          179         for (i=0; i<tfp->psfmapsize; i++) {
          180                 psfp = &(tfp->psfmap[i]);
          181                 if(t>=psfp->start && t<=psfp->end) break;
          182         }
          183         if (i >= tfp->psfmapsize)
          184                 error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune);
          185 
          186         setpsfont(psfp->psftid, fontsize);
          187 
          188         if (t == 0x0001) {        /* character is in charlib */
          189                 endstring();
          190                 if (pageon()) {
          191                         Bprint(Bstdout, "%d %d m ", hpos, vpos);
          192                         /* if char is unicode character rather than name, clean up for postscript */
          193                         wid = chartorune(&r, (*cp)->name);
          194                         if(' '<r && r<0x7F)
          195                                 Bprint(Bstdout, "%d build_%s\n", (*cp)->troffcharwidth, (*cp)->name);
          196                         else{
          197                                 if((*cp)->name[wid] != 0)
          198                                         error(FATAL, "character <%s> badly named\n", (*cp)->name);
          199                                 Bprint(Bstdout, "%d build_X%.4x\n", (*cp)->troffcharwidth, r);
          200                         }
          201 
          202                         /* stash charent pointer in a list so that we can print these character definitions
          203                          * in the prologue.
          204                          */
          205                         for (i=0; i<build_char_cnt; i++)
          206                                 if (*cp == build_char_list[i]) break;
          207                         if (i == build_char_cnt) {
          208                                 build_char_list = galloc(build_char_list, sizeof(struct charent *) * ++build_char_cnt,
          209                                 "build_char_list");
          210                                 build_char_list[build_char_cnt-1] = *cp;
          211                         }
          212                 }
          213                 expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
          214         } else if (isinstring() || rune != ' ') {
          215                 startstring();
          216                 if (pageon()) {
          217                         if (rune == ' ')
          218                                 Bprint(Bstdout, " ");
          219                         else
          220                                 Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str);
          221                 }
          222                 expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
          223         }
          224 }
          225 
          226 /* runeout puts a symbol into a string (queue) to be output.
          227  * It also has to keep track of the current and last symbol
          228  * output to check that the spacing is correct by default
          229  * or needs to be adjusted with a spacing operation.
          230  */
          231 
          232 void
          233 runeout(Rune rune) {
          234         char stoken[UTFmax+1];
          235         int i;
          236 
          237         i = runetochar(stoken, &rune);
          238         stoken[i] = '\0';
          239         glyphout(rune, stoken, TRUE);
          240 }
          241 
          242 void
          243 specialout(char *stoken) {
          244         Rune rune;
          245 
          246         chartorune(&rune, stoken);
          247         glyphout(rune, stoken, TRUE);
          248 }
          249 
          250 void
          251 graphfunc(Biobuf *bp) {
          252 }
          253 
          254 long
          255 nametorune(char *name) {
          256         return(0);
          257 }
          258 
          259 void
          260 notavail(char *msg) {
          261         Bprint(Bstderr, "%s is not available at this time.\n", msg);
          262 }