diff options
author | rsc <devnull@localhost> | 2004-05-15 23:55:53 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-05-15 23:55:53 +0000 |
commit | 61f5c35c9465f0702739b41249a664d409f0482c (patch) | |
tree | 17546b7dcc76abd9ee74dc7543cc77121acfe39a /src/cmd/postscript/tr2post/utils.c | |
parent | 173302913ebce353eadcbb12d71c3759cbe79e34 (diff) | |
download | plan9port-61f5c35c9465f0702739b41249a664d409f0482c.tar.gz plan9port-61f5c35c9465f0702739b41249a664d409f0482c.tar.bz2 plan9port-61f5c35c9465f0702739b41249a664d409f0482c.zip |
more files
Diffstat (limited to 'src/cmd/postscript/tr2post/utils.c')
-rw-r--r-- | src/cmd/postscript/tr2post/utils.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/cmd/postscript/tr2post/utils.c b/src/cmd/postscript/tr2post/utils.c new file mode 100644 index 00000000..8f58ea45 --- /dev/null +++ b/src/cmd/postscript/tr2post/utils.c @@ -0,0 +1,264 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "../common/common.h" +#include "tr2post.h" + +int hpos = 0, vpos = 0; +int fontsize, fontpos; + +#define MAXSTR 128 +int trindex; /* index into trofftab of current troff font */ +static int expecthmot = 0; + +void +initialize(void) { +} + +void +hgoto(int x) { + hpos = x; + if (pageon()) { + endstring(); +/* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */ + } +} + +void +vgoto(int y) { + vpos = y; + if (pageon()) { + endstring(); +/* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */ + } +} + +void +hmot(int x) { + int delta; + + if ((x<expecthmot-1) || (x>expecthmot+1)) { + delta = x - expecthmot; + if (curtrofffontid <0 || curtrofffontid >= troffontcnt) { + Bprint(Bstderr, "troffontcnt=%d curtrofffontid=%d\n", troffontcnt, curtrofffontid); + Bflush(Bstderr); + exits(""); + } + if (delta == troffontab[curtrofffontid].spacewidth*fontsize/10 && isinstring()) { + if (pageon()) runeout(' '); + } else { + if (pageon()) { + endstring(); + /* Bprint(Bstdout, " %d 0 rmoveto ", delta); */ +/* Bprint(Bstdout, " %d %d m ", hpos+x, vpos); */ + if (debug) Bprint(Bstderr, "x=%d expecthmot=%d\n", x, expecthmot); + } + } + } + hpos += x; + expecthmot = 0; +} + +void +vmot(int y) { + endstring(); +/* Bprint(Bstdout, " 0 %d rmoveto ", -y); */ + vpos += y; +} + +struct charent ** +findglyph(int trfid, Rune rune, char *stoken) { + struct charent **cp; + + for (cp = &(troffontab[trfid].charent[RUNEGETGROUP(rune)][RUNEGETCHAR(rune)]); *cp != 0; cp = &((*cp)->next)) { + if ((*cp)->name) { + if (debug) Bprint(Bstderr, "looking for <%s>, have <%s> in font %s\n", stoken, (*cp)->name, troffontab[trfid].trfontid); + if (strcmp((*cp)->name, stoken) == 0) + break; + } + } + return(cp); +} + +/* output glyph. Use first rune to look up character (hash) + * then use stoken UTF string to find correct glyph in linked + * list of glyphs in bucket. + */ +void +glyphout(Rune rune, char *stoken, BOOLEAN specialflag) { + struct charent **cp; + struct troffont *tfp; + struct psfent *psfp; + int i, t; + int fontid; /* this is the troff font table index, not the mounted font table index */ + int mi, fi, wid; + Rune r; + + settrfont(); + + /* check current font for the character, special or not */ + fontid = curtrofffontid; +if (debug) fprint(2, " looking through current font: trying %s\n", troffontab[fontid].trfontid); + cp = findglyph(fontid, rune, stoken); + if (*cp != 0) goto foundit; + + if (specialflag) { + if (expecthmot) hmot(0); + + /* check special fonts for the special character */ + /* cycle through the (troff) mounted fonts starting at the next font */ + for (mi=0; mi<fontmnt; mi++) { + if (troffontab[fontid].trfontid==0) error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n", + fontid, troffontab[fontid].trfontid); + if (fontmtab[mi]==0) { + if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", mi, fontmtab[mi], fontmnt); + continue; + } + if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0) break; + } + if (mi==fontmnt) error(FATAL, "current troff font is not mounted, botch!\n"); + for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) { + if (fontmtab[i]==0) { + if (debug) fprint(2, "fontmtab[%d]=0x%x, fontmnt=%d\n", i, fontmtab[i], fontmnt); + continue; + } + fontid = findtfn(fontmtab[i], TRUE); +if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid); + if (troffontab[fontid].special) { + cp = findglyph(fontid, rune, stoken); + if (*cp != 0) goto foundit; + } + } + + /* check font 1 (if current font is not font 1) for the special character */ + if (mi != 1) { + fontid = findtfn(fontmtab[1], TRUE);; +if (debug) fprint(2, " looking through font at position 1: trying %s\n", troffontab[fontid].trfontid); + cp = findglyph(fontid, rune, stoken); + if (*cp != 0) goto foundit; + } + } + + if (*cp == 0) { + error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken, + troffontab[curtrofffontid].trfontid); + expecthmot = 0; + } + + /* use the peter face in lieu of the character that we couldn't find */ + rune = 'p'; stoken = "pw"; + for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) { + if (fontmtab[i]==0) { + if (debug) fprint(2, "fontmtab[%d]=0x%x\n", i, fontmtab[i]); + continue; + } + fontid = findtfn(fontmtab[i], TRUE); +if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid); + if (troffontab[fontid].special) { + cp = findglyph(fontid, rune, stoken); + if (*cp != 0) goto foundit; + } + } + + if (*cp == 0) { + error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken, + troffontab[curtrofffontid].trfontid); + expecthmot = 0; + return; + } + +foundit: + t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff); + if (debug) { + Bprint(Bstderr, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n", + rune, rune, (*cp)->postfontid, (*cp)->postcharid, (*cp)->troffcharwidth); + } + + tfp = &(troffontab[fontid]); + for (i=0; i<tfp->psfmapsize; i++) { + psfp = &(tfp->psfmap[i]); + if(t>=psfp->start && t<=psfp->end) break; + } + if (i >= tfp->psfmapsize) + error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune); + + setpsfont(psfp->psftid, fontsize); + + if (t == 0x0001) { /* character is in charlib */ + endstring(); + if (pageon()) { + struct charent *tcp; + + Bprint(Bstdout, "%d %d m ", hpos, vpos); + /* if char is unicode character rather than name, clean up for postscript */ + wid = chartorune(&r, (*cp)->name); + if(' '<r && r<0x7F) + Bprint(Bstdout, "%d build_%s\n", (*cp)->troffcharwidth, (*cp)->name); + else{ + if((*cp)->name[wid] != 0) + error(FATAL, "character <%s> badly named\n", (*cp)->name); + Bprint(Bstdout, "%d build_X%.4x\n", (*cp)->troffcharwidth, r); + } + + /* stash charent pointer in a list so that we can print these character definitions + * in the prologue. + */ + for (i=0; i<build_char_cnt; i++) + if (*cp == build_char_list[i]) break; + if (i == build_char_cnt) { + build_char_list = galloc(build_char_list, sizeof(struct charent *) * ++build_char_cnt, + "build_char_list"); + build_char_list[build_char_cnt-1] = *cp; + } + } + expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth; + } else if (isinstring() || rune != ' ') { + startstring(); + if (pageon()) { + if (rune == ' ') + Bprint(Bstdout, " "); + else + Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str); + } + expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth; + } +} + +/* runeout puts a symbol into a string (queue) to be output. + * It also has to keep track of the current and last symbol + * output to check that the spacing is correct by default + * or needs to be adjusted with a spacing operation. + */ + +void +runeout(Rune rune) { + char stoken[UTFmax+1]; + int i; + + i = runetochar(stoken, &rune); + stoken[i] = '\0'; + glyphout(rune, stoken, TRUE); +} + +void +specialout(char *stoken) { + Rune rune; + int i; + + i = chartorune(&rune, stoken); + glyphout(rune, stoken, TRUE); +} + +void +graphfunc(Biobuf *bp) { +} + +long +nametorune(char *name) { + return(0); +} + +void +notavail(char *msg) { + Bprint(Bstderr, "%s is not available at this time.\n", msg); +} |