aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/postscript/tr2post/utils.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-05-15 23:55:53 +0000
committerrsc <devnull@localhost>2004-05-15 23:55:53 +0000
commit61f5c35c9465f0702739b41249a664d409f0482c (patch)
tree17546b7dcc76abd9ee74dc7543cc77121acfe39a /src/cmd/postscript/tr2post/utils.c
parent173302913ebce353eadcbb12d71c3759cbe79e34 (diff)
downloadplan9port-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.c264
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);
+}