wrfont.ps 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. % Copyright (C) 1991, 1995, 1996 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: wrfont.ps,v 1.2 2000/09/19 18:29:11 lpd Exp $
  18. % wrfont.ps
  19. % Write out a Type 1 font in readable, reloadable form.
  20. % Note that this does NOT work on protected fonts, such as Adobe fonts
  21. % (unless you have loaded unprot.ps first, in which case you may be
  22. % violating the Adobe license).
  23. % ****** NOTE: This file must be kept consistent with gs_pfile.ps.
  24. /wrfont_dict 100 dict def
  25. wrfont_dict begin
  26. % ------ Options ------ %
  27. % Define whether to use eexec encryption for the font.
  28. % eexec encryption is only useful for compatibility with Adobe Type Manager
  29. % and other programs; it only slows Ghostscript down.
  30. /eexec_encrypt false def
  31. % Define whether to write out the CharStrings in binary or in hex.
  32. % Binary takes less space on the file, but isn't guaranteed portable.
  33. /binary_CharStrings false def
  34. % Define whether to use binary token encodings when possible.
  35. % Binary tokens are smaller and load faster, but are a Level 2 feature.
  36. /binary_tokens false def
  37. % Define whether to encrypt the CharStrings on the file. (CharStrings
  38. % are always encrypted in memory.) Unencrypted CharStrings load about
  39. % 20% slower, but make the files compress much better for transport.
  40. /encrypt_CharStrings true def
  41. % Define whether the font must provide standard PostScript language
  42. % equivalents for any facilities it uses that are provided in Ghostscript
  43. % but are not part of the standard PostScript language.
  44. /standard_only true def
  45. % Define the value of lenIV to use in writing out the font.
  46. % use_lenIV = 0 produces the smallest output, but this may not be
  47. % compatible with old Adobe interpreters. use_lenIV = -1 means
  48. % use the value of lenIV from the font.
  49. /use_lenIV -1 def
  50. % Define whether to produce the smallest possible output, relying
  51. % as much as possible on Ghostscript-specific support code.
  52. % Taking full advantage of this requires the following settings:
  53. % binary_CharStrings = true, binary_tokens = true, standard_only = false.
  54. /smallest_output false def
  55. % Define whether to write out all currently known Encodings by name,
  56. % or only StandardEncoding and ISOLatin1Encoding.
  57. /name_all_Encodings false def
  58. % ---------------- Runtime support ---------------- %
  59. /.packedfilefilter where
  60. { pop }
  61. { (gs_pfile.ps) runlibfile }
  62. ifelse
  63. % ------ Output utilities ------ %
  64. % By convention, the output file is named psfile.
  65. % Define some utilities for writing the output file.
  66. /wtstring 2000 string def
  67. /wb {psfile exch write} bind def
  68. /wnb {/wb load repeat} bind def
  69. /w1 {psfile exch write} bind def
  70. /ws {psfile exch writestring} bind def
  71. /wl {ws (\n) ws} bind def
  72. /wt {wtstring cvs ws ( ) ws} bind def
  73. /wd % Write a dictionary.
  74. { dup length wo {dict dup begin} wol { we } forall
  75. {end} wol
  76. } bind def
  77. /wld % Write a large dictionary more efficiently.
  78. % Ignore the readonly attributes.
  79. { dup length wo {dict dup begin} wol
  80. 0 exch
  81. { exch wo wo () wl
  82. 1 add dup 200 eq
  83. { wo ({def} repeat) wl 0 }
  84. if
  85. }
  86. forall
  87. dup 0 ne
  88. { wo ({def} repeat) wl }
  89. { pop }
  90. ifelse
  91. (end) ws
  92. } bind def
  93. /we % Write a dictionary entry.
  94. { exch wo wo /def cvx wo (\n) ws
  95. } bind def
  96. /wcs % Write a CharString (or Subrs entry)
  97. { dup type /stringtype eq
  98. { 4330 exch changelenIV 0 ge
  99. { % Add some leading garbage bytes.
  100. wtstring changelenIV 2 index length getinterval
  101. .type1decrypt exch pop
  102. wtstring exch 0 exch length changelenIV add getinterval
  103. }
  104. { % Drop some leading garbage bytes.
  105. wtstring .type1decrypt exch pop
  106. changelenIV neg 1 index length 1 index sub getinterval
  107. }
  108. ifelse
  109. binary_tokens encrypt_CharStrings and
  110. { % Suppress recognizing the readonly status of the string.
  111. 4330 exch dup .type1encrypt exch pop wo
  112. }
  113. { encrypt_CharStrings
  114. { 4330 exch dup .type1encrypt exch pop
  115. } if
  116. smallest_output
  117. { wo
  118. }
  119. { readonly dup length wo
  120. binary_tokens not { ( ) ws } if
  121. readproc ws wx
  122. }
  123. ifelse
  124. }
  125. ifelse
  126. }
  127. { wo % PostScript procedure
  128. }
  129. ifelse
  130. } bind def
  131. % Construct the inversion of the system name table.
  132. /SystemNames where
  133. { pop /snit 256 dict def
  134. 0 1 255
  135. { dup SystemNames exch get
  136. dup null ne { exch snit 3 1 roll put } { pop pop } ifelse
  137. }
  138. for
  139. }
  140. { /snit 1 dict def
  141. }
  142. ifelse
  143. % Write an object, using binary tokens if requested and possible.
  144. /woa % write in ascii
  145. { psfile exch write==only
  146. } bind def
  147. % Lookup table for ASCII output.
  148. /intbytes % int nbytes -> byte*
  149. { { dup 255 and exch -8 bitshift } repeat pop
  150. } bind def
  151. /wotta 10 dict dup begin
  152. { /booleantype /integertype }
  153. { { ( ) ws woa } def }
  154. forall
  155. % Iterate over arrays so we can print operators.
  156. /arraytype
  157. { dup xcheck {(}) ({)} {(]) ([)} ifelse ws exch dup wol exch ws wop
  158. } bind def
  159. /dicttype
  160. { ( ) ws wd } def
  161. /nametype
  162. { dup xcheck { ( ) ws } if woa
  163. } bind def
  164. % Map back operators to their names,
  165. % so we can write procedures.
  166. /nulltype
  167. { pop ( null) ws
  168. } bind def
  169. /operatortype
  170. { wtstring cvs cvn cvx wo
  171. } bind def
  172. % Convert reals to integers if possible.
  173. /realtype
  174. { dup cvi 1 index eq { cvi wo } { ( ) ws woa } ifelse
  175. } bind def
  176. % == truncates strings longer than 200 characters!
  177. /stringtype
  178. { (\() ws dup
  179. { dup dup 32 lt exch 127 ge or
  180. { (\\) ws dup -6 bitshift 48 add w1
  181. dup -3 bitshift 7 and 48 add w1
  182. 7 and 48 add
  183. }
  184. { dup dup -2 and 40 eq exch 92 eq or {(\\) ws} if
  185. }
  186. ifelse w1
  187. }
  188. forall
  189. (\)) ws wop
  190. } bind def
  191. /packedarraytype
  192. { ([) ws dup { wo } forall
  193. encodingnames 1 index known
  194. % This is an encoding, but not one of the standard ones.
  195. % Use the built-in encoding only if it is available.
  196. { encodingnames exch get wo
  197. ({findencoding}stopped{pop) ws
  198. (}{counttomark 1 add 1 roll cleartomark}ifelse)
  199. }
  200. { pop ()
  201. }
  202. ifelse
  203. (/packedarray where{pop counttomark packedarray exch pop}{]readonly}ifelse) ws
  204. wl
  205. }
  206. def
  207. end def
  208. % Lookup table for binary output.
  209. /wottb 8 dict dup begin
  210. wotta currentdict copy pop
  211. /integertype
  212. { dup dup 127 le exch -128 ge and
  213. { 136 wb 255 and wb }
  214. { dup dup 32767 le exch -32768 ge and
  215. { 134 wb 2 intbytes wb wb }
  216. { 132 wb 4 intbytes wb wb wb wb }
  217. ifelse
  218. }
  219. ifelse
  220. } bind def
  221. /nametype
  222. { dup snit exch known
  223. { dup xcheck { 146 } { 145 } ifelse wb
  224. snit exch get wb
  225. }
  226. { wotta /nametype get exec
  227. }
  228. ifelse
  229. } bind def
  230. /stringtype
  231. { dup dup length dup 255 le { 142 2 } { 2 intbytes 143 3 } ifelse wnb
  232. ws wop
  233. } bind def
  234. end def
  235. /wop % Write object protection
  236. { wcheck not { /readonly cvx wo } if
  237. } bind def
  238. /wo % Write an object.
  239. { dup type binary_tokens { wottb } { wotta } ifelse
  240. exch get exec
  241. } bind def
  242. /wol % Write a list of objects.
  243. { { wo } forall
  244. } bind def
  245. % Write a hex string for Subrs or CharStrings.
  246. /wx % string ->
  247. { binary_CharStrings
  248. { ws
  249. }
  250. { % Some systems choke on very long lines, so
  251. % we break up the hexstring into chunks of 50 characters.
  252. { dup length 25 le {exit} if
  253. dup 0 25 getinterval psfile exch writehexstring (\n) ws
  254. dup length 25 sub 25 exch getinterval
  255. } loop
  256. psfile exch writehexstring
  257. } ifelse
  258. } bind def
  259. % ------ CharString encryption utilities ------ %
  260. /enc_dict 20 dict def
  261. 1 dict begin
  262. /bind { } def % make sure we can print out the procedures
  263. enc_dict begin
  264. (type1enc.ps) runlibfile
  265. enc_dict /.type1decrypt undef % we don't need this
  266. end end
  267. enc_dict { 1 index where { pop pop pop } { def } ifelse } forall
  268. % ------ Other utilities ------ %
  269. % Test whether two values are equal (for default dictionary entries).
  270. /valueeq % <obj1> <obj2> valueeq <bool>
  271. { 2 copy eq
  272. { pop pop true }
  273. { % Special hack for comparing FontMatrix values
  274. dup type /arraytype eq 2 index type /arraytype eq and
  275. { dup length 2 index length eq
  276. { true 0 1 3 index length 1 sub
  277. { % Stack: arr1 arr2 true index
  278. 3 index 1 index get 3 index 3 -1 roll get eq not
  279. { pop false exit }
  280. if
  281. }
  282. for 3 1 roll pop pop
  283. }
  284. { pop pop false
  285. }
  286. ifelse
  287. }
  288. { pop pop false
  289. }
  290. ifelse
  291. }
  292. ifelse
  293. } bind def
  294. % ------ The main program ------ %
  295. % Define the dictionary of keys to skip because they are treated specially.
  296. /.fontskipkeys mark
  297. /CharStrings dup
  298. /Encoding dup
  299. /FDepVector dup
  300. /FID dup
  301. /FontInfo dup
  302. /Metrics dup
  303. /Metrics2 dup
  304. /Private dup
  305. .dicttomark def
  306. /.minfontskipkeys mark
  307. .fontskipkeys { } forall
  308. /FontName dup
  309. /UniqueID dup
  310. .dicttomark def
  311. /.privateskipkeys mark
  312. /ND dup
  313. /NP dup
  314. /RD dup
  315. /Subrs dup
  316. .dicttomark def
  317. /.minprivateskipkeys mark
  318. .privateskipkeys { } forall
  319. /MinFeature dup
  320. /Password dup
  321. /UniqueID dup
  322. .dicttomark def
  323. % Define the procedures for the Private dictionary.
  324. % These must be defined without `bind',
  325. % for the sake of the DISKFONTS feature.
  326. 4 dict begin
  327. /-! {string currentfile exch readhexstring pop} def
  328. /-| {string currentfile exch readstring pop} def
  329. /|- {readonly def} def
  330. /| {readonly put} def
  331. currentdict end /encrypted_procs exch def
  332. 4 dict begin
  333. /-! {string currentfile exch readhexstring pop
  334. 4330 exch dup .type1encrypt exch pop} def
  335. /-| {string currentfile exch readstring pop
  336. 4330 exch dup .type1encrypt exch pop} def
  337. /|- {readonly def} def
  338. /| {readonly put} def
  339. currentdict end /unencrypted_procs exch def
  340. % Construct an inverse dictionary of encodings.
  341. /encodingnames mark
  342. StandardEncoding /StandardEncoding
  343. ISOLatin1Encoding /ISOLatin1Encoding
  344. SymbolEncoding /SymbolEncoding
  345. DingbatsEncoding /DingbatsEncoding
  346. /resourceforall where
  347. { pop (*) { cvn dup findencoding exch } 100 string /Encoding resourceforall }
  348. if
  349. .dicttomark def
  350. % Invert the standard encodings.
  351. .knownEncodings length 256 mul dict begin
  352. 0 .knownEncodings
  353. { { currentdict 1 index known { pop } { 1 index def } ifelse
  354. 1 add
  355. }
  356. forall
  357. }
  358. forall pop
  359. currentdict end /inverseencodings exch def
  360. /writefont % <psfile> writefont - (writes the current font)
  361. { /psfile exch def
  362. /Font currentfont def
  363. /FontInfo Font /FontInfo .knownget not { 0 dict } if def
  364. /FontType Font /FontType get def
  365. /hasPrivate Font /Private known def
  366. /Private hasPrivate { Font /Private get } { 0 dict } ifelse def
  367. /readproc binary_CharStrings { (-| ) } { (-! ) } ifelse def
  368. /privateprocs
  369. encrypt_CharStrings binary_tokens not and
  370. { encrypted_procs } { unencrypted_procs } ifelse
  371. def
  372. /addlenIV false def
  373. /changelenIV use_lenIV 0 lt
  374. { 0 }
  375. { use_lenIV Private /lenIV .knownget not
  376. { 4 /addlenIV use_lenIV 4 ne def } if sub }
  377. ifelse def
  378. /minimize
  379. smallest_output
  380. FontType 1 eq and
  381. Font /UniqueID known and
  382. def
  383. (%!FontType) ws FontType wtstring cvs ws (-1.0: ) ws
  384. currentfont /FontName get wt
  385. FontInfo /version .knownget not { (001.001) } if wl
  386. FontInfo /CreationDate .knownget { (%%Creation Date: ) ws wl } if
  387. FontInfo /VMusage .knownget
  388. { (%%VMusage: ) ws dup wt wtstring cvs wl }
  389. if
  390. (systemdict begin) wl
  391. % If we're going to use eexec, create the filters now.
  392. /realpsfile psfile def
  393. eexec_encrypt
  394. { /eexecfilter psfile binary_CharStrings not
  395. { pop /bxstring 35 string def
  396. { pop dup length 0 ne
  397. { realpsfile exch writehexstring realpsfile (\n) writestring }
  398. { pop }
  399. ifelse bxstring
  400. }
  401. /NullEncode filter dup /hexfilter exch def
  402. }
  403. if 55665 /eexecEncode filter def
  404. }
  405. if
  406. % Turn on binary tokens if relevant.
  407. binary_tokens { (currentobjectformat 1 setobjectformat) wl } if
  408. % If the file has a UniqueID, write out a check against loading it twice.
  409. minimize
  410. { Font /FontName get wo
  411. Font /UniqueID get wo
  412. Private length addlenIV { 1 add } if wo
  413. Font length 1 add wo % +1 for FontFile
  414. ( .checkexistingfont) wl
  415. }
  416. { Font /UniqueID known
  417. { ({} FontDirectory) ws Font /FontName get dup wo ( known) wl
  418. ( {) ws wo ( findfont dup /UniqueID known) wl
  419. ( { dup /UniqueID get) ws Font /UniqueID get wo ( eq exch /FontType get 1 eq and }) wl
  420. ( { pop false } ifelse) wl
  421. ( { pop save /restore load } if) wl
  422. ( } if) wl
  423. }
  424. if
  425. }
  426. ifelse
  427. % If we are writing unencrypted CharStrings for a standard environment,
  428. % write out the encryption procedures.
  429. privateprocs unencrypted_procs eq standard_only and
  430. { (systemdict /.type1encrypt known) wl
  431. ( { save /restore load } { { } } ifelse) wl
  432. (userdict begin) wl
  433. enc_dict { we } forall
  434. (end exec) wl
  435. }
  436. if
  437. % Write out the creation of the font dictionary and FontInfo.
  438. minimize not
  439. { Font length 1 add wo {dict begin} wol % +1 for FontFile
  440. }
  441. if
  442. (/FontInfo ) ws FontInfo wd {readonly def} wol
  443. % Write out the other fixed entries in the font dictionary.
  444. Font begin
  445. Font
  446. { minimize
  447. { .minfontskipkeys 2 index known
  448. { pop pop
  449. }
  450. { //.compactfontdefault 2 index .knownget
  451. { 1 index valueeq { pop pop } { we } ifelse }
  452. { we }
  453. ifelse
  454. }
  455. ifelse
  456. }
  457. { .fontskipkeys 2 index known { pop pop } { we } ifelse
  458. }
  459. ifelse
  460. } forall
  461. /Encoding
  462. encodingnames Encoding known
  463. name_all_Encodings
  464. Encoding StandardEncoding eq or
  465. Encoding ISOLatin1Encoding eq or and
  466. { encodingnames Encoding get cvx }
  467. { Encoding }
  468. ifelse
  469. dup /StandardEncoding cvx eq minimize and
  470. { pop pop }
  471. { we }
  472. ifelse
  473. % Write the FDepVector, if any.
  474. Font /FDepVector .knownget
  475. { {/FDepVector [} wol
  476. { /FontName get wo {findfont} wol () wl } forall
  477. {] readonly def} wol
  478. }
  479. if
  480. % Write out the Metrics, if any.
  481. Font /Metrics .knownget
  482. { (/Metrics ) ws wld {readonly def} wol
  483. }
  484. if
  485. Font /Metrics2 .knownget
  486. { (/Metrics2 ) ws wld {readonly def} wol
  487. }
  488. if
  489. % Start the eexec-encrypted section, if applicable.
  490. eexec_encrypt
  491. { {currentdict currentfile eexec} wol () wl
  492. /psfile eexecfilter store
  493. (\000\000\000\000) ws {begin} wol
  494. }
  495. if
  496. % Create and initialize the Private dictionary, if any.
  497. hasPrivate
  498. {
  499. Private
  500. minimize
  501. { begin {Private dup begin}
  502. }
  503. { dup length privateprocs length add dict copy begin
  504. privateprocs { readonly def } forall
  505. /Private wo
  506. currentdict length 1 add wo {dict dup begin}
  507. }
  508. ifelse wol () wl
  509. currentdict
  510. { 1 index minimize { .minprivateskipkeys } { .privateskipkeys } ifelse
  511. exch known
  512. { pop pop }
  513. { 1 index /lenIV eq use_lenIV 0 ge and { pop use_lenIV } if we }
  514. ifelse
  515. } forall
  516. addlenIV { /lenIV use_lenIV we } if
  517. }
  518. if
  519. % Write the Subrs entries, if any.
  520. currentdict /Subrs known
  521. { (/Subrs[) wl
  522. Subrs
  523. { dup null ne
  524. { wcs minimize not { () wl } if }
  525. { pop /null cvx wo }
  526. ifelse
  527. } forall
  528. {] dup {readonly pop} forall readonly def} wol () wl
  529. }
  530. if
  531. % Wrap up the Private dictionary.
  532. hasPrivate
  533. { end % Private
  534. minimize
  535. { {end readonly pop} } % Private
  536. { {end readonly def} } % Private in font
  537. ifelse wol
  538. }
  539. if
  540. % Write the CharStrings entries.
  541. % Detect identical (eq) entries, which bdftops produces.
  542. currentdict /CharStrings known
  543. {
  544. /CharStrings wo CharStrings length wo
  545. minimize
  546. { encrypt_CharStrings not wo ( .readCharStrings) wl
  547. CharStrings length dict
  548. CharStrings
  549. { exch inverseencodings 1 index .knownget not { dup } if wo
  550. % Stack: vdict value key
  551. 3 copy pop .knownget { wo pop pop } { 3 copy put pop wcs } ifelse
  552. } forall
  553. }
  554. { {dict dup Private begin begin} wol () wl
  555. CharStrings length dict
  556. CharStrings
  557. { 2 index 1 index known
  558. { exch wo 1 index exch get wo {load def} wol () wl
  559. }
  560. { 2 index 1 index 3 index put
  561. exch wo wcs ( |-) wl
  562. }
  563. ifelse
  564. } forall
  565. {end end} wol
  566. }
  567. ifelse
  568. pop
  569. { readonly def } % CharStrings in font
  570. wol
  571. }
  572. if
  573. % Terminate the output.
  574. end % Font
  575. eexec_encrypt
  576. { {end mark currentfile closefile} wol () wl
  577. eexecfilter dup flushfile closefile % psfile is eexecfilter
  578. binary_CharStrings not { hexfilter dup flushfile closefile } if
  579. /psfile realpsfile store
  580. 8
  581. { (0000000000000000000000000000000000000000000000000000000000000000)
  582. wl
  583. }
  584. repeat {cleartomark} wol
  585. }
  586. if
  587. { FontName currentdict end definefont pop
  588. }
  589. wol
  590. Font /UniqueID known { /exec cvx wo } if
  591. binary_tokens { /setobjectformat cvx wo } if
  592. ( end) wl % systemdict
  593. } bind def
  594. % ------ Other utilities ------ %
  595. % Prune garbage characters and OtherSubrs out of the current font,
  596. % if the relevant dictionaries are writable.
  597. /prunefont
  598. { currentfont /CharStrings get wcheck
  599. { currentfont /CharStrings get dup [ exch
  600. { pop dup (S????00?) .stringmatch not { pop } if
  601. } forall
  602. ] { 2 copy undef pop } forall pop
  603. }
  604. if
  605. } bind def
  606. end % wrfont_dict
  607. /writefont { wrfont_dict begin writefont end } def