plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

utils.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 }