home *** CD-ROM | disk | FTP | other *** search
/ jppd.dyndns.org / jppd.dyndns.org.tar / jppd.dyndns.org / QUERYPRO / Impressora_PDF / converter.exe / GPLGS / gs_cff.ps < prev    next >
Text File  |  2003-04-13  |  23KB  |  773 lines

  1. %    Copyright (C) 1997, 1998, 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2. % This software is provided AS-IS with no warranty, either express or
  3. % implied.
  4. % This software is distributed under license and may not be copied,
  5. % modified or distributed except as expressly authorized under the terms
  6. % of the license contained in the file LICENSE in this distribution.
  7. % For more information about licensing, please refer to
  8. % http://www.ghostscript.com/licensing/. For information on
  9. % commercial licensing, go to http://www.artifex.com/licensing/ or
  10. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. % San Rafael, CA  94903, U.S.A., +1(415)492-9861.
  12.  
  13. % $Id: gs_cff.ps,v 1.17 2003/04/12 18:08:18 ray Exp $
  14. % Loader for CFF (compressed) fonts, including OpenType CFFs.
  15. % The following are not implemented yet:
  16. %    Deleted entries in the Name Index
  17. %    Embedded PostScript
  18. %    Multiple Master fonts
  19. %    Chameleon fonts
  20. %    Synthetic fonts
  21.  
  22. % ---------------- Font loading machinery ---------------- %
  23.  
  24. % Augment the FONTPATH machinery so it recognizes OpenType CFF font sets.
  25.  
  26. /.scanfontheaders where {
  27.   pop /.scanfontheaders [
  28.    .scanfontheaders aload pop (OTTO*)
  29.   ] def
  30. } if
  31.  
  32. % Load a font file that might be an OpenType CFF font set.
  33.  
  34. % <file> .loadfontfile -
  35. /.loadnonottofontfile /.loadfontfile load def
  36. /.loadfontfile {
  37.   dup 4 string .peekstring pop (OTTO) eq {
  38.         % If this is a font at all, it's an OpenType CFF font set.
  39.     .loadottofontfile
  40.   } {
  41.         % Not a TrueType font.
  42.     .loadnonottofontfile
  43.   } ifelse
  44. } bind def
  45.  
  46. % <file> .loadottofontfile -
  47. /.loadottofontfile {
  48.   /FontSetInit /ProcSet findresource begin
  49.   2 dict begin
  50.   /f exch def /cff null def
  51.   card32 pop card16 6 { next pop } repeat dup {
  52.         % Stack: numtables tablesleft
  53.     dup 0 eq {
  54.       pop pop /.loadottofontfile cvx /invalidfont signalerror
  55.     } if
  56.     f 4 string readstring pop (CFF ) eq { sub exit } if
  57.     f 12 string readstring pop pop 1 sub    % skip to next table
  58.   } loop
  59.         % Stack: tablesread
  60.   card32 pop card32 card32
  61.         % Stack: tablesread start length
  62.   exch 3 -1 roll 1 add 16 mul 12 add sub
  63.   f exch subfilefilter flushfile    % skip to start
  64.   f exch subfilefilter end
  65.     % Use a random FontSet resource name.  ****** WRONG ******
  66.   realtime rand xor =string cvs exch false
  67.   ReadData
  68. } bind def
  69.  
  70. 30 dict begin
  71.  
  72. % ---------------- Standard strings (actually names) ---------------- %
  73.  
  74. /StandardStrings mark
  75.     % The initial StandardStrings that that denote characters are
  76.     % defined as a pseudo-Encoding.
  77. % 0
  78.   /CFFStandardStrings .findencoding aload pop
  79. % 379
  80.   (001.000)
  81. % 380
  82.   (001.001) (001.002) (001.003) /Black /Bold
  83.   /Book /Light /Medium /Regular /Roman
  84.   /Semibold
  85. .packtomark def
  86.  
  87. % ---------------- Standard encodings ---------------- %
  88.  
  89. /StandardEncodings [
  90.  
  91. % StandardEncoding
  92. mark
  93.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  94.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  95.   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  96.   17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
  97.   33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
  98.   49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
  99.   65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
  100.   81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0
  101.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  102.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  103.   0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
  104.   0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123
  105.   0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136
  106.   137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  107.   0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0
  108.   0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0
  109. .packtomark
  110.  
  111. % ExpertEncoding
  112. mark
  113.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  114.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  115.   1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99
  116.   239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252
  117.   0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262
  118.   0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272
  119.   273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  120.   289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0
  121.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  122.   0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  123.   0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313
  124.   0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319
  125.   320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330
  126.   331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
  127.   347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
  128.   363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
  129. .packtomark
  130.  
  131. ] readonly def
  132.  
  133. % ---------------- Standard Charsets ---------------- %
  134.  
  135. % We include an explicit 0 at the beginning of each charset.
  136.  
  137. /StandardCharsets [
  138.  
  139. % ISOAdobe
  140. mark
  141.   0
  142.   1 1 228 { } for
  143. .packtomark
  144.  
  145. % Expert
  146. mark
  147.   0
  148.   1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239
  149.   240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253
  150.   254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267
  151.   268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
  152.   284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
  153.   300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  154.   316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164
  155.   169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
  156.   342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  157.   358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  158.   374 375 376 377 378
  159. .packtomark
  160.  
  161. % ExpertSubset
  162. mark
  163.   0
  164.   1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243
  165.   244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258
  166.   259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300
  167.   301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150
  168.   164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340
  169.   341 342 343 344 345 346
  170. .packtomark
  171.  
  172. ] readonly def
  173.  
  174. % ---------------- Font loading ---------------- %
  175.  
  176. % ------ Utilities ------ %
  177.  
  178. /advance {    % <n> advance -
  179.   f cff eq { pos add /pos exch store } { pop } ifelse
  180. } bind def
  181. /next {        % - next <byte>
  182.   f read {
  183.     1 advance
  184.     CFFDEBUG { (  ) print dup = } if
  185.   } if
  186. } bind def
  187. /next2 {    % - next2 <byte1> <byte2>
  188.   f read {
  189.     f read {
  190.       2 advance
  191.       CFFDEBUG { (  ) print 1 index =only (,) print dup = } if
  192.     } {
  193.       1 advance
  194.       CFFDEBUG { (  ) print dup = } if
  195.     } ifelse
  196.   } if
  197. } bind def
  198. /nextstring {    % <length> nextstring <string>
  199.   dup 0 eq {
  200.     pop ()
  201.   } {
  202.     string f exch readstring pop dup length advance
  203.     CFFDEBUG { (  ) print dup == } if
  204.   } ifelse
  205. } bind def
  206. /card8        % - card8 <card8>
  207.  /next load
  208. def
  209. /card16 {    % - card16 <card16>
  210.   next2 exch 8 bitshift add
  211. } bind def
  212. /card32 {    % - card32 <card32>
  213.   card16 16 bitshift card16 add
  214. } bind def
  215. /offsetprocs [
  216.   /card8 load
  217.   /card16 load
  218.   { card8 16 bitshift card16 add } bind
  219.   /card32 load
  220. ] readonly def
  221. /offsetproc {    % <offsize> offsetproc <proc>
  222.   1 sub //offsetprocs exch get
  223. } bind def
  224. /offset {    % <offsize> offset <offset>
  225.   offsetproc exec
  226. } bind def
  227. /sid        % - <sid> sid
  228.   /card16 load
  229. def
  230. /Index {    % <name> Index <name> <array>
  231.   CFFDEBUG { (% reading Index: ) print dup = } if
  232.   mark card16 dup 0 ne {
  233.     1 exch next offsetproc dup exec pop exch {
  234.       dup exec dup 4 -1 roll sub 3 1 roll exch
  235.     } repeat pop
  236.   } if pop .packtomark
  237.   CFFDEBUG { (% Index lengths = ) print dup === } if
  238.   [ exch { nextstring } forall ] readonly
  239. } bind def
  240. /tokens {    % - tokens <num1> ... <op#> (op# = 12 means EOF)
  241.   {
  242.     f read not { 12 exit } if
  243.     CFFDEBUG { (..) print dup = } if
  244.     1 advance
  245.     dup 12 eq { pop next 32 add exit } if
  246.     dup 28 lt { exit } if
  247.     dup 32 lt {
  248.       28 sub {
  249.     { card16 32768 xor 32768 sub }
  250.     { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if }
  251.     { tokenreal }
  252.     { 31 exit }
  253.       } exch get exec
  254.     } {
  255.       dup 247 lt {
  256.     139 sub
  257.       } {
  258.     247 sub {
  259.       { next 108 add }
  260.       { next 364 add }
  261.       { next 620 add }
  262.       { next 876 add }
  263.       { next 108 add neg }
  264.       { next 364 add neg }
  265.       { next 620 add neg }
  266.       { next 876 add neg }
  267.       % 255 is deliberately omitted and will cause a rangecheck
  268.     } exch get exec
  269.       } ifelse
  270.     } ifelse
  271.   } loop
  272. } bind def
  273. /tokenbuf 100 string def
  274. /tokenput {    % <index> <char> tokenput <index+1>
  275.   tokenbuf 2 index 3 -1 roll put 1 add
  276. } bind def
  277. /tokenrealarray [
  278.  (0123456789.E) { } forall
  279.  [(E) 0 get /tokenput cvx (-) 0 get] cvx
  280.  null        % will give an error
  281.  (-) 0 get
  282.  { exit }
  283. ] readonly def
  284. /tokenreal {    % - tokenreal <float>
  285.   0 {
  286.     next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput
  287.         % We must leave the byte on the stack temporarily so that
  288.         % the exit will see a consistent stack state.
  289.     1 index 15 and tokenrealarray exch get exec tokenput exch pop
  290.   } loop
  291.   tokenbuf 0 3 -1 roll getinterval cvr exch pop
  292. } bind def
  293. /Dict {        % <opsdict> Dict -
  294.   /opdict exch store {
  295.     mark tokens
  296.     CFFDEBUG { (tokens: ) print ] dup === mark exch aload pop } if
  297.     opdict exch .knownget { exec } if cleartomark
  298.   } loop cleartomark
  299. } bind def
  300. /idstring {    % <sid> idstring <string|name>
  301.   dup 391 lt { //StandardStrings } { 391 sub strings } ifelse exch get
  302. } bind def
  303. /idname {    % <sid> idname <name>
  304.   idstring dup type /nametype ne { cvn } if
  305. } bind def
  306. /subfilefilter {    % <file> <length> subfilefilter <filter>
  307.     % SubFileDecode interprets a length of 0 as infinite.
  308.   dup 0 le { pop pop () 0 } if () /SubFileDecode filter
  309. } bind def
  310.  
  311. % ------ Top dictionary ------ %
  312.  
  313. /offput {    % <offset> <proc> offput -
  314.   CFFDEBUG { (queued: ) print 1 index =only ( ) print dup === } if
  315.   currentdict exch aload length 1 add packedarray cvx
  316.   offsets 3 1 roll put
  317. } bind def
  318. /queueput {    % <font> <proc> queueput -
  319.   16#7fffffff offsets { pop .min } forall
  320.   pos sub nextstring
  321.   3 1 roll aload length 2 add packedarray cvx
  322.   [ queued aload pop counttomark 2 add -1 roll ]
  323.   /queued exch store
  324. } bind def
  325. /printvk {    % <value> <key> printvk <value> <key>
  326.   CFFDEBUG { (\t% ) print dup =only ( = ) print 1 index === } if
  327. } bind def
  328. /xxput {    % <value> <key> <dict> xxput -
  329.   3 1 roll exch put
  330. } bind def
  331. /putfi {    % <value> <key> putfi -
  332.   printvk FontInfo xxput
  333. } bind def
  334. /xdef {        % <value> <key> xdef -
  335.   exch def
  336. } bind def
  337. /pxdef {    % <value> <key> pxdef -
  338.   printvk xdef
  339. } bind def
  340. /topdictops mark
  341.   12 { CFFDEBUG { (\t% EOD) = } if exit }
  342.   0 { idstring /version putfi }
  343.   1 { idstring /Notice putfi }
  344.   32 { idstring /Copyright putfi }
  345.   2 { idstring /FullName putfi }
  346.   3 { idstring /FamilyName putfi }
  347.   4 { idstring /Weight putfi }
  348.   33 { 0 ne /isFixedPitch putfi }
  349.   34 { /ItalicAngle putfi }
  350.   35 { /UnderlinePosition putfi }
  351.   36 { /UnderlineThickness putfi }
  352.   37 { /PaintType pxdef }
  353.   38 { /FontType pxdef }        % actually CharstringType
  354.   39 { counttomark array astore /FontMatrix pxdef }
  355.   13 { /UniqueID pxdef }
  356.   5 { counttomark array astore /FontBBox pxdef }
  357.   40 { /StrokeWidth pxdef }
  358.   14 { counttomark array astore /XUID pxdef }
  359.   15 {
  360.     /charset printvk pop
  361.     dup StandardCharsets length lt {
  362.       StandardCharsets exch get /charset xdef
  363.     } {
  364.       { queuecharset } offput
  365.     } ifelse
  366.   }
  367.   16 {
  368.     /Encoding printvk pop
  369.     dup StandardEncodings length lt {
  370.       /Encoding xdef
  371.     } {
  372.       { queueEncoding } offput
  373.     } ifelse
  374.   }
  375.   17 { { readCharStrings } offput }
  376.   18 { exch /readPrivate cvx 2 packedarray offput }
  377.     % CIDFont operators
  378.   62 {        % ROS, must be first in a CIDFont
  379.     currentdict /FontType undef
  380.     currentdict /Encoding undef
  381.     currentdict /FontMatrix undef
  382.     /CIDFontVersion 0 def
  383.     /CIDFontRevision 0 def
  384.     /CIDFontType 0 def
  385.     /CIDCount 8720 def % Default value defined in CFF spec.
  386.     3 dict begin
  387.     /Supplement pxdef
  388.     idstring /Ordering pxdef
  389.     idstring /Registry pxdef
  390.     /CIDSystemInfo currentdict end def
  391.   }
  392.   63 { /CIDFontVersion pxdef }
  393.   64 { /CIDFontRevision pxdef }
  394.   65 { /CIDFontType pxdef }
  395.   66 { /CIDCount pxdef }
  396.   67 { /UIDBase pxdef }
  397.   68 { { readFDArray } offput }
  398.   69 { { readFDSelect } offput }
  399.     % This operator only appears in a FDArray element.
  400.   70 { idstring /FontName pxdef }
  401. .dicttomark readonly def
  402.  
  403. % readcharset and readFDSelect may require the length of CharStringArray,
  404. % but these structures may occur in the file before the CharStrings.
  405. % If that happens, use a hack: assume that all the data up to the next
  406. % queued read should be read.
  407.  
  408. /charstringcount {    % <font> charstringcount <count> true
  409.             % <font> charstringcount <length> false
  410.   /CharStringArray .knownget {
  411.     length true
  412.   } {
  413.     % Hack: look for the next queued read.
  414.     16#7fffffff offsets { pop .min } forall
  415.     pos sub false
  416.   } ifelse
  417. } bind def
  418.  
  419. /readCharStrings {    % <font> readCharStrings -
  420.   /CharStringArray Index put
  421. } bind def
  422.  
  423. % ------ Charsets and encodings ------ %
  424.  
  425. % Note: formats 1 and 2 can overflow the operand stack.
  426. % We'll fix this if it ever becomes necessary.
  427. /charsetcount {
  428.   charstringcount { 1 sub } { 2 idiv } ifelse
  429. } bind def
  430. /charsetformats [
  431. { [ 0 3 -1 roll charsetcount { sid } repeat ]
  432. } bind
  433. { [ 0 3 -1 roll charsetcount {
  434.     dup 0 eq { pop exit } if
  435.     sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  436.   } loop ]
  437. } bind
  438. { [ 0 3 -1 roll charsetcount {
  439.     dup 0 eq { pop exit } if
  440.     sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
  441.   } loop ]
  442. } bind
  443. ] readonly def
  444. /queuecharset {        % <font> queuecharset -
  445.   { readcharset } queueput
  446. } bind def
  447. /readcharset {        % <data> <font> readcharset -
  448.   begin 0 () /SubFileDecode filter /f exch store
  449.   charsetformats next get currentdict exch exec /charset exch def end
  450. } bind def
  451.  
  452. /encodingformats [
  453. { 1 1 next { next exch Encoding 3 1 roll put } for
  454. } bind
  455. { 1 next {
  456.     next next 1 add {
  457.             % Stack: gid code
  458.       Encoding 1 index 3 index put
  459.       exch 1 add exch 1 add
  460.     } repeat pop
  461.   } repeat pop
  462. } bind
  463. ] readonly def
  464. /queueEncoding {    % <font> queueEncoding -
  465.   { readEncoding } queueput
  466. } bind def
  467. /readEncoding {        % <data> <font> readEncoding -
  468.   begin 0 () /SubFileDecode filter /f exch store
  469.   /Encoding [ 256 { /.notdef } repeat ] def
  470.   next encodingformats 1 index 127 and get exec
  471.   128 ge {
  472.             % Read supplementary encodings.
  473.     next {
  474.       Encoding next sid idname put
  475.     } repeat
  476.   } if end
  477. } bind def
  478.  
  479. % ------ FDArray and FDSelect ------ %
  480.  
  481. /readFDArray {        % <font> readFDArray -
  482.   /FDarray Index exch pop exch
  483.   2 dict begin /f null def begin
  484.   [ exch {
  485.     dup length subfilefilter /f exch store
  486.     10 dict begin
  487.     /FontType 2 def
  488.     /PaintType 0 def
  489.     /FontMatrix [0.001 0 0 0.001 0 0] def
  490.     /Private 20 dict def
  491.     //topdictops Dict currentdict end
  492.   } forall ] /FDArray xdef end end
  493. } bind def
  494.  
  495. /fdselectformats [
  496. % Note: this procedure can overflow the operand stack.
  497. % We'll fix this if it ever becomes necessary.
  498. { [ exch charstringcount pop { card8 } repeat ] } bind    % Format 0
  499. { /FDSelect cvx /invalidfont signalerror } bind        % Format 1
  500. dup                            % Format 2
  501. % The following procedure does not use excessive op-stack space.
  502. { pop 65535 array card16 card16 exch            % Format 3
  503.   { % Stack: array previndex
  504.     card8 card16 
  505.     exch 1 index 4 -1 roll
  506.     exch 1 exch 1 sub
  507.     { 3 index exch 2 index put } for pop
  508.   } repeat
  509.   % now resize the array to the final index.
  510.   0 exch getinterval
  511. } bind
  512. ] readonly def
  513.  
  514. /readFDSelect {        % <font> readFDSelect -
  515.   begin fdselectformats next get currentdict exch exec /FDSelect exch def end
  516. } bind def
  517.  
  518.  
  519. % ------ Private dictionary ------ %
  520.  
  521. /deltarray {        % -mark- <num1> ... deltarray <num1'> ...
  522.   0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop
  523.   counttomark array astore
  524. } bind def
  525.  
  526. /privatedictops mark
  527.   12 { CFFDEBUG { (\t% EOD) = } if exit }
  528.   6 { deltarray /BlueValues pxdef }
  529.   7 { deltarray /OtherBlues pxdef }
  530.   8 { deltarray /FamilyBlues pxdef }
  531.   9 { deltarray /FamilyOtherBlues pxdef }
  532.   41 { /BlueScale pxdef }
  533.   42 { /BlueShift pxdef }
  534.   43 { /BlueFuzz pxdef }
  535.   10 { 1 array astore /StdHW pxdef }
  536.   11 { 1 array astore /StdVW pxdef }
  537.   44 { deltarray /StemSnapH pxdef }
  538.   45 { deltarray /StemSnapV pxdef }
  539.   46 { 0 ne /ForceBold pxdef }
  540.   47 { /ForceBoldThreshold pxdef }
  541.   48 { /lenIV pxdef }
  542.   49 { /LanguageGroup pxdef }
  543.   50 { /ExpansionFactor pxdef }
  544.   51 { /initialRandomSeed pxdef }
  545.   19 { PrivateStart add { readSubrs } offput }
  546.   20 { /defaultWidthX pxdef }
  547.   21 { /nominalWidthX pxdef }
  548.     % Multiple Master fonts only
  549.   59 { /NDV pxdef }
  550.   60 { /CDV pxdef }
  551.   61 { /lenBuildCharArray pxdef }
  552. .dicttomark readonly def
  553.  
  554. /readPrivate {        % <font> <size> readPrivate -
  555.   2 dict begin
  556.   /PrivateStart pos def
  557.   f 3 1 roll exch 1 index f exch subfilefilter /f exch store
  558.   dup /FontType get exch
  559.   /Private get begin
  560.         % Default lenIV to -1 even for Type 1 CharStrings.
  561.   2 ne { /lenIV -1 def } if
  562.   //privatedictops Dict end
  563.   exch /f exch store advance
  564.   end
  565. } bind def
  566.  
  567. /readSubrs {        % <font> readSubrs -
  568.   /Subrs Index put
  569. } bind def
  570.  
  571. % ------ Main program ------ %
  572.  
  573. % Clean up after finishing a font.
  574. /cleanupFont {        % (currentdict) cleanupFont -
  575.         % Remove unwanted entries.
  576.   currentdict /charset undef
  577.   currentdict /CharStringArray undef
  578. } bind def
  579.  
  580. % Update the Encoding and CharStrings for a real font.
  581. /finishFont {        % (currentdict) finishFont -
  582.         % Construct the real Encoding.
  583.         % The value of Encoding is either a number, for predefined
  584.         % encodings, or an array of mixed GIDs and names.
  585.   /Encoding mark Encoding
  586.   CFFDEBUG { (Encoding: ) print dup === flush } if
  587.   dup type /integertype eq {
  588.     StandardEncodings exch get { idname } forall
  589.   } {
  590.     {
  591.       dup type /integertype eq { charset exch get idname } if
  592.     } forall
  593.   } ifelse .packtomark def
  594.         % Construct the CharStrings.
  595.         % Note that they may only correspond to an initial
  596.         % subset of the charset.
  597.   /CharStrings charset length CharStringArray length .min dict def
  598.   CFFDEBUG {
  599.     charset length =only ( charset ) print
  600.     CharStringArray length =only ( CharStringArray) =
  601.     charset == flush
  602.   } if
  603.   0 1 CharStrings maxlength 1 sub {
  604.     dup CharStringArray exch get
  605.     exch charset exch get idstring CharStrings xxput
  606.   } for
  607.   cleanupFont
  608. } bind def
  609.  
  610. % Replace CharStrings with GlyphDirectory for a CIDFont;
  611. % Move GlobalSubrs to descendent fonts.
  612. /finishCIDFont {    % (currentdict) finishCIDFont -
  613.         % Construct the GlyphDirectory, similar to CharStrings.
  614.   /FDBytes FDArray length 1 gt { 1 } { 0 } ifelse def
  615.   /GlyphDirectory charset length CharStringArray length .min dict def
  616.   CFFDEBUG {
  617.     charset length =only ( charset ) print
  618.     CharStringArray length =only ( CharStringArray) =
  619.     charset == flush
  620.   } if
  621.   0 1 GlyphDirectory maxlength 1 sub {
  622.     dup CharStringArray exch get
  623.         % If there is more than one FDArray entry, add the font
  624.         % index to the beginning of each charstring.
  625.     FDBytes 1 eq {
  626.       FDSelect 2 index get
  627.       1 string dup 0 4 -1 roll put exch concatstrings
  628.     } if
  629.     exch charset exch get GlyphDirectory xxput
  630.   } for
  631.  
  632.   Private /GlobalSubrs .knownget {
  633.     FDArray {
  634.     /Private get /GlobalSubrs 2 index put
  635.     } forall
  636.     pop
  637.     Private /GlobalSubrs undef
  638.   } if
  639.  
  640.         % Clean up.
  641.   currentdict /FDSelect undef
  642.   cleanupFont
  643. } bind def
  644. % We need to pass the file as a parameter for the sake of the PDF
  645. % interpreter. Also for the sake of PDF, a flag forces the font
  646. % to be defined as <resname> instead of the name embedded in the data.
  647. % This is needed for subsetted fonts; it is valid if the CFF
  648. % contains only a single font.
  649. /StartData {          % <resname> <nbytes> StartData -
  650.   currentfile exch subfilefilter false ReadData
  651. } bind def
  652. /ReadData {           % <resname> <file> <forceresname> ReadData -
  653.  
  654.     % Initialize.
  655.  
  656.   30 dict begin
  657.   /forceresname exch def
  658.   /cff exch def
  659.   /pos 0 def
  660.   /resname exch cvlit def
  661.   /DEBUG CFFDEBUG def    % bring the binding closer
  662.  
  663.     % Read the header.
  664.  
  665.   /f cff def
  666.   /vmajor next def
  667.   /vminor next def
  668.   /hdrsize next def
  669.   /aoffsize next def
  670.  
  671.     % Read the Indexes.
  672.  
  673.   /names Index def
  674.   /topdicts Index def
  675.   /strings Index def
  676.   /gsubrs Index def
  677.  
  678.     % Read the top Dicts.
  679.  
  680.   /offsets 50 dict def
  681.   /queued [] def
  682.   /opdict null def        % reserve a slot
  683.   /fonts [ topdicts {
  684.     0 () /SubFileDecode filter /f exch def
  685.     40 dict begin
  686.         % Preload defaults that differ from PostScript defaults,
  687.         % or that are required.
  688.       /FontType 2 def
  689.       /PaintType 0 def
  690.       /FontMatrix [0.001 0 0 0.001 0 0] def
  691.       /charset StandardCharsets 0 get def
  692.       /Encoding 0 def
  693.       /FontInfo 10 dict
  694.     dup /UnderlinePosition -100 put
  695.     dup /UnderlineThickness 50 put
  696.       def
  697.       /Private 20 dict
  698.     gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if
  699.       def
  700.       //topdictops Dict
  701.     currentdict end
  702.   } forall ] def
  703.  
  704.     % Read other tables with queued offsets.
  705.  
  706.   CFFDEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
  707.   { /f cff def
  708.     CFFDEBUG { (pos=) print pos = } if
  709.     offsets pos 2 copy .knownget not { pop pop exit } if
  710.     3 1 roll undef
  711.     CFFDEBUG { (exec queued: ) print dup == } if
  712.     exec
  713.   } loop
  714.   offsets length 0 ne {
  715.     QUIET not {
  716.       (Error reading the CFF font ) print resname =string cvs print ( : missing tables at ) print [ offsets { pop } forall ] ==
  717.       (Current position is ) print pos ==
  718.     } if
  719.   } if
  720.  
  721.     % Process out-of-order tables.
  722.  
  723.   CFFDEBUG { queued length =only ( queued) = flush } if
  724.   queued { exec } forall
  725.  
  726.     % Update Encoding and CharStrings.
  727.  
  728.   fonts {
  729.     begin
  730.     currentdict /CIDFontType known { finishCIDFont } { finishFont } ifelse
  731.     end
  732.   } forall
  733.  
  734.     % Wrap up.
  735.  
  736.   resname mark 0 1 fonts length 1 sub {
  737.     CFFDEBUG { dup =only ( ) print flush } if
  738.     dup names exch get
  739.     forceresname { pop resname } if
  740.     CFFDEBUG { dup == flush } if
  741.     exch fonts exch get
  742.     dup /CIDFontType known {
  743.         % This is a CIDFont.
  744.       dup /CIDFontName 3 index put
  745.       1 index exch /CIDFont defineresource
  746.     } {
  747.         % This is a font.
  748.       dup /FontName 3 index put
  749.       1 index exch definefont
  750.     } ifelse
  751.   } for .dicttomark
  752.   end        % temporary dict
  753.   end        % FontSetInit ProcSet
  754.   /FontSet defineresource pop
  755.  
  756. } bind def
  757.  
  758. % ---------------- Resource category definition ---------------- %
  759.  
  760. currentdict end readonly
  761.  
  762. languagelevel exch 2 .setlanguagelevel
  763.  
  764. /FontSet /Generic /Category findresource dup length dict .copydict
  765. /Category defineresource pop
  766.  
  767. /FontSetInit exch /ProcSet defineresource pop
  768.  
  769. .setlanguagelevel
  770.