wrfont.ps 18 KB

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