2
* This routine scans a page for font definitions and character usage.
3
* It keeps an estimate of the memory remaining in the printer, and
4
* returns false when that memory is exhausted, unless scanning the
5
* first page. Otherwise it returns 1 if no problems were found,
6
* or 2 if it thinks the first page of a section may overflow memory.
8
#include "dvips.h" /* The copyright notice in that file is included too! */
11
* These are the external routines we need.
15
extern integer firstboploc ;
17
* And, of course, the globals it uses.
20
extern integer debug_flag;
22
extern fontdesctype *curfnt ;
23
extern fontmaptype *ffont ;
24
extern quarterword *curpos, *curlim ;
25
extern integer fontmem ;
26
extern integer pagecount ;
27
extern integer pagenum ;
28
extern Boolean compressed ;
29
extern FILE *dvifile ;
30
extern char errbuf[] ;
31
extern frametype frames[] ;
32
extern integer pagecost ;
33
extern Boolean noomega ;
35
* Charge pagecost for the cost of showing the character that *cd refers to
36
* and charge fontmem for the cost of downloading the character if necessary.
37
* A zero result indicates that we have run out of memory.
38
* If the character is small (a small packet), we save 43 bytes (since we
39
* use a single string instead of an array with integers in the PostScript.)
42
prescanchar P1C(chardesctype *, cd)
44
register quarterword *cras ;
45
register integer thischar ;
47
if ((cd->flags & (PREVPAGE | THISPAGE)) == 0) {
48
/* the character hasn't been used before in the current section */
50
if (curfnt->resfont) {
51
thischar = PSCHARCOST ;
52
cd->flags |= THISPAGE ;
53
} else if (cras != NULL) {
55
if (cd->flags & BIGCHAR)
58
if ((cd->flags & REPACKED) == 0) {
64
thischar += getlong(cras + 17) ;
66
thischar += getlong(cras + 9) ;
68
thischar += getlong(cras + 5) ;
72
thischar += getlong(cras + 1)
73
* ((getlong(cras + 5) + 7) >> 3) ;
75
thischar += (cras[3] * 256L + cras[4]) *
76
((cras[1] * 256L + cras[2] + 7) >> 3) ;
78
thischar += ((long)(cras[2] * ((cras[1] + 7) >> 3))) ;
80
cd->flags |= THISPAGE ;
84
if (fontmem <= pagecost) {
92
* When a font is selected during the prescan, this routine makes sure that
93
* the tfm or pk file is loaded and charges fontmem for the VM overhead in
94
* creating the font. The result is true unless the section must be aborted
95
* in order to keep this font from overflowing VM.
98
preselectfont P1C(fontdesctype *, f)
101
if (curfnt->loaded == 0 || curfnt->loaded == 3) {
102
if (!residentfont(curfnt))
103
if (!virtualfont(curfnt))
106
if (curfnt->psname == 0) {
107
if (curfnt->loaded < 2) /* virtual font costs nothing (yet) */
109
fontmem -= PSFONTCOST ;
111
fontmem -= FONTCOST + curfnt->maxchars ;
112
if (curfnt->loadeddpi != curfnt->dpi)
113
fontmem -= 48 ; /* for the new font matrix */
116
if (fontmem <= pagecost) {
124
* Now our scanpage routine.
129
register shalfword cmd ;
130
register chardesctype *cd ;
131
register fontmaptype *cfnt = 0 ;
134
register frametype *frp = frames ;
136
if (firstboploc == 0)
137
firstboploc = ftell(dvifile) ;
142
(void)fprintf(stderr,"Scanning page %ld\n", pagenum) ;
143
#else /* ~SHORTINT */
144
(void)fprintf(stderr,"Scanning page %d\n", pagenum) ;
145
#endif /* ~SHORTINT */
150
bopcolor(0) ; /* IBM: color - put current colorstack to bopstackdepth */
153
switch (cmd=dvibyte()) {
154
case 130: case 131: case 135: case 136: case 139:
155
case 247: case 248: case 249: case 250: case 251: case 252: case 253:
156
case 254: case 255: /* unimplemented or illegal commands */
157
(void)sprintf(errbuf,
158
"! DVI file contains unexpected command (%d)",cmd) ;
160
case 132: case 137: /* eight-byte commands setrule, putrule */
165
case 146: case 151: case 156: case 160: case 165: case 170:
166
/* four-byte commands right4, w4, x4, down4, y4, z4 */
168
case 145: case 150: case 155: case 159: case 164: case 169:
169
/* three-byte commands right3, w3, x3, down3, y3, z3 */
171
case 144: case 149: case 154: case 158: case 163: case 168:
172
/* two-byte commands right2, w2, x2, down2, y2, z2 */
174
case 143: case 148: case 153: case 157: case 162: case 167:
175
/* one-byte commands right1, w1, x1, down1, y1, z1 */
177
case 147: case 152: case 161: case 166: /* w0, x0, y0, z0 */
178
case 138: case 141: case 142: /* nop, push, pop */
180
case 134: case 129: /* set2, put2 */
182
(void)sprintf(errbuf,
183
"! DVI file contains unexpected Omega command (%d)",cmd) ;
186
mychar = dvibyte() ; mychar = (mychar << 8) + dvibyte() ;
188
case 133: case 128: cmd = dvibyte() ; /* set1 commands drops through */
189
default: /* these are commands 0 (setchar0) thru 127 (setchar 127) */
193
* We are going to approximate that each string of consecutive characters
194
* requires (length of string) bytes of PostScript VM.
197
error("! Bad DVI file: no font selected") ;
198
if (mychar>=curfnt->maxchars) {
199
(void)sprintf(errbuf,"! invalid char %d from font %s", mychar, curfnt->name) ;
202
if (curfnt->loaded == 2) { /* scanning a virtual font character */
207
if (++frp == &frames[MAXFRAME] )
208
error("! virtual recursion stack overflow") ;
209
cd = curfnt->chardesc + mychar ;
210
if (cd->packptr == 0)
211
error("! a non-existent virtual character is being used; check vf/tfm files") ;
212
curpos = cd->packptr + 2 ;
213
curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
214
ffont = curfnt->localfonts ;
217
else if (!preselectfont(ffont->desc))
221
if (!prescanchar(curfnt->chardesc + mychar))
225
case 171: case 172: case 173: case 174: case 175: case 176: case 177:
226
case 178: case 179: case 180: case 181: case 182: case 183: case 184:
227
case 185: case 186: case 187: case 188: case 189: case 190: case 191:
228
case 192: case 193: case 194: case 195: case 196: case 197: case 198:
229
case 199: case 200: case 201: case 202: case 203: case 204: case 205:
230
case 206: case 207: case 208: case 209: case 210: case 211: case 212:
231
case 213: case 214: case 215: case 216: case 217: case 218: case 219:
232
case 220: case 221: case 222: case 223: case 224: case 225: case 226:
233
case 227: case 228: case 229: case 230: case 231: case 232: case 233:
234
case 234: case 235: case 236: case 237: case 238: /* font selection commands */
235
if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
237
fnt = dvibyte() ; /* fnt1 */
239
fnt = (fnt << 8) + dvibyte() ;
241
for (cfnt=ffont; cfnt; cfnt = cfnt->next)
242
if (cfnt->fontnum == fnt) goto fontfound ;
243
printf("Font number %d not found\n", fnt) ;
244
error("! no font selected") ;
245
fontfound: curfnt = cfnt->desc ;
246
if (!preselectfont(curfnt))
249
case 239: predospecial((integer)dvibyte(), 1) ; break ; /* xxx1 */
250
case 240: predospecial((integer)twobytes(), 1) ; break ; /* xxx2 */
251
case 241: predospecial(threebytes(), 1) ; break ; /* xxx3 */
252
case 242: predospecial(signedquad(), 1) ; break ; /* xxx4 */
253
case 243: case 244: case 245: case 246: fontdef(cmd-242) ; break ; /* fntdef1 */
254
case 140: /* eop or end of virtual char */
263
goto endofpage ; /* eop */
267
if (fontmem > pagecost)
273
(void)fprintf(stderr, "Page %ld may be too complex to print\n", pagenum) ;
274
#else /* ~SHORTINT */
275
(void)fprintf(stderr, "Page %d may be too complex to print\n", pagenum) ;
276
#endif /* ~SHORTINT */
278
* This case should be rare indeed. Even with only 200K of virtual memory,
279
* at 11 bytes per char, you can have 18K characters on a page.
284
curpos = frames->curp ;
285
curlim = frames->curl ;
287
curfnt = frames->curf ;