dpost.ps: increase linewidth to match groff
[troff.git] / tr2ps / utils.c
blobeef38358d6ea3ac447d8200b859748704200c89d
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "ustr.h"
5 #include "common.h"
6 #include "tr2ps.h"
8 int hpos = 0, vpos = 0;
9 int fontsize, fontpos;
11 #define MAXSTR 128
13 int trindex; /* index into trofftab of current troff font */
14 static int expecthmot = 0;
16 void initialize(void)
20 void hgoto(int x)
22 hpos = x;
23 if (pageon())
24 endstring();
27 void vgoto(int y)
29 vpos = y;
30 if (pageon())
31 endstring();
34 void hmot(int x)
36 int delta;
38 if (x < expecthmot - 1 || x > expecthmot + 1) {
39 delta = x - expecthmot;
40 if (curtrofffontid < 0 || curtrofffontid >= troffontcnt) {
41 fprintf(ferr, "troffontcnt=%d curtrofffontid=%d\n",
42 troffontcnt, curtrofffontid);
43 exit(1);
45 if (delta == troffontab[curtrofffontid].spacewidth * fontsize / 10 && isinstring()) {
46 if (pageon())
47 runeout(' ');
48 } else {
49 if (pageon()) {
50 endstring();
51 if (debug)
52 fprintf(ferr, "x=%d expecthmot=%d\n",
53 x, expecthmot);
57 hpos += x;
58 expecthmot = 0;
61 void vmot(int y)
63 endstring();
64 vpos += y;
67 struct charent *findglyph(int trfid, uc_t rune, char *stoken)
69 struct charent *cp;
70 cp = troffontab[trfid].charent[rune];
72 for (; cp; cp = cp->next)
73 if (cp->name)
74 if (strcmp(cp->name, stoken) == 0)
75 break;
76 return cp;
80 * Output glyph. Use first rune to look up character (hash)
81 * then use stoken UTF string to find correct glyph in linked
82 * list of glyphs in bucket.
84 void glyphout(uc_t rune, char *stoken, int specialflag)
86 struct charent *cp;
87 int i;
88 int fontid; /* this is the troff font table index, not the mounted font table index */
89 int mi = -1, wid;
90 uc_t r;
92 settrfont();
94 /* check current font for the character, special or not */
95 fontid = curtrofffontid;
96 cp = findglyph(fontid, rune, stoken);
97 if (cp)
98 goto foundit;
100 if (specialflag) {
101 if (expecthmot)
102 hmot(0);
104 if (!*troffontab[fontid].trfontid)
105 error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n",
106 fontid, troffontab[fontid].trfontid);
107 /* check special fonts for the special character */
108 /* cycle through the (troff) mounted fonts starting at the next font */
109 for (mi = 0; mi < fontmnt; mi++) {
110 if (!*fontmtab[mi])
111 continue;
112 if (strcmp(troffontab[fontid].trfontid, fontmtab[mi]) == 0)
113 break;
115 if (mi == fontmnt)
116 error(FATAL, "current troff font is not mounted, botch!\n");
117 for (i = (mi + 1) % fontmnt; i != mi; i = (i+1) % fontmnt) {
118 if (!*fontmtab[i])
119 continue;
120 fontid = findtfn(fontmtab[i], TRUE);
121 /* looking in special fonts */
122 if (troffontab[fontid].special) {
123 cp = findglyph(fontid, rune, stoken);
124 if (cp)
125 goto foundit;
129 /* check font 1 (if current font is not font 1) for the special character */
130 if (mi != 1) {
131 fontid = findtfn(fontmtab[1], TRUE);
132 cp = findglyph(fontid, rune, stoken);
133 if (cp)
134 goto foundit;
138 if (!cp) {
139 error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n",
140 rune, stoken, troffontab[curtrofffontid].trfontid);
141 expecthmot = 0;
142 return;
145 foundit:
146 /* set the correct font */
147 setpsfont(findpfn(troffontab[fontid].psfontid), fontsize);
149 if (cp->charnum == 0x0001) { /* character is in charlib */
150 endstring();
151 if (pageon()) {
152 fprintf(fout, "%d %d m ", hpos, vpos);
153 /* if char is unicode character rather than name, clean up for postscript */
154 wid = uc_dec(&r, cp->name);
155 if (' ' < r && r < 0x7F) {
156 fprintf(fout, "%d build_%s\n",
157 cp->troffcharwidth, cp->name);
158 } else {
159 if (cp->name[wid] != 0)
160 error(FATAL, "character <%s> badly named\n", cp->name);
161 fprintf(fout, "%d build_X%.4x\n", cp->troffcharwidth, r);
163 build_char(cp);
165 expecthmot = cp->troffcharwidth * fontsize / unitwidth;
166 } else if (isinstring() || rune != ' ') {
167 if (pageon()) {
168 if (rune == ' ')
169 showglyph(" ");
170 else if (cp->charnum < 256)
171 showglyph(charcode[cp->charnum].str);
172 else if (*cp->gname)
173 showglyph_byname(cp->gname);
175 expecthmot = cp->troffcharwidth * fontsize / unitwidth;
180 * runeout puts a symbol into a string (queue) to be output.
181 * It also has to keep track of the current and last symbol
182 * output to check that the spacing is correct by default
183 * or needs to be adjusted with a spacing operation.
185 void runeout(uc_t rune)
187 char stoken[UTFmax + 1];
188 int i;
190 i = uc_enc(stoken, rune);
191 stoken[i] = '\0';
192 glyphout(rune, stoken, TRUE);
195 void specialout(char *stoken)
197 uc_t rune;
198 uc_dec(&rune, stoken);
199 glyphout(rune, stoken, TRUE);