|
|
1.1 root 1:
2:
3: /*
4: *
5: * The stuff in this file used to be part of di10.c. I've taken it out of
6: * the main part of the post-processor because we're now accepting two
7: * different formats for the raster files. The original raster files had
8: * some rather severe limitations. They were machine dependent and used
9: * shorts etc. quite extensively, especially as offsets to locate glyph
10: * bitmaps. That put a limit on the point sizes that could be offered
11: * even at 240 dots per inch, but at a resolution of 300 dots an inch
12: * we probably wouldn't be able to access the bitmaps in a complete font
13: * past size 24 or so. In addition nobody's supporting the old style
14: * raster files or digitizing new characters for us. I've decided to
15: * let the new post-processor read the old style raster files along with
16: * the ones supplied by Imagen, although the old style won't be the
17: * default.
18: *
19: *
20: *
21: * The following things manage raster font information.
22: * The big problem is mapping desired font + size into
23: * available font + size. For now, a file RASTERLIST
24: * contains entries like
25: * R 6 8 10 14 999
26: * I 8 10 12 999
27: * ...
28: * This data is used to create an array "fontdata" that
29: * describes legal fonts and sizes, and pointers to any
30: * data from files that has actually been loaded.
31: *
32: */
33:
34:
35: #include <stdio.h>
36:
37: #include "gen.h" /* some general purpose definitions */
38: #include "ext.h" /* external variable definitions */
39: #include "glyph.h" /* raster file structures */
40: #include "impcodes.h" /* Impress 2.0 opcode definitions */
41: #include "dimpress.h" /* we'll need a few of these defs */
42:
43:
44: #define MAXFONT 60 /* max number of fonts forever */
45:
46:
47: struct fontdata {
48: char name[4]; /* e.g., "R" or "PA" */
49: int size[10]; /* e.g., 6 8 10 14 0 */
50: struct fontset *fsp[10]; /* either NULL or block of data */
51: };
52:
53:
54:
55: struct Fontheader fh;
56: struct fontset {
57: int size;
58: int family;
59: struct Charparam *chp;
60: unsigned char *cdp; /* char data pointer */
61: unsigned char *chused; /* bit-indexed; 1 if char downloaded */
62: };
63:
64:
65: struct fontdata fontdata[MAXFONT];
66: struct fontset *fs; /* current font+size */
67: int maxfonts = 0; /* number actually used */
68: int nfamily = 0; /* next available family number */
69: int lastfam = -1; /* last family we told Impress about */
70:
71: extern int res; /* resolution assumed in input file */
72: extern int pres; /* printer resolution */
73: extern int rres; /* raster file resolution */
74: extern int hpos; /* troff's position variables */
75: extern int vpos;
76: extern float xfac; /* scaling factors */
77: extern float yfac;
78: extern int xoffset; /* hor and vert offsets in pixels */
79: extern int yoffset;
80: extern int font; /* using font in this position */
81: extern int size; /* and want this point size */
82: extern int lastfont; /* got raster files for guy last */
83: extern int lastsize; /* and in this point size */
84: extern int lastw; /* width of the last character */
85: extern int lastx; /* Impress coordinates right now */
86: extern int lasty;
87: extern int center; /* try and improve placement? */
88:
89:
90: /*****************************************************************************/
91:
92:
93: initfontdata() /* read RASTERLIST information */
94: {
95: char name[100];
96: FILE *fp;
97: int i, j, n;
98:
99: sprintf(name, "%s/RASTERLIST", rastdir);
100: if ((fp = fopen(name, "r")) == NULL)
101: error(FATAL, "can't open %s", name);
102: maxfonts = 0;
103: while (fscanf(fp, "%s", fontdata[maxfonts].name) != EOF) {
104: i = 0;
105: while (fscanf(fp, "%d", &n) != EOF && n < 100) {
106: fontdata[maxfonts].size[i] = n;
107: fontdata[maxfonts].fsp[i] = NULL;
108: i++;
109: }
110: fontdata[maxfonts].size[i] = 999;
111: if (++maxfonts > MAXFONT)
112: error(FATAL, "Too many fonts in RASTERLIST");
113: }
114: fclose(fp);
115: if (debug) {
116: fprintf(stderr, "initfontdata(): maxfonts=%d", maxfonts);
117: for (i = 0; i < maxfonts; i++) {
118: fprintf(stderr, "%.4s ", fontdata[i].name);
119: for (j = 0; fontdata[i].size[j] < 100; j++)
120: fprintf(stderr, " %3d", fontdata[i].size[j]);
121: fprintf(stderr, "\n");
122: }
123: }
124: }
125:
126: getfontdata(f, s) /* causes loading of font information if needed */
127: char *f;
128: int s;
129: {
130: int fd, n, i, j;
131: char name[100];
132: static int first = 1;
133:
134: if (first) {
135: initfontdata();
136: first = 0;
137: }
138:
139: for (i = 0; i < maxfonts; i++)
140: if (strcmp(f, fontdata[i].name) == 0)
141: break;
142: if (i >= maxfonts) /* the requested font wasn't there */
143: i = 0; /* use the first one (probably R) */
144:
145: s = (s * pres) / rres; /* scale the requested point size */
146:
147: /* find the best approximation to size s */
148: for (j = 1; s >= fontdata[i].size[j]; j++)
149: ;
150: j--;
151:
152: /* open file if necessary */
153: if (fontdata[i].fsp[j] == NULL) {
154: fs = (struct fontset *) malloc(sizeof(struct fontset));
155: fontdata[i].fsp[j] = fs;
156: fs->chp = (struct Charparam *) malloc(256*sizeof(struct Charparam));
157: sprintf(name, "%s/%s.%d", rastdir, f, fontdata[i].size[j]);
158: fd = open(name, 0);
159: if (fd == -1)
160: error(FATAL, "can't open %s", name);
161: read(fd, &fh, sizeof(struct Fontheader));
162: read(fd, fs->chp, 256*sizeof(struct Charparam));
163: fs->size = fontdata[i].size[j];
164: fs->family = nfamily;
165: nfamily += 2; /* even-odd leaves room for big fonts */
166: fs->cdp = (unsigned char *) malloc(fh.f_size);
167: fs->chused = (unsigned char *) malloc(256/8);
168: for (n = 0; n < 256/8; n++)
169: fs->chused[n] = 0;
170: n = read(fd, fs->cdp, fh.f_size);
171: close(fd);
172: }
173: fs = fontdata[i].fsp[j];
174: }
175:
176: xychar(c, f, s, chwid, tf)
177: register int c; /* print this character */
178: char *f; /* using this font */
179: int s; /* and this point size */
180: int chwid; /* use this as the char width? */
181: FILE *tf; /* output written to this FILE */
182:
183: {
184: register unsigned char *p;
185: register struct Charparam *par;
186: register int x, y;
187: char hold;
188: int i, n, rwid, ht, fam;
189: int w;
190:
191: x = hpos * xfac + 0.5;
192: x += xoffset;
193: y = vpos * yfac + 0.5;
194: y += yoffset;
195:
196: if (font != lastfont || size != lastsize) {
197: getfontdata(f, s);
198: lastsize = size;
199: lastfont = font;
200: }
201: par = fs->chp + c;
202: p = fs->cdp + par->c_addr;
203:
204: fam = fs->family;
205: if (c > 127)
206: fam++;
207: if (fam != lastfam) {
208: putc(ASF, tf);
209: putc(lastfam = fam, tf);
210: }
211:
212: /* first cut: ship each glyph as needed. */
213: /* ignore memory use, efficiency, etc. */
214:
215: if ( !checkbit(fs->chused, c) ) { /* 1st use of this character */
216: setbit(fs->chused, c);
217: putc(ASGLY, tf);
218: putint((fam << 7) | c, tf);
219: par->c_width = (char)((lastw * pres) / res);
220: putc(par->c_width, tf); /* character width */
221: hold=(char) (w = CONVINT(par->c_left) + CONVINT(par->c_right) + 1);
222: putc(hold,tf);
223: if ( center )
224: putc((w - CONVINT(par->c_width)) / 2, tf);
225: else putc(par->c_left, tf);
226: /* this nonsense fixes a bug in output produced by rec.c: */
227: /* when up is < 0 (and = 0?) size is one too big */
228: rwid = (1 + CONVINT(par->c_left) + CONVINT(par->c_right) + BYTE-1) / BYTE;
229: ht = par->c_size / rwid;
230: par->c_down = (char)(ht - CONVINT(par->c_up));
231: hold=(char)(CONVINT(par->c_down) + CONVINT(par->c_up));
232: putc(hold, tf);
233: putc(par->c_up, tf);
234: for (i = par->c_size; i--; )
235: putc(*p++, tf);
236: }
237:
238: if (y != lasty) {
239: putc(ASETAV, tf);
240: putint(y, tf);
241: lasty = y;
242: }
243:
244: if (ABS(x-lastx) > SLOP) {
245: putc(ASETAH, tf);
246: putint(x, tf);
247: lastx = x + (par->c_width & BMASK);
248: } else {
249: lastx += (par->c_width & BMASK);
250: }
251:
252: if (c <= 127)
253: putc(c, tf); /* fails if c > 127, probably disastrously */
254: else
255: putc(c-128, tf);
256: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.