Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
%    Copyright (C) 1992, 1993, 1994, 1995, 1999 Aladdin Enterprises.  All rights reserved.
2
% 
3
% This software is provided AS-IS with no warranty, either express or
4
% implied.
5
% 
6
% This software is distributed under license and may not be copied,
7
% modified or distributed except as expressly authorized under the terms
8
% of the license contained in the file LICENSE in this distribution.
9
% 
10
% For more information about licensing, please refer to
11
% http://www.ghostscript.com/licensing/. For information on
12
% commercial licensing, go to http://www.artifex.com/licensing/ or
13
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15
 
16
% $Id: font2c.ps,v 1.6 2003/07/10 02:56:51 ray Exp $
17
% font2c.ps
18
% Write out a PostScript Type 0 or Type 1 font as C code
19
% that can be linked with the interpreter.
20
% This even works on protected fonts, if you use the -dWRITESYSTEMDICT
21
% switch in the command line.  The code is reentrant and location-
22
% independent and has no external references, so it can be put into
23
% a sharable library even on VMS.
24
 
25
/font2cdict 100 dict dup begin
26
 
27
% Define the maximum string length that all compilers will accept.
28
% This must be approximately
29
%	min(max line length, max string literal length) / 4 - 5.
30
 
31
/max_wcs 50 def
32
 
33
% Define a temporary file for writing out procedures.
34
/wtempname (_.tmp) def
35
 
36
% ------ Protection utilities ------ %
37
 
38
% Protection values are represented by a mask:
39
/a_noaccess 0 def
40
/a_executeonly 1 def
41
/a_readonly 3 def
42
/a_all 7 def
43
/prot_names
44
 [ (0) (a_execute) null (a_readonly) null null null (a_all)
45
 ] def
46
/prot_opers
47
 [ {noaccess} {executeonly} {} {readonly} {} {} {} {}
48
 ] def
49
 
50
% Get the protection of an object.
51
   /getpa
52
    { dup wcheck
53
       { pop a_all }
54
       {	% Check for executeonly or noaccess objects in protected.
55
         dup protected exch known
56
	  { protected exch get }
57
	  { pop a_readonly }
58
	 ifelse
59
       }
60
      ifelse
61
    } bind def
62
 
63
% Get the protection appropriate for (all the) values in a dictionary.
64
   /getva
65
    { a_noaccess exch
66
       { exch pop
67
         dup type dup /stringtype eq 1 index /arraytype eq or
68
	 exch /packedarraytype eq or
69
	  { getpa a_readonly and or }
70
	  { pop pop a_all exit }
71
	 ifelse
72
       }
73
      forall
74
    } bind def
75
 
76
% Keep track of executeonly and noaccess objects,
77
% but don't let the protection actually take effect.
78
.currentglobal
79
false .setglobal	% so protected can reference local objs
80
/protected		% do first so // will work
81
  systemdict wcheck { 1500 dict } { 1 dict } ifelse
82
def
83
systemdict wcheck not
84
 { (Warning: you will not be able to convert protected fonts.\n) print
85
   (If you need to convert a protected font, please\n) print
86
   (restart the program and specify the -dWRITESYSTEMDICT switch.\n) print
87
   flush
88
   (%end) .skipeof
89
 }
90
if
91
userdict begin
92
  /executeonly
93
   { dup //protected exch //a_executeonly put readonly
94
   } bind def
95
  /noaccess
96
   { dup //protected exch //a_noaccess put readonly
97
   } bind def
98
end
99
true .setglobal
100
systemdict begin
101
  /executeonly
102
   { userdict /executeonly get exec
103
   } bind odef
104
  /noaccess
105
   { userdict /noaccess get exec
106
   } bind odef
107
end
108
%end
109
.setglobal
110
 
111
% ------ Output utilities ------ %
112
 
113
% By convention, the output file is named cfile.
114
 
115
% Define some utilities for writing the output file.
116
   /wtstring 100 string def
117
   /wb {cfile exch write} bind def
118
   /ws {cfile exch writestring} bind def
119
   /wl {ws (\n) ws} bind def
120
   /wt {wtstring cvs ws} bind def
121
 
122
% Write a C string.  Some compilers have unreasonably small limits on
123
% the length of a string literal or the length of a line, so every place
124
% that uses wcs must either know that the string is short,
125
% or be prepared to use wcca instead.
126
   /wbx
127
    { 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
128
    } bind def
129
   /wcst
130
    [
131
      32 { /wbx load } repeat
132
      95 { /wb load } repeat
133
      129 { /wbx load } repeat
134
    ] def
135
   ("\\) { wcst exch { (\\) ws wb } put } forall
136
   /wcs
137
    { (") ws { dup wcst exch get exec } forall (") ws
138
    } bind def
139
   /can_wcs	% Test if can use wcs
140
    { length max_wcs le
141
    } bind def
142
   /wncs	% name -> C string
143
    { wtstring cvs wcs
144
    } bind def
145
% Write a C string as an array of character values.
146
% We only need this because of line and literal length limitations.
147
   /wca		% <string> <prefix> <suffix> wca -
148
    { 0 4 -2 roll exch
149
       {	% Stack: suffix n prefix char
150
	 exch ws
151
	 exch dup 19 ge { () wl pop 0 } if 1 add
152
	 exch dup 32 ge 1 index 126 le and
153
	  { 39 wb dup 39 eq 1 index 92 eq or { 92 wb } if wb 39 wb }
154
	  { wt }
155
	 ifelse (,)
156
       } forall
157
      pop pop ws
158
    } bind def
159
   /wcca	% <string> wcca -
160
    { ({\n) (}) wca
161
    } bind def
162
 
163
% Write object protection attributes.  Note that dictionaries and arrays are
164
% the only objects that can be writable.
165
   /wpa
166
    { dup xcheck { (a_executable|) ws } if
167
      dup type dup /dicttype eq exch /arraytype eq or
168
       { getpa }
169
       { getpa a_readonly and }
170
      ifelse prot_names exch get ws
171
    } bind def
172
   /wva
173
    { getva prot_names exch get ws
174
    } bind def
175
 
176
% ------ Object writing ------ %
177
 
178
   /wnstring 128 string def
179
 
180
% Convert an object to a string to be scanned at a later time.
181
   /cvos		% <obj> cvos <string>
182
    {		% We'd like to use == and write directly to a string,
183
		% but we can't do the former because of operators,
184
		% and we can't do the latter because we can't predict
185
		% how long the string would have to be....
186
	 wtempname (w) file dup 3 -1 roll wproc closefile
187
	 wtempname status pop pop pop exch pop string
188
	 wtempname (r) file dup 3 -1 roll readstring pop exch closefile
189
    } bind def
190
 
191
% Write a string/name or null as an element of a string/name/null array.
192
% Convert any other kind of value to a token to be read back in.
193
   /wsn
194
    { dup null eq
195
       { pop (\t255,255,) wl
196
       }
197
       { dup type /nametype eq { wnstring cvs } if
198
	 dup type /stringtype ne { cvos (255,) ws } if
199
	 dup length 256 idiv wt (,) ws
200
	 dup length 256 mod wt
201
	 (,) (,\n) wca
202
       }
203
      ifelse
204
    } bind def
205
% Write a packed string/name/null array.
206
   /wsna	% <name> <(string|name|null)*> wsna -
207
    { (\tstatic const unsigned char ) ws exch wt ([] = {) wl
208
      { wsn } forall
209
      (\t0\n};) wl
210
    } bind def
211
 
212
% Write a number or an array of numbers, as refs.
213
/isnumber
214
 { type dup /integertype eq exch /realtype eq or
215
 } bind def
216
/wnums
217
 { dup isnumber
218
    { (real_v\() ws wt (\),) ws }
219
    { { wnums } forall }
220
   ifelse
221
 } bind def
222
 
223
% Test whether a procedure or unusual array can be written (printed).
224
/iswx 4 dict dup begin
225
  /arraytype { { iswproc } isall } def
226
  /nametype { pop true } def
227
  /operatortype { pop true } def	% assume it has been bound in
228
  /packedarraytype /arraytype load def
229
end def
230
/iswnx 6 dict dup begin
231
  /arraytype { { iswproc } isall } def
232
  /integertype { pop true } def
233
  /nametype { pop true } def
234
  /realtype { pop true } def
235
  /stringtype { pop true } def
236
  /packedarraytype /arraytype load def
237
end def
238
/iswproc	% <obj> iswproc <bool>
239
 { dup xcheck { iswx } { iswnx } ifelse
240
   1 index type .knownget { exec } { pop false } ifelse
241
 } bind def
242
 
243
% Write a printable procedure (one for which iswproc returns true).
244
/wproca 3 dict dup begin
245
  /arraytype
246
   { 1 index ({) writestring
247
      { 1 index ( ) writestring 1 index exch wproc } forall
248
     (}) writestring
249
   } bind def
250
  /packedarraytype /arraytype load def
251
  /operatortype { .writecvs } bind def	% assume binding would work
252
end def
253
/wproc		% <file> <proc> wproc -
254
 { dup type wproca exch .knownget { exec } { write==only } ifelse
255
 } bind def
256
 
257
% Write a named object.  Return true if this was possible.
258
% Legal types are: boolean, integer, name, real, string,
259
% array of (integer, integer+real, name, null+string),
260
% and certain procedures and other arrays (see iswproc above).
261
% All other objects are either handled specially or ignored.
262
   /isall	% <array> <proc> isall <bool>
263
    { true 3 -1 roll
264
       { 2 index exec not { pop false exit } if }
265
      forall exch pop
266
    } bind def
267
   /wott 8 dict dup begin
268
      /arraytype
269
       { woatt
270
          { aload pop 2 index 2 index exec
271
	     { exch pop exec exit }
272
	     { pop pop }
273
	    ifelse
274
	  }
275
	 forall
276
       } bind def
277
      /booleantype
278
       { { (\tmake_true\(&) } { (\tmake_false\(&) } ifelse ws
279
         wt (\);) wl true
280
       } bind def
281
      /integertype
282
       { (\tmake_int\(&) ws exch wt (, ) ws
283
         wt (\);) wl true
284
       } bind def
285
      /nametype
286
       { (\tcode = (*pprocs->name_create)\(i_ctx_p, &) ws exch wt
287
         (, ) ws wnstring cvs wcs	% OK, names are short
288
	 (\);) wl
289
	 (\tif ( code < 0 ) return code;) wl
290
	 true
291
       } bind def
292
      /packedarraytype
293
	/arraytype load def
294
      /realtype
295
       { (\tmake_real\(&) ws exch wt (, (float)) ws
296
         wt (\);) wl true
297
       } bind def
298
      /stringtype
299
       { ({\tstatic const unsigned char s_[] = ) ws
300
         dup dup can_wcs { wcs } { wcca } ifelse
301
	 (;) wl
302
	 (\tmake_const_string\(&) ws exch wt
303
	 (, a_readonly, ) ws length wt (, (const byte *)s_\);) wl
304
	 (}) wl true
305
       } bind def
306
   end def
307
% Write some other kind of object, if known.
308
   /wother
309
    { dup otherobjs exch known
310
       { otherobjs exch get (\t) ws exch wt ( = ) ws wt (;) wl true }
311
       { pop pop false }
312
      ifelse
313
    } bind def
314
% Top-level procedure.
315
   /wo		% name obj -> OK
316
    { dup type wott exch .knownget { exec } { wother } ifelse
317
    } bind def
318
 
319
% Write an array (called by wo).
320
   /wap		% <name> <array> wap -
321
    { dup xcheck not 1 index wcheck not and 1 index rcheck and
322
       { pop pop }
323
       { (\tr_set_attrs\(&) ws exch wt (, ) ws wpa (\);) wl }
324
      ifelse
325
    } bind def
326
   /wnuma {	% <name> <array> <element_C_type> <<type>_v> wnuma -
327
      ({\tstatic const ref_\() ws exch ws (\) a_[] = {) wl exch
328
		% Stack: name type_v array
329
      dup length 0 eq {
330
	(\t) ws 1 index ws (\(0\)) wl
331
      } {
332
	dup {
333
	  (\t) ws 2 index ws (\() ws wt (\),) wl
334
	} forall
335
      } ifelse exch pop
336
		% Stack: name array
337
      (\t};) wl
338
      dup wcheck {
339
	(\tcode = (*pprocs->scalar_array_create)\(i_ctx_p, &) ws exch wt
340
	(, (const ref *)a_, ) ws dup length wt
341
	(, ) ws wpa (\);) wl
342
	(\tif ( code < 0 ) return code;) wl
343
      } {
344
	(\tmake_const_array\(&) ws exch wt
345
	(, avm_foreign|) ws dup wpa (, ) ws length wt
346
	(, (const ref *)a_\);) wl
347
      } ifelse
348
      (}) wl
349
    } bind def
350
   /woatt [
351
	% Integers
352
     { { { type /integertype eq } isall }
353
       { (long) (integer_v) wnuma true }
354
     }
355
	% Integers + reals
356
     { { { type dup /integertype eq exch /realtype eq or } isall }
357
       { (float) (real_v) wnuma true }
358
     }
359
	% Strings + nulls
360
     { { { type dup /nulltype eq exch /stringtype eq or } isall }
361
       { ({) ws dup (sa_) exch wsna
362
	 (\tcode = (*pprocs->string_array_create)\(i_ctx_p, &) ws exch wt
363
	 (, \(const char *\)sa_, ) ws dup length wt (, ) ws wpa (\);) wl
364
	 (\tif ( code < 0 ) return code;) wl
365
	 (}) wl true
366
       }
367
     }
368
	% Names
369
     { { { type /nametype eq } isall }
370
       { ({) ws dup (na_) exch wsna
371
	 (\tcode = (*pprocs->name_array_create)\(i_ctx_p, &) ws 1 index wt
372
	 (, \(const char *\)na_, ) ws dup length wt (\);) wl
373
	 (\tif ( code < 0 ) return code;) wl
374
	 wap (}) wl true
375
       }
376
     }
377
	% Procedure
378
     { { iswproc }
379
       { dup cvos
380
		% Stack: name proc string
381
	 ({\tstatic const unsigned char s_[] = ) ws
382
         dup dup can_wcs { wcs } { wcca } ifelse
383
	 (;) wl
384
	 (\tcode = (*pprocs->ref_from_string)\(i_ctx_p, &) ws 2 index wt
385
	 (, \(const char *\)s_, ) ws length wt (\);) wl
386
	 (\tif ( code < 0 ) return code;) wl
387
	 wap (}) wl true
388
	 wtempname deletefile
389
       }
390
     }
391
	% Default
392
     { { pop true }
393
       { wother }
394
     }
395
   ] def
396
 
397
% Write a named dictionary.  We assume the ref is already declared.
398
   /wd		% <name> <dict> <extra> wd -
399
    { 3 1 roll
400
      ({) ws
401
      (\tref v_[) ws dup length wt (];) wl
402
      dup [ exch
403
       { counttomark 2 sub wtstring cvs
404
         (v_[) exch concatstrings (]) concatstrings exch wo not
405
          { (Skipping ) print ==only (....\n) print }
406
	 if
407
       } forall
408
      ]
409
		% Stack: array of keys (names)
410
      ({) ws dup (str_keys_) exch wsna
411
      (\tstatic const cfont_dict_keys keys_ =) wl
412
      (\t { 0, 0, ) ws length wt (, ) ws 3 -1 roll wt (, ) ws
413
      dup wpa (, ) ws dup wva ( };) wl pop
414
      (\tcode = \(*pprocs->ref_dict_create\)\(i_ctx_p, &) ws wt
415
      (, &keys_, \(const char *\)str_keys_, v_\);) wl
416
      (\tif ( code < 0 ) return code;) wl
417
      (}) wl
418
      (}) wl
419
    } bind def
420
 
421
% Write character dictionary keys.
422
% We save a lot of space by abbreviating keys which appear in
423
% StandardEncoding or ISOLatin1Encoding.
424
% Writes code to declare and initialize enc_keys_, str_keys, and keys_.
425
/wcdkeys	% <dict> wcdkeys -
426
 {	% Write keys present in StandardEncoding or ISOLatin1Encoding,
427
	% pushing other keys on the o-stack.
428
   (static const charindex enc_keys_[] = {) wl
429
   dup [ exch 0 exch
430
    { pop decoding 1 index known
431
       { decoding exch get ({) ws dup -8 bitshift wt
432
	 (,) ws 255 and wt (}, ) ws
433
	 1 add dup 5 mod 0 eq { (\n) ws } if
434
       }
435
       { exch }
436
      ifelse
437
    }
438
   forall pop
439
   ]
440
   ({0,0}\n};) wl
441
	% Write other keys.
442
   (str_keys_) exch wsna
443
	% Write the declaration for keys_.
444
   (static const cfont_dict_keys keys_ = {) wl
445
   (\tenc_keys_, countof\(enc_keys_\) - 1,) wl
446
   (\t) ws dup length wt ( - \(countof\(enc_keys_\) - 1\), 0, ) ws
447
   dup wpa (, ) ws wva () wl
448
   (};) wl
449
 } bind def
450
 
451
% Enumerate character dictionary values in the same order that
452
% the keys appear in enc_keys_ and str_keys_.
453
% <proc> is called with each value in turn.
454
/cdforall	% <dict> <proc> cdforall -
455
 { 2 copy
456
    { decoding 3 index known
457
       { 3 -1 roll pop exec }
458
       { pop pop pop }
459
      ifelse
460
    }
461
   /exec cvx 3 packedarray cvx
462
   /forall cvx
463
   5 -2 roll
464
    { decoding 3 index known
465
       { pop pop pop }
466
       { 3 -1 roll pop exec }
467
      ifelse
468
    }
469
   /exec cvx 3 packedarray cvx
470
   /forall cvx
471
   6 packedarray cvx exec
472
 } bind def
473
 
474
% ------ Writers for special objects ------ %
475
 
476
/writespecial 10 dict dup begin
477
 
478
   /FontInfo { 0 wd } def
479
 
480
   /Private { 0 wd } def
481
 
482
   /CharStrings
483
    { ({) wl
484
      dup wcdkeys
485
      (static const unsigned char values_[] = {) wl
486
       { wsn } cdforall
487
      (\t0\n};) wl
488
      (\tcode = \(*pprocs->string_dict_create\)\(i_ctx_p, &) ws wt
489
      (, &keys_, (const char *)str_keys_, \(const char *\)values_\);) wl
490
      (\tif ( code < 0 ) return code;) wl
491
      (}) wl
492
    } bind def
493
 
494
   /Metrics
495
    { ({) wl
496
      dup wcdkeys
497
      (static const ref_(float) values_[] = {) wl
498
      dup { (\t) ws wnums () wl } cdforall
499
      (\t0\n};) wl
500
      (static const unsigned char lengths_[] = {) wl
501
       { (\t) ws dup isnumber
502
	  { pop 0 }
503
	  { length 1 add }
504
	 ifelse wt (,) wl
505
       } cdforall
506
      (\t0\n};) wl
507
      (\tcode = \(*pprocs->num_dict_create\)\(i_ctx_p, &) ws wt
508
      (, &keys_, str_keys_, (const ref *)values_, lengths_\);) wl
509
      (\tif ( code < 0 ) return code;) wl
510
      (}) wl
511
    } bind def
512
 
513
   /Metrics2 /Metrics load def
514
 
515
   /FDepVector pop	% (converted to a list of font names)
516
 
517
end def
518
 
519
% ------ The main program ------ %
520
 
521
% Construct an inverse dictionary of encodings.
522
[ /StandardEncoding /ISOLatin1Encoding
523
  /SymbolEncoding /DingbatsEncoding
524
  /KanjiSubEncoding
525
]
526
dup length dict begin
527
 { mark exch dup { .findencoding exch def } stopped cleartomark
528
 } forall
529
currentdict end /encodingnames exch def
530
 
531
% Invert the StandardEncoding and ISOLatin1Encoding vectors.
532
512 dict begin
533
 
534
 
535
currentdict end /decoding exch def
536
 
537
/writefont		% cfilename procname -> [writes the current font]
538
 { (gsf_) exch concatstrings
539
     /fontprocname exch def
540
   /cfname exch def
541
   /cfile cfname (w) file def
542
 
543
% Remove unwanted keys from the font.
544
   currentfont dup length dict begin { def } forall
545
    { /FID /MIDVector /CurMID } { currentdict exch undef } forall
546
   /Font currentdict end def
547
 
548
% Replace the FDepVector with a list of font names.
549
   Font /FDepVector .knownget
550
    { [ exch { /FontName get } forall ]
551
      Font /FDepVector 3 -1 roll put
552
    }
553
   if
554
 
555
% Find all the special objects we know about.
556
% wo uses this to write out references to otherwise intractable objects.
557
   /otherobjs writespecial length dict dup begin
558
     writespecial
559
      { pop Font 1 index .knownget { exch def } { pop } ifelse
560
      }
561
     forall
562
   end def
563
 
564
% Define a dummy FontInfo, in case the font doesn't have one.
565
   /FontInfo 0 dict def
566
 
567
% Write out the boilerplate.
568
   Font begin
569
   (/****************************************************************) wl
570
   (   Portions of this file are subject to the following notice(s):) wl
571
   systemdict /copyright get wl
572
   FontInfo /Notice .knownget
573
    { (----------------------------------------------------------------) wl wl
574
    } if
575
   (****************************************************************/) wl
576
   () wl
577
   (/* ) ws cfname ws ( */) wl
578
   (/* This file was created by the ) ws product ws ( font2c utility. */) wl
579
   () wl
580
   (#undef DEBUG) wl
581
   (#include "ccfont.h") wl
582
   () wl
583
 
584
% Write the procedure prologue.
585
   (#ifdef __PROTOTYPES__) wl
586
   (ccfont_proc\() ws fontprocname ws (\);) wl
587
   (int) wl
588
   fontprocname ws ((i_ctx_t *i_ctx_p, const cfont_procs *pprocs, ref *pfont)) wl
589
   (#else) wl
590
   (int) wl
591
   fontprocname ws ((i_ctx_p, pprocs, pfont) i_ctx_t *i_ctx_p; const cfont_procs *pprocs; ref *pfont;) wl
592
   (#endif) wl
593
   ({\tint code;) wl
594
   (\tref Font;) wl
595
   otherobjs
596
    { exch pop (\tref ) ws wt (;) wl }
597
   forall
598
 
599
% Write out the special objects.
600
   otherobjs
601
    { exch writespecial 2 index get exec
602
    }
603
   forall
604
 
605
% Write out the main font dictionary.
606
% If possible, substitute the encoding name for the encoding;
607
% PostScript code will fix this up.
608
    { /Encoding /PrefEnc }
609
    { Font 1 index .knownget
610
       { encodingnames exch .knownget { def } { pop } ifelse }
611
       { pop }
612
      ifelse
613
    }
614
   forall
615
   (Font) Font FontType 0 eq { 5 } { 1 } ifelse wd
616
 
617
% Finish the procedural initialization code.
618
   (\t*pfont = Font;) wl
619
   (\treturn 0;) wl
620
   (}) wl
621
   end				% Font
622
 
623
   cfile closefile
624
 
625
 } bind def
626
 
627
end def			% font2cdict
628
 
629
% Compute the procedure name from the font name.
630
% Replace all non-alphanumeric characters with '_'.
631
/makefontprocnamemap 256 string
632
 
633
   (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
634
    { 2 copy dup put pop } forall
635
readonly def
636
/makefontprocname	% <fontname> makefontprocname <procnamestring>
637
 { dup length string cvs
638
   dup length 1 sub -1 0
639
    {		% Stack: string index
640
      2 copy 2 copy get //makefontprocnamemap exch get put pop
641
    }
642
   for 
643
 } def
644
 
645
/writefont { font2cdict begin writefont end } def
646
 
647
% If the program was invoked from the command line, run it now.
648
[ shellarguments
649
 { counttomark dup 2 eq exch 3 eq or
650
    { counttomark -1 roll cvn
651
      (Converting ) print dup =only ( font.\n) print flush
652
		% Ensure that we get a clean copy of the font from the
653
		% file system.
654
      2 {	% do both local and global
655
	currentglobal not setglobal
656
	dup undefinefont
657
      } repeat
658
      findfont setfont
659
      (FontName is ) print currentfont /FontName get ==only (.\n) print flush
660
      counttomark 1 eq
661
       {	% Construct the procedure name from the file name.
662
         currentfont /FontName get makefontprocname
663
       }
664
      if
665
      writefont
666
      (Done.\n) print flush
667
    }
668
    { cleartomark
669
      (Usage: font2c fontname cfilename.c [shortname]\n) print
670
      ( e.g.: font2c Courier cour.c\n) print flush
671
      mark
672
    }
673
   ifelse
674
 }
675
if pop