|
|
1.1 root 1:
2:
3: /*
4: *
5: * A few routines used to handle printer resident fonts. They cause us
6: * some problems because there's no guaranteed way the post-processor
7: * can be sure what fonts are resident on a particular printer. It's
8: * certainly possible that two otherwise identical printers could
9: * support different resident fonts, and we need to be able to deal
10: * with that situation. The way I've decided to handle things is have
11: * the post-processor look for special files in *bitdir/RESIDENT as
12: * part of the startup procedure. If the file's found and can be
13: * read it's used to get all the required resident font data for
14: * the printer. If we can't read the control file we'll just assume
15: * there aren't any resident fonts. Usually the file we're looking for
16: * will have the same name as the target printer, although that can
17: * be changed by an option - so we can handle different sets of
18: * resident fonts.
19: *
20: * The control file is ASCII right now and names the resident fonts,
21: * the available sizes, family tables, and the member maps. All the
22: * required maps are read and immediately written to the output file.
23: * Everything else is saved in resdata[] and only used when needed.
24: * See the comments at the start of resfonts() for a more complete
25: * description of the file.
26: *
27: * The member maps and family tables come from Imagen, although not
28: * directly. I got the info for the lucida fonts by taking one of
29: * their programs (mkres) and forcing routine dump_data() to run.
30: * The output from mkres was then used to build the control file.
31: * You may have to do something similiar if you've got a new set
32: * of printer resident fonts.
33: *
34: * There are other problems, most caused by Imagen's resident fonts.
35: * The most annoying is the need to use member maps and family tables.
36: * As it turns out the available member codes aren't good enough to
37: * access all the required characters in a resident font. That means
38: * we can't just use map 0 and the character code available in the
39: * font files. Things sure would have been simpler if resident fonts
40: * were more logical. Actually I'm not convinced resident fonts are
41: * that great an idea.
42: *
43: */
44:
45:
46: #include <stdio.h>
47:
48: #include "gen.h" /* definitions used by everyone */
49: #include "ext.h" /* external variable declarations */
50: #include "init.h" /* just used to get RESDIR */
51: #include "rast.h" /* raster file definitions */
52: #include "impcodes.h" /* Impress 2.0 opcodes */
53:
54:
55: Resdata resdata[MAXRESIDENT]; /* used to manage resident fonts */
56: int maxres = 0; /* entries so far in resdata[] */
57:
58:
59: /*
60: *
61: * We'll want to add size list data for the resident fonts to the
62: * sizedata[] structure so mapsize() works properly.
63: *
64: */
65:
66:
67: extern Sizedata sizedata[]; /* so we can add resident font sizes */
68: extern int maxrast;
69:
70:
71: /*****************************************************************************/
72:
73:
74: resfonts(tf)
75:
76:
77: FILE *tf; /* Impress commands go here */
78:
79:
80: {
81:
82:
83: char name[60]; /* control file pathname */
84: char cmd[20]; /* commands read from *name */
85: int i; /* fill in resdata[i] next */
86: int member; /* starting member for triple */
87: int symbol; /* starting symbol */
88: int count; /* members mapped by this triple */
89: int j, n; /* used for a bunch of things */
90: FILE *fp;
91:
92:
93: /*
94: *
95: * Resident fonts require some rather special attention. We'll need to
96: * keep track of all the resident font names and their associated
97: * family tables. In addition we'll need to download all the required
98: * member maps. All this stuff is expected to be in file *resfile
99: * which is located in *bitdir/RESIDENT. If the file can't be read
100: * we'll just assume there aren't any printer resident fonts.
101: *
102: * For now the control file is ASCII, even though there are more
103: * efficient ways of doing things. A decent alternative would be
104: * to have all the required Impress commands in the file. That
105: * way the file could just be copied directly to the output file.
106: * Member maps work nicely that way, but the family tables pose
107: * some problems because we've got to add the size to the font
108: * name string. Anyway there other choices and most any of them
109: * would cause the post-processor to run faster.
110: *
111: * For now the control file format looks something like,
112: *
113: *
114: * font <name1>
115: * sizes <size list> 0
116: * families <n>
117: * <map1> <font1>
118: * .
119: * .
120: * .
121: * <mapn> <fontn>
122: * font <name2>
123: * .
124: * .
125: * .
126: * font <namen>
127: * map <mapname1> <n>
128: * <mem1> <symbol1> <count1>
129: * .
130: * .
131: * .
132: * <memn> <symboln> <countn>
133: * map <mapname2> <n>
134: *
135: * .
136: * .
137: * .
138: *
139: * map <mapnamen> <n>
140: * .
141: * .
142: * .
143: * (EOF)
144: *
145: *
146: * The <size list> data must be given in increasing order and terminated
147: * with a 0 entry. Comments can be put in the file, although I don't
148: * recommend it. They're lines that have '#' as the first non white
149: * space character.
150: *
151: * The font names and family tables are saved in resdata[], size info
152: * is added to sizedata[], and the member maps are immediately downloaded.
153: *
154: * I'm not responsible for the member maps or family tables. I got the
155: * ones for the lucida font by running Imagen's mkres program with the
156: * dump_data() routine working (just took a few ifdefs out). The output
157: * from that routine was used to build the ASCII control file.
158: *
159: */
160:
161:
162: sprintf(name, "%s/%s/%s", bitdir, RESDIR, resfile);
163: if ( (fp = fopen(name, "r")) == NULL )
164: return;
165:
166: i = maxres - 1; /* incremented when "font" is read */
167:
168: while ( fscanf(fp, "%s", cmd) != EOF ) {
169: if ( strcmp(cmd, "font") == 0 )
170: fscanf(fp, "%10s", resdata[++i].name);
171: else if ( strcmp(cmd, "sizes") == 0 ) {
172: strncpy(sizedata[maxrast].name, resdata[i].name, L_FNAME);
173: j = 0;
174: while ( fscanf(fp, "%d", &n) != EOF && n != 0 )
175: sizedata[maxrast].sizes[j++] = n;
176: sizedata[maxrast].sizes[j] = 999;
177: if ( ++maxrast >= MAXFONTS )
178: error(FATAL, "too many fonts in %s", name);
179: } else if ( strcmp(cmd, "families") == 0 ) {
180: fscanf(fp, "%d", &resdata[i].count);
181: for ( j = 0; j < resdata[i].count; j++ )
182: fscanf(fp, "%d %10s", &resdata[i].table[j].map, resdata[i].table[j].name);
183: } else if ( strcmp(cmd, "map") == 0 ) {
184: fscanf(fp, "%d %d", &n, &j);
185: putc(ACM, tf);
186: putc(n, tf);
187: putc(j, tf);
188: for ( ; j > 0; j-- ) {
189: fscanf(fp, "%d %d %d", &member, &symbol, &count);
190: putc(member, tf);
191: putint(symbol, tf);
192: putc(count, tf);
193: } /* End for */
194: } else if ( cmd[0] == '#' )
195: while ( (n = getc(fp)) != EOF && n != '\n' ) ;
196: else error(FATAL, "bad command %s in file %s", cmd, name);
197: } /* End while */
198:
199: maxres = i + 1;
200:
201: fclose(fp);
202:
203: } /* End of resfonts */
204:
205:
206: /*****************************************************************************/
207:
208:
209: isresident(name)
210:
211:
212: char *name; /* is this a printer resident font? */
213:
214:
215: {
216:
217:
218: int i; /* check res_data[i] next */
219:
220:
221: /*
222: *
223: * Returns TRUE if font *name is a resident font and FALSE otherwise.
224: * Resident fonts are those listed in resdata[] array, which is set up
225: * in routine resfonts() using file *bitdir/RESIDENT/resfile.
226: *
227: */
228:
229:
230: for ( i = 0; i < maxres; i++ )
231: if ( strncmp(name, resdata[i].name, L_FNAME) == 0 )
232: return(TRUE);
233:
234: return(FALSE);
235:
236: } /* End of isresident */
237:
238:
239: /*****************************************************************************/
240:
241:
242: getresdata(f, s, tf)
243:
244:
245: char *f; /* name of the resident font */
246: int s; /* in this point size */
247: FILE *tf; /* job's output file */
248:
249:
250: {
251:
252:
253: int i; /* loop index for setting famlies */
254:
255:
256: /*
257: *
258: * Makes sure data about resident font *f in size s is added to the
259: * fam_data[] array. Essentially the same as routine getrastdata()
260: * except that the chused bitmap is set to all ones so download()
261: * will know the printer already has the glyph. Also don't need the
262: * advance stuff saved in fam_data[].
263: *
264: */
265:
266:
267: cur_fam = getfamdata(f, s); /* using this family next */
268: fam = &fam_data[cur_fam];
269:
270: if ( cur_fam >= next_fam ) { /* first use */
271: if ( next_fam > MAXFAMILY ) /* can only use 0 to 95 */
272: error(FATAL, "job uses too many font families");
273:
274: strncpy(fam->name, f, L_FNAME); /* initialize the fields */
275: fam->name[L_FNAME-1] = '\0';
276: fam->size = s;
277: fam->rst = NULL;
278: fam->advance = NULL;
279: fam->glyphdir = NULL;
280: fam->first = 0;
281: fam->last = 128;
282:
283: for ( i = 0; i < 4; i++ ) {
284: fam->chused[i] = (unsigned char *) rastalloc((MAXMEMBER+BYTE)/BYTE, TRUE, 0377);
285: fam->fam[i] = -1;
286: } /* End for */
287:
288: famtables(f, s, tf); /* use resdata[] to define families */
289:
290: next_fam++;
291: } /* End if */
292:
293: return(cur_fam); /* probably never used */
294:
295: } /* End of getresdata */
296:
297:
298: /*****************************************************************************/
299:
300:
301: famtables(f, s, tf)
302:
303:
304: char *f; /* define tables for this font */
305: int s; /* in this size */
306: FILE *tf; /* commands written here */
307:
308:
309: {
310:
311:
312: int i; /* fonts position in resdata[] */
313: int j; /* next family pair */
314:
315:
316: /*
317: *
318: * Defines the family tables for font *f in size s using the data that
319: * was read from the ASCII control file and saved in resdata[]. We'll
320: * have to look font f up in resdata[] before doing anything. Although
321: * that wastes time because it was just done in isresident() it shouldn't
322: * be all that expensive because the family tables aren't downloaded
323: * that often. There are easy ways to get around it if you want.
324: *
325: */
326:
327:
328: for ( i = 0; i < maxres; i++ )
329: if ( strncmp(f, resdata[i].name, L_FNAME) == 0 )
330: break;
331:
332: if ( i >= maxres ) /* probably can't ever happen */
333: error(FATAL, "can't ffind family data for font %s", f);
334:
335: putc(ACFT, tf);
336: putc(cur_fam, tf);
337: putc(resdata[i].count, tf);
338:
339: for ( j = 0; j < resdata[i].count; j++ ) {
340: putc(resdata[i].table[j].map, tf);
341: fprintf(tf, "%.10s%d", resdata[i].table[j].name, s);
342: putc('\0', tf);
343: } /* End for */
344:
345: } /* End of famtables */
346:
347:
348: /*****************************************************************************/
349:
350:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.