summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlgs/lib/gs_cff.ps
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlgs/lib/gs_cff.ps')
-rw-r--r--Master/tlpkg/tlgs/lib/gs_cff.ps779
1 files changed, 779 insertions, 0 deletions
diff --git a/Master/tlpkg/tlgs/lib/gs_cff.ps b/Master/tlpkg/tlgs/lib/gs_cff.ps
new file mode 100644
index 00000000000..6fcf80358f3
--- /dev/null
+++ b/Master/tlpkg/tlgs/lib/gs_cff.ps
@@ -0,0 +1,779 @@
+% Copyright (C) 1997, 1998, 1999, 2000 Aladdin Enterprises. All rights reserved.
+%
+% This software is provided AS-IS with no warranty, either express or
+% implied.
+%
+% This software is distributed under license and may not be copied,
+% modified or distributed except as expressly authorized under the terms
+% of the license contained in the file LICENSE in this distribution.
+%
+% For more information about licensing, please refer to
+% http://www.ghostscript.com/licensing/. For information on
+% commercial licensing, go to http://www.artifex.com/licensing/ or
+% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
+% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
+
+% $Id: gs_cff.ps 6883 2006-06-29 04:07:16Z alexcher $
+% Loader for CFF (compressed) fonts, including OpenType CFFs.
+% The following are not implemented yet:
+% Deleted entries in the Name Index
+% Embedded PostScript
+% Multiple Master fonts
+% Chameleon fonts
+% Synthetic fonts
+
+% ---------------- Font loading machinery ---------------- %
+
+% Augment the FONTPATH machinery so it recognizes OpenType CFF font sets.
+
+/.scanfontheaders where {
+ pop /.scanfontheaders [
+ .scanfontheaders aload pop (OTTO*)
+ ] def
+} if
+
+% Load a font file that might be an OpenType CFF font set.
+
+% <file> .loadfontfile -
+/.loadnonottofontfile /.loadfontfile load def
+/.loadfontfile {
+ dup 4 string .peekstring pop (OTTO) eq {
+ % If this is a font at all, it's an OpenType CFF font set.
+ .init_otto_font_file
+ % Use a random FontSet resource name. ****** WRONG ******
+ realtime rand xor =string cvs exch false
+ ReadData
+ } {
+ % Not a TrueType font.
+ .loadnonottofontfile
+ } ifelse
+} bind def
+
+% <file> .init_otto_font_file <file>
+/.init_otto_font_file {
+ /FontSetInit /ProcSet findresource begin
+ 2 dict begin
+ /f exch def /cff null def
+ card32 pop card16 6 { next pop } repeat dup {
+ % Stack: numtables tablesleft
+ dup 0 eq {
+ pop pop /.loadottofontfile cvx /invalidfont signalerror
+ } if
+ f 4 string readstring pop (CFF ) eq { sub exit } if
+ f 12 string readstring pop pop 1 sub % skip to next table
+ } loop
+ % Stack: tablesread
+ card32 pop card32 card32
+ % Stack: tablesread start length
+ exch 3 -1 roll 1 add 16 mul 12 add sub
+ f exch subfilefilter flushfile % skip to start
+ f exch subfilefilter end
+} bind def
+
+30 dict begin
+
+% ---------------- Standard strings (actually names) ---------------- %
+
+/StandardStrings mark
+ % The initial StandardStrings that that denote characters are
+ % defined as a pseudo-Encoding.
+% 0
+ /CFFStandardStrings .findencoding aload pop
+% 379
+ (001.000)
+% 380
+ (001.001) (001.002) (001.003) /Black /Bold
+ /Book /Light /Medium /Regular /Roman
+ /Semibold
+.packtomark def
+
+% ---------------- Standard encodings ---------------- %
+
+/StandardEncodings [
+
+% StandardEncoding
+mark
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
+ 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
+ 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
+ 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
+ 0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123
+ 0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136
+ 137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0
+ 0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0
+.packtomark
+
+% ExpertEncoding
+mark
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99
+ 239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252
+ 0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262
+ 0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272
+ 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
+ 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313
+ 0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319
+ 320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330
+ 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
+ 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
+ 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
+.packtomark
+
+] readonly def
+
+% ---------------- Standard Charsets ---------------- %
+
+% We include an explicit 0 at the beginning of each charset.
+
+/StandardCharsets [
+
+% ISOAdobe
+mark
+ 0
+ 1 1 228 { } for
+.packtomark
+
+% Expert
+mark
+ 0
+ 1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239
+ 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253
+ 254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267
+ 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283
+ 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
+ 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
+ 316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164
+ 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
+ 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
+ 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
+ 374 375 376 377 378
+.packtomark
+
+% ExpertSubset
+mark
+ 0
+ 1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243
+ 244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258
+ 259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300
+ 301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150
+ 164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340
+ 341 342 343 344 345 346
+.packtomark
+
+] readonly def
+
+% ---------------- Font loading ---------------- %
+
+% ------ Utilities ------ %
+
+/advance { % <n> advance -
+ f cff eq { pos add /pos exch store } { pop } ifelse
+} bind def
+/next { % - next <byte>
+ f read {
+ 1 advance
+ CFFDEBUG { ( ) print dup = } if
+ } if
+} bind def
+/next2 { % - next2 <byte1> <byte2>
+ f read {
+ f read {
+ 2 advance
+ CFFDEBUG { ( ) print 1 index =only (,) print dup = } if
+ } {
+ 1 advance
+ CFFDEBUG { ( ) print dup = } if
+ } ifelse
+ } if
+} bind def
+/nextstring { % <length> nextstring <string>
+ dup 0 eq {
+ pop ()
+ } {
+ string f exch readstring pop dup length advance
+ CFFDEBUG { ( ) print dup == } if
+ } ifelse
+} bind def
+/card8 % - card8 <card8>
+ /next load
+def
+/card16 { % - card16 <card16>
+ next2 exch 8 bitshift add
+} bind def
+/card32 { % - card32 <card32>
+ card16 16 bitshift card16 add
+} bind def
+/offsetprocs [
+ /card8 load
+ /card16 load
+ { card8 16 bitshift card16 add } bind
+ /card32 load
+] readonly def
+/offsetproc { % <offsize> offsetproc <proc>
+ 1 sub //offsetprocs exch get
+} bind def
+/offset { % <offsize> offset <offset>
+ offsetproc exec
+} bind def
+/sid % - <sid> sid
+ /card16 load
+def
+/Index { % <name> Index <name> <array>
+ CFFDEBUG { (% reading Index: ) print dup = } if
+ mark card16 dup 0 ne {
+ 1 exch next offsetproc dup exec pop exch {
+ dup exec dup 4 -1 roll sub 3 1 roll exch
+ } repeat pop
+ } if pop .packtomark
+ CFFDEBUG { (% Index lengths = ) print dup === } if
+ [ exch { nextstring } forall ] readonly
+} bind def
+/tokens { % - tokens <num1> ... <op#> (op# = 12 means EOF)
+ {
+ f read not { 12 exit } if
+ CFFDEBUG { (..) print dup = } if
+ 1 advance
+ dup 12 eq { pop next 32 add exit } if
+ dup 28 lt { exit } if
+ dup 32 lt {
+ 28 sub {
+ { card16 32768 xor 32768 sub }
+ { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if }
+ { tokenreal }
+ { 31 exit }
+ } exch get exec
+ } {
+ dup 247 lt {
+ 139 sub
+ } {
+ 247 sub {
+ { next 108 add }
+ { next 364 add }
+ { next 620 add }
+ { next 876 add }
+ { next 108 add neg }
+ { next 364 add neg }
+ { next 620 add neg }
+ { next 876 add neg }
+ % 255 is deliberately omitted and will cause a rangecheck
+ } exch get exec
+ } ifelse
+ } ifelse
+ } loop
+} bind def
+/tokenbuf 100 string def
+/tokenput { % <index> <str> tokenput <index+length>
+ dup length 3 1 roll
+ tokenbuf 2 index 3 -1 roll putinterval add
+} bind def
+/tokenrealarray [
+ (0)(1)(2)(3)(4)(5)(6)(7)(8)(9)(.)(E)
+ (E-)
+ () % ignore the invalid value
+ (-)
+ { exit } bind
+] readonly def
+/tokenreal { % - tokenreal <float>
+ 0 {
+ next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput
+ % We must leave the byte on the stack temporarily so that
+ % the exit will see a consistent stack state.
+ 1 index 15 and tokenrealarray exch get exec tokenput exch pop
+ } loop
+ tokenbuf 0 3 -1 roll getinterval cvr exch pop
+} bind def
+/Dict { % <opsdict> Dict -
+ /opdict exch store {
+ mark tokens
+ CFFDEBUG { (tokens: ) print ] dup === mark exch aload pop } if
+ opdict exch .knownget { exec } if cleartomark
+ } loop cleartomark
+} bind def
+/idstring { % <sid> idstring <string|name>
+ dup 391 lt { //StandardStrings } { 391 sub strings } ifelse exch get
+} bind def
+/idname { % <sid> idname <name>
+ idstring dup type /nametype ne { cvn } if
+} bind def
+/subfilefilter { % <file> <length> subfilefilter <filter>
+ % SubFileDecode interprets a length of 0 as infinite.
+ dup 0 le { pop pop () 0 } if () /SubFileDecode filter
+} bind def
+
+% ------ Top dictionary ------ %
+
+/offput { % <offset> <proc> offput -
+ 1 index 0 le
+ CFFDEBUG { dup { (not ) print } if (queued: ) print 2 index =only ( ) print 1 index === } if
+ { pop pop
+ }
+ { currentdict exch aload length 1 add packedarray cvx
+ offsets 3 1 roll put
+ }
+ ifelse
+} bind def
+/queueput { % <font> <proc> queueput -
+ 16#7fffffff offsets { pop .min } forall
+ pos sub nextstring
+ 3 1 roll aload length 2 add packedarray cvx
+ [ queued aload pop counttomark 2 add -1 roll ]
+ /queued exch store
+} bind def
+/printvk { % <value> <key> printvk <value> <key>
+ CFFDEBUG { (\t% ) print dup =only ( = ) print 1 index === } if
+} bind def
+/xxput { % <value> <key> <dict> xxput -
+ 3 1 roll exch put
+} bind def
+/putfi { % <value> <key> putfi -
+ printvk FontInfo xxput
+} bind def
+/xdef { % <value> <key> xdef -
+ exch def
+} bind def
+/pxdef { % <value> <key> pxdef -
+ printvk xdef
+} bind def
+/topdictops mark
+ 12 { CFFDEBUG { (\t% EOD) = } if exit }
+ 0 { idstring /version putfi }
+ 1 { idstring /Notice putfi }
+ 32 { idstring /Copyright putfi }
+ 2 { idstring /FullName putfi }
+ 3 { idstring /FamilyName putfi }
+ 4 { idstring /Weight putfi }
+ 33 { 0 ne /isFixedPitch putfi }
+ 34 { /ItalicAngle putfi }
+ 35 { /UnderlinePosition putfi }
+ 36 { /UnderlineThickness putfi }
+ 37 { /PaintType pxdef }
+ 38 { /FontType pxdef } % actually CharstringType
+ 39 { counttomark array astore /FontMatrix pxdef }
+ 13 { /UniqueID pxdef }
+ 5 { counttomark array astore /FontBBox pxdef }
+ 40 { /StrokeWidth pxdef }
+ 14 { counttomark array astore /XUID pxdef }
+ 15 {
+ /charset printvk pop
+ dup StandardCharsets length lt {
+ StandardCharsets exch get /charset xdef
+ } {
+ { queuecharset } offput
+ } ifelse
+ }
+ 16 {
+ /Encoding printvk pop
+ dup StandardEncodings length lt {
+ /Encoding xdef
+ } {
+ { queueEncoding } offput
+ } ifelse
+ }
+ 17 { { readCharStrings } offput }
+ 18 { exch /readPrivate cvx 2 packedarray offput }
+ % CIDFont operators
+ 62 { % ROS, must be first in a CIDFont
+ currentdict /FontType undef
+ currentdict /Encoding undef
+ currentdict /FontMatrix undef
+ /CIDFontVersion 0 def
+ /CIDFontRevision 0 def
+ /CIDFontType 0 def
+ /CIDCount 8720 def % Default value defined in CFF spec.
+ 3 dict begin
+ /Supplement pxdef
+ idstring /Ordering pxdef
+ idstring /Registry pxdef
+ /CIDSystemInfo currentdict end def
+ }
+ 63 { /CIDFontVersion pxdef }
+ 64 { /CIDFontRevision pxdef }
+ 65 { /CIDFontType pxdef }
+ 66 { /CIDCount pxdef }
+ 67 { /UIDBase pxdef }
+ 68 { { readFDArray } offput }
+ 69 { { readFDSelect } offput }
+ % This operator only appears in a FDArray element.
+ % We don't really need it, so ignore an error.
+ 70 { { idstring } .internalstopped { pop pop } { /FontName pxdef } ifelse }
+.dicttomark readonly def
+
+% readcharset and readFDSelect may require the length of CharStringArray,
+% but these structures may occur in the file before the CharStrings.
+% If that happens, use a hack: assume that all the data up to the next
+% queued read should be read.
+
+/charstringcount { % <font> charstringcount <count> true
+ % <font> charstringcount <length> false
+ /CharStringArray .knownget {
+ length true
+ } {
+ % Hack: look for the next queued read.
+ 16#7fffffff offsets { pop .min } forall
+ pos sub false
+ } ifelse
+} bind def
+
+/readCharStrings { % <font> readCharStrings -
+ /CharStringArray Index put
+} bind def
+
+% ------ Charsets and encodings ------ %
+
+% Note: formats 1 and 2 can overflow the operand stack.
+% We'll fix this if it ever becomes necessary.
+/charsetcount {
+ charstringcount { 1 sub } { 2 idiv } ifelse
+} bind def
+/charsetformats [
+{ [ 0 3 -1 roll charsetcount { sid } repeat ]
+} bind
+{ [ 0 3 -1 roll charsetcount {
+ dup 0 eq { pop exit } if
+ sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
+ } loop ]
+} bind
+{ [ 0 3 -1 roll charsetcount {
+ dup 0 eq { pop exit } if
+ sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop
+ } loop ]
+} bind
+] readonly def
+/queuecharset { % <font> queuecharset -
+ { readcharset } queueput
+} bind def
+/readcharset { % <data> <font> readcharset -
+ begin 0 () /SubFileDecode filter /f exch store
+ charsetformats next get currentdict exch exec /charset exch def end
+} bind def
+
+/encodingformats [
+{ 1 1 next { next exch Encoding 3 1 roll put } for
+} bind
+{ 1 next {
+ next next 1 add {
+ % Stack: gid code
+ Encoding 1 index 3 index put
+ exch 1 add exch 1 add
+ } repeat pop
+ } repeat pop
+} bind
+] readonly def
+/queueEncoding { % <font> queueEncoding -
+ { readEncoding } queueput
+} bind def
+/readEncoding { % <data> <font> readEncoding -
+ begin 0 () /SubFileDecode filter /f exch store
+ /Encoding [ 256 { /.notdef } repeat ] def
+ next encodingformats 1 index 127 and get exec
+ 128 ge {
+ % Read supplementary encodings.
+ next {
+ Encoding next sid idname put
+ } repeat
+ } if end
+} bind def
+
+% ------ FDArray and FDSelect ------ %
+
+/readFDArray { % <font> readFDArray -
+ /FDarray Index exch pop exch
+ 2 dict begin /f null def begin
+ [ exch {
+ dup length subfilefilter /f exch store
+ 10 dict begin
+ /FontType 2 def
+ /PaintType 0 def
+ /FontMatrix [0.001 0 0 0.001 0 0] def
+ /Private 20 dict def
+ //topdictops Dict currentdict end
+ } forall ] /FDArray xdef end end
+} bind def
+
+/fdselectformats [
+% Note: this procedure can overflow the operand stack.
+% We'll fix this if it ever becomes necessary.
+{ [ exch charstringcount pop { card8 } repeat ] } bind % Format 0
+{ /FDSelect cvx /invalidfont signalerror } bind % Format 1
+dup % Format 2
+% The following procedure does not use excessive op-stack space.
+{ pop 65535 array card16 card16 exch % Format 3
+ { % Stack: array previndex
+ card8 card16
+ exch 1 index 4 -1 roll
+ exch 1 exch 1 sub
+ { 3 index exch 2 index put } for pop
+ } repeat
+ % now resize the array to the final index.
+ 0 exch getinterval
+} bind
+] readonly def
+
+/readFDSelect { % <font> readFDSelect -
+ begin fdselectformats next get currentdict exch exec /FDSelect exch def end
+} bind def
+
+
+% ------ Private dictionary ------ %
+
+/deltarray { % -mark- <num1> ... deltarray <num1'> ...
+ 0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop
+ counttomark array astore
+} bind def
+
+/privatedictops mark
+ 12 { CFFDEBUG { (\t% EOD) = } if exit }
+ 6 { deltarray /BlueValues pxdef }
+ 7 { deltarray /OtherBlues pxdef }
+ 8 { deltarray /FamilyBlues pxdef }
+ 9 { deltarray /FamilyOtherBlues pxdef }
+ 41 { /BlueScale pxdef }
+ 42 { /BlueShift pxdef }
+ 43 { /BlueFuzz pxdef }
+ 10 { 1 array astore /StdHW pxdef }
+ 11 { 1 array astore /StdVW pxdef }
+ 44 { deltarray /StemSnapH pxdef }
+ 45 { deltarray /StemSnapV pxdef }
+ 46 { 0 ne /ForceBold pxdef }
+ 47 { /ForceBoldThreshold pxdef }
+ 48 { /lenIV pxdef }
+ 49 { /LanguageGroup pxdef }
+ 50 { /ExpansionFactor pxdef }
+ 51 { /initialRandomSeed pxdef }
+ 19 { PrivateStart add { readSubrs } offput }
+ 20 { /defaultWidthX pxdef }
+ 21 { /nominalWidthX pxdef }
+ % Multiple Master fonts only
+ 59 { /NDV pxdef }
+ 60 { /CDV pxdef }
+ 61 { /lenBuildCharArray pxdef }
+.dicttomark readonly def
+
+/readPrivate { % <font> <size> readPrivate -
+ 2 dict begin
+ /PrivateStart pos def
+ f 3 1 roll exch 1 index f exch subfilefilter /f exch store
+ dup /FontType get exch
+ /Private get begin
+ % Default lenIV to -1 even for Type 1 CharStrings.
+ 2 ne { /lenIV -1 def } if
+ //privatedictops Dict end
+ exch /f exch store advance
+ end
+} bind def
+
+/readSubrs { % <font> readSubrs -
+ /Subrs Index put
+} bind def
+
+% ------ Main program ------ %
+
+% Clean up after finishing a font.
+/cleanupFont { % (currentdict) cleanupFont -
+ % Remove unwanted entries.
+ currentdict /charset undef
+ currentdict /CharStringArray undef
+} bind def
+
+% Update the Encoding and CharStrings for a real font.
+/finishFont { % (currentdict) finishFont -
+ % Construct the real Encoding.
+ % The value of Encoding is either a number, for predefined
+ % encodings, or an array of mixed GIDs and names.
+ /Encoding mark Encoding
+ CFFDEBUG { (Encoding: ) print dup === flush } if
+ dup type /integertype eq {
+ StandardEncodings exch get { idname } forall
+ } {
+ {
+ dup type /integertype eq { charset exch get idname } if
+ } forall
+ } ifelse .packtomark def
+ % Construct the CharStrings.
+ % Note that they may only correspond to an initial
+ % subset of the charset.
+ /CharStrings charset length CharStringArray length .min dict def
+ CFFDEBUG {
+ charset length =only ( charset ) print
+ CharStringArray length =only ( CharStringArray) =
+ charset == flush
+ } if
+ 0 1 CharStrings maxlength 1 sub {
+ dup CharStringArray exch get
+ exch charset exch get idstring CharStrings xxput
+ } for
+ cleanupFont
+} bind def
+
+% Replace CharStrings with GlyphDirectory for a CIDFont;
+% Move GlobalSubrs to descendent fonts.
+/finishCIDFont { % (currentdict) finishCIDFont -
+ % Construct the GlyphDirectory, similar to CharStrings.
+ /FDBytes FDArray length 1 gt { 1 } { 0 } ifelse def
+ /GlyphDirectory charset length CharStringArray length .min dict def
+ CFFDEBUG {
+ charset length =only ( charset ) print
+ CharStringArray length =only ( CharStringArray) =
+ charset == flush
+ } if
+ 0 1 GlyphDirectory maxlength 1 sub {
+ dup CharStringArray exch get
+ % If there is more than one FDArray entry, add the font
+ % index to the beginning of each charstring.
+ FDBytes 1 eq {
+ FDSelect 2 index get
+ 1 string dup 0 4 -1 roll put exch concatstrings
+ } if
+ exch charset exch get GlyphDirectory xxput
+ } for
+
+ Private /GlobalSubrs .knownget {
+ FDArray {
+ /Private get /GlobalSubrs 2 index put
+ } forall
+ pop
+ Private /GlobalSubrs undef
+ } if
+
+ % Clean up.
+ currentdict /FDSelect undef
+ cleanupFont
+} bind def
+% We need to pass the file as a parameter for the sake of the PDF
+% interpreter. Also for the sake of PDF, a flag forces the font
+% to be defined as <resname> instead of the name embedded in the data.
+% This is needed for subsetted fonts; it is valid if the CFF
+% contains only a single font.
+/StartData { % <resname> <nbytes> StartData -
+ currentfile exch subfilefilter false ReadData
+} bind def
+/ReadData { % <resname> <file> <forceresname> ReadData -
+
+ % Initialize.
+
+ 30 dict begin
+ /forceresname exch def
+ /cff exch def
+ /pos 0 def
+ /resname exch cvlit def
+ /DEBUG CFFDEBUG def % bring the binding closer
+
+ % Read the header.
+
+ /f cff def
+ /vmajor next def
+ /vminor next def
+ /hdrsize next def
+ /aoffsize next def
+
+ % Read the Indexes.
+
+ /names Index def
+ /topdicts Index def
+ /strings Index def
+ /gsubrs Index def
+
+ % Read the top Dicts.
+
+ /offsets 50 dict def
+ /queued [] def
+ /opdict null def % reserve a slot
+ /fonts [ topdicts {
+ 0 () /SubFileDecode filter /f exch def
+ 40 dict begin
+ % Preload defaults that differ from PostScript defaults,
+ % or that are required.
+ /FontType 2 def
+ /PaintType 0 def
+ /FontMatrix [0.001 0 0 0.001 0 0] def
+ /charset StandardCharsets 0 get def
+ /Encoding 0 def
+ /FontInfo 10 dict
+ dup /UnderlinePosition -100 put
+ dup /UnderlineThickness 50 put
+ def
+ /Private 20 dict
+ gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if
+ def
+ //topdictops Dict
+ currentdict end
+ } forall ] def
+
+ % Read other tables with queued offsets.
+ % We process these in order so we can advance if needed.
+ % The CFF file may not be positionable.
+ { % outer loop since offsets may be updated when processing
+ CFFDEBUG { (offsets: ) print [ offsets { pop } forall ] == } if
+ [ offsets { pop } forall ] { lt } .sort % process in order of appearance
+ {
+ /f cff def
+ CFFDEBUG { (queued offset: ) print dup =print flush (, current pos=) print pos = } if
+ dup pos ne { dup pos sub nextstring pop } if % negative advance will cause error
+ offsets exch 2 copy get 3 1 roll undef
+ CFFDEBUG { (exec queued: ) print dup == } if
+ exec
+ } forall
+ offsets length 0 eq { exit } if
+ } loop
+
+ % Process out-of-order tables.
+
+ CFFDEBUG { queued length =only ( queued) = flush } if
+ queued { exec } forall
+
+ % Update Encoding and CharStrings.
+
+ fonts {
+ begin
+ currentdict /CIDFontType known { finishCIDFont } { finishFont } ifelse
+ end
+ } forall
+
+ % Wrap up.
+
+ resname mark 0 1 fonts length 1 sub {
+ CFFDEBUG { dup =only ( ) print flush } if
+ dup names exch get
+ forceresname { pop resname } if
+ CFFDEBUG { dup == flush } if
+ exch fonts exch get
+ dup /CIDFontType known {
+ % This is a CIDFont.
+ dup /CIDFontName 3 index put
+ 1 index exch /CIDFont defineresource
+ } {
+ % This is a font.
+ dup /FontName 3 index put
+ 1 index exch definefont
+ } ifelse
+ } for .dicttomark
+ end % temporary dict
+ end % FontSetInit ProcSet
+ /FontSet defineresource pop
+
+} bind def
+
+% ---------------- Resource category definition ---------------- %
+
+currentdict end readonly
+
+languagelevel exch 2 .setlanguagelevel
+
+/FontSet /Generic /Category findresource dup length dict .copydict
+/Category defineresource pop
+
+/FontSetInit exch /ProcSet defineresource pop
+
+.setlanguagelevel