1
0

gs_cff.ps 21 KB

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