Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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