diff options
Diffstat (limited to 'Master/xemtex/gslib/gs_cff.ps')
-rw-r--r-- | Master/xemtex/gslib/gs_cff.ps | 758 |
1 files changed, 758 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/gs_cff.ps b/Master/xemtex/gslib/gs_cff.ps new file mode 100644 index 00000000000..2b9b510e7c7 --- /dev/null +++ b/Master/xemtex/gslib/gs_cff.ps @@ -0,0 +1,758 @@ +% Copyright (C) 1997, 1998, 1999, 2000 Aladdin Enterprises. All rights reserved. +% +% This program is free software; you can redistribute it and/or modify it +% under the terms of the GNU General Public License as published by the +% Free Software Foundation; either version 2 of the License, or (at your +% option) any later version. +% +% This program is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +% Public License for more details. +% +% You should have received a copy of the GNU General Public License along +% with this program; if not, write to the Free Software Foundation, Inc., +% 59 Temple Place, Suite 330, Boston, MA, 02111-1307. + +% $Id: gs_cff.ps,v 1.10.2.1.2.1 2003/04/12 14:02:38 giles Exp $ +% 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. + .loadottofontfile + } { + % Not a TrueType font. + .loadnonottofontfile + } ifelse +} bind def + +% <file> .loadottofontfile - +/.loadottofontfile { + /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 + 1 sub + } 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 + % Use a random FontSet resource name. ****** WRONG ****** + realtime rand xor =string cvs exch false + ReadData +} 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 + DEBUG { ( ) print dup = } if + } if +} bind def +/next2 { % - next2 <byte1> <byte2> + f read { + f read { + 2 advance + DEBUG { ( ) print 1 index =only (,) print dup = } if + } { + 1 advance + DEBUG { ( ) print dup = } if + } ifelse + } if +} bind def +/nextstring { % <length> nextstring <string> + dup 0 eq { + pop () + } { + string f exch readstring pop dup length advance + DEBUG { ( ) 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 { % - Index <array> + 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 + [ exch { nextstring } forall ] readonly +} bind def +/tokens { % - tokens <num1> ... <op#> (op# = 12 means EOF) + { + f read not { 12 exit } if + DEBUG { (..) 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> <char> tokenput <index+1> + tokenbuf 2 index 3 -1 roll put 1 add +} bind def +/tokenrealarray [ + (0123456789.E) { } forall + [(E) 0 get /tokenput cvx (-) 0 get] cvx + null % will give an error + (-) 0 get + { exit } +] 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 + DEBUG { (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 - + DEBUG { (queued: ) print 1 index =only ( ) print dup === } if + currentdict exch aload length 1 add packedarray cvx + offsets 3 1 roll put +} 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 +/xxput { % <value> <key> <dict> xxput - + 3 1 roll exch put +} bind def +/putfi { % <value> <key> putfi - + FontInfo xxput +} bind def +/xdef { % <value> <key> xdef - + exch def +} bind def +/topdictops mark + 12 { 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 xdef } + 38 { /FontType xdef } % actually CharstringType + 39 { counttomark array astore /FontMatrix xdef } + 13 { /UniqueID xdef } + 5 { counttomark array astore /FontBBox xdef } + 40 { /StrokeWidth xdef } + 14 { counttomark array astore /XUID xdef } + 15 { + dup StandardCharsets length lt { + StandardCharsets exch get /charset xdef + } { + { queuecharset } offput + } ifelse + } + 16 { + 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 xdef + idstring /Ordering xdef + idstring /Registry xdef + /CIDSystemInfo currentdict end def + } + 63 { /CIDFontVersion xdef } + 64 { /CIDFontRevision xdef } + 65 { /CIDFontType xdef } + 66 { /CIDCount xdef } + 67 { /UIDBase xdef } + 68 { { readFDArray } offput } + 69 { { readFDSelect } offput } + % This operator only appears in a FDArray element. + 70 { idstring /FontName exch def } +.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 - + Index 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 + +% Note: this implementation can overflow the operand stack. +% We'll fix this if it ever becomes necessary. +/fdselectformats [ +{ [ exch charstringcount pop { card8 } repeat ] } bind +{ /FDSelect cvx /invalidfont signalerror } bind +dup +{ pop [ card16 card16 exch { + % Stack: previndex + card8 card16 dup 4 1 roll 3 -1 roll sub 1 sub { + exch 1 index + } repeat exch + } repeat pop ] +} 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 { exit } + 6 { deltarray /BlueValues xdef } + 7 { deltarray /OtherBlues xdef } + 8 { deltarray /FamilyBlues xdef } + 9 { deltarray /FamilyOtherBlues xdef } + 41 { /BlueScale xdef } + 42 { /BlueShift xdef } + 43 { /BlueFuzz xdef } + 10 { 1 array astore /StdHW xdef } + 11 { 1 array astore /StdVW xdef } + 44 { deltarray /StemSnapH xdef } + 45 { deltarray /StemSnapV xdef } + 46 { 0 ne /ForceBold xdef } + 47 { /ForceBoldThreshold xdef } + 48 { /lenIV xdef } + 49 { /LanguageGroup xdef } + 50 { /ExpansionFactor xdef } + 51 { /initialRandomSeed xdef } + 19 { PrivateStart add { readSubrs } offput } + 20 { /defaultWidthX xdef } + 21 { /nominalWidthX xdef } + % Multiple Master fonts only + 59 { /NDV xdef } + 60 { /CDV xdef } + 61 { /lenBuildCharArray xdef } +.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 + DEBUG { (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 + DEBUG { + 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 + DEBUG { + 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 DEBUG 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. + + DEBUG { (offsets: ) print [ offsets { pop } forall ] == } if + { /f cff def + DEBUG { (pos=) print pos = } if + offsets pos 2 copy .knownget not { pop pop exit } if + 3 1 roll undef + DEBUG { (exec queued: ) print dup == } if + exec + } loop + offsets length 0 ne { + (Error: missing tables at ) print [ offsets { pop } forall ] == + (Current position is ) print pos == + flush stop + } if + + % Process out-of-order tables. + + DEBUG { 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 { + DEBUG { dup =only ( ) print flush } if + dup names exch get + forceresname { pop resname } if + DEBUG { 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 |