gs_cff.ps 22 KB

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