font2c.ps 19 KB

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