home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / GhostScript / !GhostScr / 6_01 / lib / gs_cff.ps < prev    next >
Text File  |  2000-03-29  |  19KB  |  621 lines

  1. %    Copyright (C) 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
  2. % This file is part of Aladdin Ghostscript.
  3. % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  4. % or distributor accepts any responsibility for the consequences of using it,
  5. % or for whether it serves any particular purpose or works at all, unless he
  6. % or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  7. % License (the "License") for full details.
  8. % Every copy of Aladdin Ghostscript must include a copy of the License,
  9. % normally in a plain ASCII text file named PUBLIC.  The License grants you
  10. % the right to copy, modify and redistribute Aladdin Ghostscript, but only
  11. % under certain conditions described in the License.  Among other things, the
  12. % License requires that the copyright notice and this notice be preserved on
  13. % all copies.
  14.  
  15. % $Id: gs_cff.ps,v 1.1 2000/03/09 08:40:39 lpd Exp $
  16. % Loader for CFF (compressed) fonts.
  17. % The following are not implemented yet:
  18. %    Deleted entries in the Name Index
  19. %    Embedded PostScript
  20. %    Multiple Master fonts
  21. %    CIDFonts
  22. %    Chameleon fonts
  23. %    Synthetic fonts
  24. % Also, Type 2 charstrings are converted into FontType 2 fonts,
  25. % which may or may not be supported.
  26.  
  27. 30 dict begin
  28.  
  29. % ---------------- Standard strings (actually names) ---------------- %
  30.  
  31. /StandardStrings mark
  32. % 0
  33.   /.notdef /space /exclam /quotedbl /numbersign
  34.   /dollar /percent /ampersand /quoteright /parenleft
  35.   /parenright /asterisk /plus /comma /hyphen
  36.   /period /slash /zero /one /two
  37.   /three /four /five /six /seven
  38.   /eight /nine /colon /semicolon /less
  39.   /equal /greater /question /at /A
  40.   /B /C /D /E /F
  41.   /G /H /I /J /K
  42.   /L /M /N /O /P
  43. % 50
  44.   /Q /R /S /T /U
  45.   /V /W /X /Y /Z
  46.   /bracketleft /backslash /bracketright /asciicircum /underscore
  47.   /quoteleft /a /b /c /d
  48.   /e /f /g /h /i
  49.   /j /k /l /m /n
  50.   /o /p /q /r /s
  51.   /t /u /v /w /x
  52.   /y /z /braceleft /bar /braceright
  53.   /asciitilde /exclamdown /cent /sterling /fraction
  54. % 100
  55.   /yen /florin /section /currency /quotesingle
  56.   /quotedblleft /guillemotleft /guilsinglleft /guilsinglright /fi
  57.   /fl /endash /dagger /daggerdbl /periodcentered
  58.   /paragraph /bullet /quotesinglbase /quotedblbase /quotedblright
  59.   /guillemotright /ellipsis /perthousand /questiondown /grave
  60.   /acute /circumflex /tilde /macron /breve
  61.   /dotaccent /dieresis /ring /cedilla /hungarumlaut
  62.   /ogonek /caron /emdash /AE /ordfeminine
  63.   /Lslash /Oslash /OE /ordmasculine /ae
  64.   /dotlessi /lslash /oslash /oe /germandbls
  65. % 150
  66.   /onesuperior /logicalnot /mu /trademark /Eth
  67.   /onehalf /plusminus /Thorn /onequarter /divide
  68.   /brokenbar /degree /thorn /threequarters /twosuperior
  69.   /registered /minus /eth /multiply /threesuperior
  70.   /copyright /Aacute /Acircumflex /Adieresis /Agrave
  71.   /Aring /Atilde /Ccedilla /Eacute /Ecircumflex
  72.   /Edieresis /Egrave /Iacute /Icircumflex /Idieresis
  73.   /Igrave /Ntilde /Oacute /Ocircumflex /Odieresis
  74.   /Ograve /Otilde /Scaron /Uacute /Ucircumflex
  75.   /Udieresis /Ugrave /Yacute /Ydieresis /Zcaron
  76. % 200
  77.   /aacute /acircumflex /adieresis /agrave /aring
  78.   /atilde /ccedilla /eacute /ecircumflex /edieresis
  79.   /egrave /iacute /icircumflex /idieresis /igrave
  80.   /ntilde /oacute /ocircumflex /odieresis /ograve
  81.   /otilde /scaron /uacute /ucircumflex /udieresis
  82.   /ugrave /yacute /ydieresis /zcaron /exclamsmall
  83.   /Hungarumlautsmall /dollaroldstyle /dollarsuperior /ampersandsmall /Acutesmall
  84.   /parenleftsuperior /parenrightsuperior /twodotenleader /onedotenleader /zerooldstyle
  85.   /oneoldstyle /twooldstyle /threeoldstyle /fouroldstyle /fiveoldstyle
  86.   /sixoldstyle /sevenoldstyle /eightoldstyle /nineoldstyle /commasuperior
  87. % 250
  88.   /threequartersemdash /periodsuperior /questionsmall /asuperior /bsuperior
  89.   /centsuperior /dsuperior /esuperior /isuperior /lsuperior
  90.   /msuperior /nsuperior /osuperior /rsuperior /ssuperior
  91.   /tsuperior /ff /ffi /ffl /parenleftinferior
  92.   /parenrightinferior /Circumflexsmall /hyphensuperior /Gravesmall /Asmall
  93.   /Bsmall /Csmall /Dsmall /Esmall /Fsmall
  94.   /Gsmall /Hsmall /Ismall /Jsmall /Ksmall
  95.   /Lsmall /Msmall /Nsmall /Osmall /Psmall
  96.   /Qsmall /Rsmall /Ssmall /Tsmall /Usmall
  97.   /Vsmall /Wsmall /Xsmall /Ysmall /Zsmall
  98. % 300
  99.   /colonmonetary /onefitted /rupiah /Tildesmall /exclamdownsmall
  100.   /centoldstyle /Lslashsmall /Scaronsmall /Zcaronsmall /Dieresissmall
  101.   /Brevesmall /Caronsmall /Dotaccentsmall /Macronsmall /figuredash
  102.   /hypheninferior /Ogoneksmall /Ringsmall /Cedillasmall /questiondownsmall
  103.   /oneeighth /threeeighths /fiveeighths /seveneighths /onethird
  104.   /twothirds /zerosuperior /foursuperior /fivesuperior /sixsuperior
  105.   /sevensuperior /eightsuperior /ninesuperior /zeroinferior /oneinferior
  106.   /twoinferior /threeinferior /fourinferior /fiveinferior /sixinferior
  107.   /seveninferior /eightinferior /nineinferior /centinferior /dollarinferior
  108.   /periodinferior /commainferior /Agravesmall /Aacutesmall /Acircumflexsmall
  109. % 350
  110.   /Atildesmall /Adieresissmall /Aringsmall /AEsmall /Ccedillasmall
  111.   /Egravesmall /Eacutesmall /Ecircumflexsmall /Edieresissmall /Igravesmall
  112.   /Iacutesmall /Icircumflexsmall /Idieresissmall /Ethsmall /Ntildesmall
  113.   /Ogravesmall /Oacutesmall /Ocircumflexsmall /Otildesmall /Odieresissmall
  114.   /OEsmall /Oslashsmall /Ugravesmall /Uacutesmall /Ucircumflexsmall
  115.   /Udieresissmall /Yacutesmall /Thornsmall /Ydieresissmall (001.000)
  116.   (001.001) (001.002) (001.003) /Black /Bold
  117.   /Book /Light /Medium /Regular /Roman
  118.   /Semibold
  119. .packtomark def
  120.  
  121. % ---------------- Standard encodings ---------------- %
  122.  
  123. /StandardEncodings [
  124.  
  125. % StandardEncoding
  126. mark
  127.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  128.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  129.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  130.   17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  131.   33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  132.   49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  133.   65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  134.   81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0
  135.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  136.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  137.   0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
  138.   0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123
  139.   0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136
  140.   137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  141.   0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0
  142.   0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0
  143. .packtomark
  144.  
  145. % ExpertEncoding
  146. mark
  147.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  148.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  149.   1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99
  150.   239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252
  151.   0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262
  152.   0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272
  153.   273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  154.   289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0
  155.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  156.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  157.   0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313
  158.   0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319
  159.   320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330
  160.   331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
  161.   347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
  162.   363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
  163. .packtomark
  164.  
  165. ] readonly def
  166.  
  167. % ---------------- Standard Charsets ---------------- %
  168.  
  169. % We include an explicit 0 at the beginning of each charset.
  170.  
  171. /StandardCharsets [
  172.  
  173. % ISOAdobe
  174. mark
  175.   0
  176.   1 1 228 { } for
  177. .packtomark
  178.  
  179. % Expert
  180. mark
  181.   0
  182.   1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239
  183.   240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253
  184.   254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267
  185.   268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
  186.   284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  187.   300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  188.   316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164
  189.   169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
  190.   342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  191.   358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  192.   374 375 376 377 378
  193. .packtomark
  194.  
  195. % ExpertSubset
  196. mark
  197.   0
  198.   1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243
  199.   244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258
  200.   259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300
  201.   301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150
  202.   164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  203.   341 342 343 344 345 346
  204. .packtomark
  205.  
  206. ] readonly def
  207.  
  208. % ---------------- Font loading ---------------- %
  209.  
  210. % ------ Utilities ------ %
  211.  
  212. /advance {    % <n> advance -
  213.   f cff eq { /pos pos 3 -1 roll add store } { pop } ifelse
  214. } def
  215. /next {        % - next <byte>
  216.   f read {
  217.     1 advance
  218.     DEBUG { (  ) print dup = } if
  219.   } if
  220. } def
  221. /nextstring {    % <length> nextstring <string>
  222.   dup 0 eq {
  223.     pop ()
  224.   } {
  225.     string f exch readstring pop dup length advance
  226.     DEBUG { (  ) print dup == } if
  227.   } ifelse
  228. } def
  229. /card8        % - card8 <card8>
  230.  /next load
  231. def
  232. /card16 {    % - card16 <card16>
  233.   card8 8 bitshift card8 add
  234. } def
  235. /offset {    % <offsize> offset <offset>
  236.   0 exch { 8 bitshift next add } repeat
  237. } def
  238. /sid        % - <sid> sid
  239.   /card16 load
  240. def
  241. /Index {    % - Index <array>
  242.   mark card16 dup 0 ne {
  243.     1 exch next dup offset pop exch {
  244.       dup offset dup 4 -1 roll sub 3 1 roll exch
  245.     } repeat pop
  246.   } if pop .packtomark
  247.   [ exch { nextstring } forall ] readonly
  248. } def
  249. /tokens {    % - tokens <num1> ... <op#> (op# = 12 means EOF)
  250.   {
  251.     f read not { 12 exit } if
  252.     DEBUG { (..) print dup = } if
  253.     1 advance
  254.     dup 12 eq { pop next 32 add exit } if
  255.     dup 28 lt { exit } if
  256.     dup 32 lt {
  257.       28 sub {
  258.     { card16 32768 xor 32768 sub }
  259.     { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if }
  260.     { tokenreal }
  261.     { 31 exit }
  262.       } exch get exec
  263.     } {
  264.       dup 247 lt {
  265.     139 sub
  266.       } {
  267.     247 sub {
  268.       { next 108 add }
  269.       { next 364 add }
  270.       { next 620 add }
  271.       { next 876 add }
  272.       { next 108 add neg }
  273.       { next 364 add neg }
  274.       { next 620 add neg }
  275.       { next 876 add neg }
  276.       % 255 is deliberately omitted and will cause a rangecheck
  277.     } exch get exec
  278.       } ifelse
  279.     } ifelse
  280.   } loop
  281. } def
  282. /tokenbuf 100 string def
  283. /tokenput {    % <index> <char> tokenput <index+1>
  284.   tokenbuf 2 index 3 -1 roll put 1 add
  285. } def
  286. /tokenrealarray [
  287.  (0123456789.E) { } forall
  288.  [(E) 0 get /tokenput cvx (-) 0 get] cvx
  289.  null        % will give an error
  290.  (-) 0 get
  291.  { exit }
  292. ] readonly def
  293. /tokenreal {    % - tokenreal <float>
  294.   0 {
  295.     next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput
  296.         % We must leave the byte on the stack temporarily so that
  297.         % the exit will see a consistent stack state.
  298.     1 index 15 and tokenrealarray exch get exec tokenput exch pop
  299.   } loop
  300.   tokenbuf 0 3 -1 roll getinterval cvr exch pop
  301. } def
  302. /Dict {        % <opsdict> Dict -
  303.   /opdict exch store {
  304.     mark tokens
  305.     DEBUG { (tokens: ) print ] dup === mark exch aload pop } if
  306.     opdict exch .knownget { exec } if cleartomark
  307.   } loop cleartomark
  308. } def
  309. /idstring {    % <sid> idstring <string|name>
  310.   dup 391 lt { StandardStrings } { 391 sub strings } ifelse exch get
  311. } def
  312. /idname {    % <sid> idname <name>
  313.   idstring dup type /nametype ne { cvn } if
  314. } def
  315. /subfilefilter {    % <file> <length> subfilefilter <filter>
  316.     % SubFileDecode interprets a length of 0 as infinite.
  317.   dup 0 le { pop pop () 0 } if () /SubFileDecode filter
  318. } def
  319.  
  320. % ------ Top dictionary ------ %
  321.  
  322. /offput {    % <offset> <proc> offput -
  323.   DEBUG { (queued: ) print 1 index =only ( ) print dup === } if
  324.   currentdict exch aload length 1 add packedarray cvx
  325.   offsets 3 1 roll put
  326. } def
  327. /queueput {    % <font> <proc> queueput -
  328.   16#7fffffff offsets { pop .min } forall
  329.   pos sub nextstring
  330.   3 1 roll aload length 2 add packedarray cvx
  331.   [ queued aload pop counttomark 2 add -1 roll ]
  332.   /queued exch store
  333. } def
  334. /xxput {    % <value> <key> <dict> xxput -
  335.   3 1 roll exch put
  336. } def
  337. /putfi {    % <value> <key> putfi -
  338.   FontInfo xxput
  339. } def
  340. /xdef {        % <value> <key> xdef -
  341.   exch def
  342. } def
  343. /topdictops mark
  344.   12 { exit }
  345.   0 { idstring /version putfi }
  346.   1 { idstring /Notice putfi }
  347.   32 { idstring /Copyright putfi }
  348.   2 { idstring /FullName putfi }
  349.   3 { idstring /FamilyName putfi }
  350.   4 { idstring /Weight putfi }
  351.   33 { 0 ne /isFixedPitch putfi }
  352.   34 { /ItalicAngle putfi }
  353.   35 { /UnderlinePosition putfi }
  354.   36 { /UnderlineThickness putfi }
  355.   37 { /PaintType xdef }
  356.   38 { /FontType xdef }        % actually CharstringType
  357.   39 { counttomark array astore /FontMatrix xdef }
  358.   13 { /UniqueID xdef }
  359.   5 { counttomark array astore /FontBBox xdef }
  360.   40 { /StrokeWidth xdef }
  361.   14 { counttomark array astore /XUID xdef }
  362.   15 {
  363.     dup StandardCharsets length lt {
  364.       StandardCharsets exch get /charset xdef
  365.     } {
  366.       { queuecharset } offput
  367.     } ifelse
  368.   }
  369.   16 {
  370.     dup StandardEncodings length lt {
  371.       /Encoding xdef
  372.     } {
  373.       { queueEncoding } offput
  374.     } ifelse
  375.   }
  376.   17 { { readCharStrings } offput }
  377.   18 { exch /readPrivate cvx 2 packedarray offput }
  378. .dicttomark readonly def
  379.  
  380. /readCharStrings {    % <font> readCharStrings -
  381.   /CharStringArray Index put
  382. } def
  383.  
  384. % ------ Charsets and encodings ------ %
  385.  
  386. % Note: formats 1 and 2 can overflow the operand stack.
  387. % We'll fix this if it ever becomes necessary.
  388. /charsetformats [
  389. { [ 0 CharStringArray length 1 sub { sid } repeat ]
  390. }
  391. { [ 0 CharStringArray length 1 sub {
  392.     dup 0 eq { pop exit } if
  393.     sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  394.   } loop ]
  395. }
  396. { [ 0 CharStringArray length 1 sub {
  397.     dup 0 eq { pop exit } if
  398.     sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  399.   } loop ]
  400. }
  401. ] readonly def
  402. /queuecharset {        % <font> queuecharset -
  403.   { readcharset } queueput
  404. } def
  405. /readcharset {        % <data> <font> readcharset -
  406.   begin 0 () /SubFileDecode filter /f exch store
  407.   charsetformats next get exec /charset exch def end
  408. } def
  409.  
  410. /encodingformats [
  411. { 1 1 next { next exch Encoding 3 1 roll put } for
  412. }
  413. { 1 next {
  414.     next next 1 add {
  415.             % Stack: gid code
  416.       Encoding 1 index 3 index put
  417.       exch 1 add exch 1 add
  418.     } repeat pop
  419.   } repeat pop
  420. }
  421. ] readonly def
  422. /queueEncoding {    % <font> queueEncoding -
  423.   { readEncoding } queueput
  424. } def
  425. /readEncoding {        % <data> <font> readEncoding -
  426.   begin 0 () /SubFileDecode filter /f exch store
  427.   /Encoding [ 256 { /.notdef } repeat ] def
  428.   next encodingformats 1 index 127 and get exec
  429.   128 ge {
  430.             % Read supplementary encodings.
  431.     next {
  432.       Encoding next sid idname put
  433.     } repeat
  434.   } if end
  435. } def
  436.  
  437. % ------ Private dictionary ------ %
  438.  
  439. /deltarray {        % -mark- <num1> ... deltarray <num1'> ...
  440.   0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop
  441.   counttomark array astore
  442. } def
  443.  
  444. /privatedictops mark
  445.   12 { exit }
  446.   6 { deltarray /BlueValues xdef }
  447.   7 { deltarray /OtherBlues xdef }
  448.   8 { deltarray /FamilyBlues xdef }
  449.   9 { deltarray /FamilyOtherBlues xdef }
  450.   41 { /BlueScale xdef }
  451.   42 { /BlueShift xdef }
  452.   43 { /BlueFuzz xdef }
  453.   10 { 1 array astore /StdHW xdef }
  454.   11 { 1 array astore /StdVW xdef }
  455.   44 { deltarray /StemSnapH xdef }
  456.   45 { deltarray /StemSnapV xdef }
  457.   46 { 0 ne /ForceBold xdef }
  458.   47 { /ForceBoldThreshold xdef }
  459.   48 { /lenIV xdef }
  460.   49 { /LanguageGroup xdef }
  461.   50 { /ExpansionFactor xdef }
  462.   51 { /initialRandomSeed xdef }
  463.   19 { { readSubrs } offput }
  464.   20 { /defaultWidthX xdef }
  465.   21 { /nominalWidthX xdef }
  466.     % Multiple Master fonts only
  467.   59 { /NDV xdef }
  468.   60 { /CDV xdef }
  469.   61 { /lenBuildCharArray xdef }
  470. .dicttomark readonly def
  471.  
  472. /readPrivate {        % <font> <size> readPrivate -
  473.   exch 1 index f exch subfilefilter /f exch def
  474.   /Private get begin //privatedictops Dict end
  475.   /f cff def advance
  476. } def
  477.  
  478. % ------ Main program ------ %
  479.  
  480. % We need to pass the file as a parameter for the sake of the PDF
  481. % interpreter.
  482. /StartData {        % <resname> <nbytes> StartData -
  483.   currentfile exch subfilefilter ReadData
  484. } def
  485. /ReadData {        % <resname> <file> ReadData -
  486.  
  487.     % Initialize.
  488.  
  489.   30 dict begin
  490.   /cff exch def
  491.   /pos 0 def
  492.   /resname exch cvlit def
  493.  
  494.     % Read the header.
  495.  
  496.   /f cff def
  497.   /vmajor next def
  498.   /vminor next def
  499.   /hdrsize next def
  500.   /aoffsize next def
  501.  
  502.     % Read the Indexes.
  503.  
  504.   /names Index def
  505.   /topdicts Index def
  506.   /strings Index def
  507.   /gsubrs Index def
  508.  
  509.     % Read the top Dicts.
  510.  
  511.   /offsets 50 dict def
  512.   /queued [] def
  513.   /opdict null def        % reserve a slot
  514.   /fonts [ topdicts {
  515.     0 () /SubFileDecode filter /f exch def
  516.     40 dict begin
  517.         % Preload defaults that differ from PostScript defaults,
  518.         % or that are required.
  519.       /FontType 2 def
  520.       /PaintType 0 def
  521.       /FontMatrix [0.001 0 0 0.001 0 0] def
  522.       /charset StandardCharsets 0 get def
  523.       /Encoding 0 def
  524.       /FontInfo 10 dict
  525.     dup /UnderlinePosition -100 put
  526.     dup /UnderlineThickness 50 put
  527.       def
  528.       /Private 20 dict
  529.     gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if
  530.       def
  531.       //topdictops Dict
  532.     currentdict end
  533.   } forall ] def
  534.  
  535.     % Read other tables with queued offsets.
  536.  
  537.   DEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
  538.   { /f cff def
  539.     DEBUG { (pos=) print pos = } if
  540.     offsets pos 2 copy .knownget not { pop pop exit } if
  541.     3 1 roll undef exec
  542.   } loop
  543.   offsets length 0 ne {
  544.     (Error: missing tables at ) print [ offsets { pop } forall ] ==
  545.     (Current position is ) print pos ==
  546.     flush stop
  547.   } if
  548.  
  549.     % Process out-of-order tables.
  550.  
  551.   DEBUG { queued length =only ( queued) = flush } if
  552.   queued { exec } forall
  553.  
  554.     % Update Encoding and CharStrings.
  555.  
  556.   fonts {
  557.     begin
  558.         % Construct the real Encoding.
  559.         % The value of Encoding is either a number, for predefined
  560.         % encodings, or an array of mixed GIDs and names.
  561.       /Encoding mark Encoding
  562.       DEBUG { (Encoding: ) print dup === flush } if
  563.       dup type /integertype eq {
  564.     StandardEncodings exch get { idname } forall
  565.       } {
  566.     {
  567.       dup type /integertype eq { charset exch get idname } if
  568.         } forall
  569.       } ifelse .packtomark def
  570.         % Construct the CharStrings.
  571.         % Note that they may only correspond to an initial
  572.         % subset of the charset.
  573.       /CharStrings charset length CharStringArray length .min dict def
  574.       DEBUG {
  575.     charset length =only ( charset ) print
  576.     CharStringArray length =only ( CharStringArray) =
  577.     charset == flush
  578.       } if
  579.       0 1 CharStrings maxlength 1 sub {
  580.     dup CharStringArray exch get
  581.     exch charset exch get idstring
  582.     CharStrings xxput
  583.       } for
  584.         % Remove unwanted entries.
  585.       currentdict /charset undef
  586.       currentdict /CharStringArray undef
  587.     end
  588.   } forall
  589.  
  590.     % Wrap up.
  591.  
  592.   resname mark 0 1 fonts length 1 sub {
  593.     DEBUG { dup =only ( ) print flush } if
  594.     dup names exch get
  595.     DEBUG { dup == flush } if
  596.     exch fonts exch get
  597.     dup /FontName 3 index put
  598.     1 index exch definefont
  599.   } for .dicttomark
  600.   end        % temporary dict
  601.   end        % FontSetInit ProcSet
  602.   /FontSet defineresource pop
  603.  
  604. } bind def
  605.  
  606. % ---------------- Resource category definition ---------------- %
  607.  
  608. currentdict end readonly
  609.  
  610. languagelevel exch 2 .setlanguagelevel
  611.  
  612. /FontSet /Generic /Category findresource dup length dict .copydict
  613. /Category defineresource pop
  614.  
  615. /FontSetInit exch /ProcSet defineresource pop
  616.  
  617. .setlanguagelevel
  618.