diff options
Diffstat (limited to 'gs/lib/gs_cidfn.ps')
-rw-r--r-- | gs/lib/gs_cidfn.ps | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/gs/lib/gs_cidfn.ps b/gs/lib/gs_cidfn.ps new file mode 100644 index 000000000..557065b7c --- /dev/null +++ b/gs/lib/gs_cidfn.ps @@ -0,0 +1,428 @@ +% Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved. +% +% This file is part of Aladdin Ghostscript. +% +% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author +% or distributor accepts any responsibility for the consequences of using it, +% or for whether it serves any particular purpose or works at all, unless he +% or she says so in writing. Refer to the Aladdin Ghostscript Free Public +% License (the "License") for full details. +% +% Every copy of Aladdin Ghostscript must include a copy of the License, +% normally in a plain ASCII text file named PUBLIC. The License grants you +% the right to copy, modify and redistribute Aladdin Ghostscript, but only +% under certain conditions described in the License. Among other things, the +% License requires that the copyright notice and this notice be preserved on +% all copies. + +% ProcSet for implementing CIDFont and CIDMap resources. +% When this is run, systemdict is still writable. + +% ---------------- Defining CIDFont resources ---------------- % + +% Define a CIDFont resource. This is the defineresource implementation for +% the CIDFont resource category. + +/.definecidfont [ + +% CIDFontType 0 +{ dup /FontMatrix known not + { dup /FontMatrix [0.001 0 0 0.001 0 0] put + dup /FDArray get + { /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop } + forall + } + if + dup /FDArray get mark exch + { % Add pro forma entries + dup /FontType 1 put + dup /CharStrings 10 dict put + dup /Encoding [] put + % Create a dummy Subrs array now. + dup /Private get dup /SubrCount .knownget + { array 1 index /Subrs 3 -1 roll put } + if pop + dup /FontName .knownget not { () } if exch .buildfont1 exch pop + } + forall ] 1 index /FDepVector 3 -1 roll put + 1 index exch .buildfont9 exch pop +} bind + +% CIDFontType 1 +{ 1 index exch .buildfont10 exch pop +} bind + +% CIDFontType 2 +{ 1 index exch .buildfont11 exch pop +} bind + +] def + +% ---------------- Reading CIDFontType 0 files ---------------- % + +30 dict begin + +% We add the following entries to the CIDFont dictionary, in addition to +% the ones documented by Adobe: +% ReadString - procedure for reading a string from the binary data +% SubrCache - dictionary for caching Subr arrays +% For CIDFonts where we read the data from disk incrementally: +% DataOffset - starting position of data in file +% (if data are in hex) OffsetMap - map from logical data positions to +% physical positions in file + +/StartData % <(Binary)|(Hex)> <datalength> StartData - + % (currentdict is CID font dict) +{ % If we're loading a resource file, we can just save a + % pointer to the binary data and load it incrementally. + % Check for this by opening the resource file, + % positioning it to currentfile's position plus the + % data length, and checking for %%EndData. + mark + { currentfile fileposition + CIDFontName 100 string ResourceFileName (r) file + mark + { % Stack: (Binary)|(Hex) length -mark- pos resfile + % -mark- + 5 index (Hex) eq + { 1 index 3 index setfileposition + 1 index 5 index .skiphex + %**************** SKIP > AND WHITESPACE SOMEHOW + } + { 1 index 3 index 6 index add setfileposition + } + ifelse + 1 index 9 string readstring pop (%%EndData) ne { stop } if + } + .internalstopped { cleartomark closefile stop } if + pop % pop the mark + } + .internalstopped + { % File is not positionable, load the data now. + cleartomark exch (Hex) eq + { { currentfile exch readhexstring pop } } + { { currentfile exch readstring pop } } + ifelse /ReadString exch def + dup 65535 le + { string ReadString + } + { mark exch + { dup 0 eq { pop exit } if + dup 65535 min dup string ReadString + 3 1 roll sub + } + loop ] + } + ifelse + /GlyphData exch def + /.vmreadstring cvx + } + { % File is positionable, just save a pointer. + % Stack: (Binary)|(Hex) length -mark- pos file + 4 1 roll + /DataOffset exch def + pop /GlyphData exch def + exch (Hex) eq + { % Hex data, build the offset map. + .buildoffsetmap + /.hexreadstring + } + { % Binary data, just skip over it. + currentfile DataOffset GlyphData add setfileposition + /.binaryreadstring + } + ifelse cvx + 2 packedarray cvx + } + ifelse /ReadString exch def + /SubrCache 10 dict def + CIDFontName currentdict /CIDFont defineresource pop + end % CID font dict + end % resource category dict +} bind def + +% Skip a given distance in an ASCIIHex encoded file. We use this at +% rendering time as well. +/.skiphex % <file> <count> .skiphex - +{ exch /ASCIIHexDecode filter dup 3 -1 roll () /SubFileDecode filter + dup flushfile closefile closefile +} bind def + +% Build the map from logical offsets to physical offsets in ASCIIHex +% encoded data. +/.buildoffsetmap +{ /OffsetMap GlyphData 256 idiv 8000 min array def + 2 dict begin + /block GlyphData OffsetMap length idiv def + 0 1 OffsetMap length 1 sub + { OffsetMap exch currentfile fileposition put + currentfile block .skiphex + } + for + GlyphData block mod dup 0 eq + { pop } + { currentfile exch .skiphex } + ifelse + end % scratch dict +} bind def + +currentdict end + +% ---------------- Rendering ---------------- % + +% ------ Generic ------ % + +% Read a string at a given offset in a "file" (binary file, ASCII hex file, +% or GlyphData in RAM). +/.binaryreadstring % <pos> <string> <file> .binaryreadstring <string> + { dup 4 -1 roll DataOffset add setfileposition exch readstring pop + } bind def +/.hexreadstring % <pos> <string> <file> .hexreadstring <string> +{ % Use the OffsetMap to get to the block of hex data, + % then skip to the correct position by reading. + GlyphData OffsetMap length idiv + % Stack: pos string file blocklen + 3 index 1 index idiv OffsetMap exch get + 2 index exch setfileposition + % Skip the next (pos % blocklen) hex bytes. + 4 -1 roll exch mod 1 index exch .skiphex + % Stack: string file + exch readhexstring pop +} bind def +/.vmreadstring % <pos> <string> .vmreadstring <vmstring> +{ GlyphData .stringsreadstring +} bind def +/.stringsreadstring % <pos> <string> <strings> .stringsreadstring + % <vmstring> +{ dup type /stringtype eq + { 3 1 roll length getinterval + } + { { % Stack: pos string glyphdata + dup 0 get length dup 4 index gt { exit } if + 4 -1 roll exch sub 3 1 roll + dup length 1 sub 1 exch getinterval + } + loop + % Stack: pos string glyphdata glyphdata[0]length + % We know no request can span more than 2 strings. + 3 index 3 index length add 1 index le + { % Request fits in a single string: just return a substring. + pop 0 get 3 1 roll length getinterval + } + { % Request spans 2 strings. Copy the first part. + 1 index 0 get 4 index 3 -1 roll 1 index sub getinterval + 2 index copy + % Copy the second part. + % Stack: pos str glyphdata str1 + length exch 1 get 0 3 index length + 3 index sub getinterval 2 index 3 1 roll putinterval + exch pop + } + ifelse + } + ifelse +} bind def + +% Interpret a byte string as a (big-endian) integer. +/.cvbsi % <bytes> .cvbsi <int> +{ 0 exch { exch 8 bitshift add } forall +} bind def + +% Read an integer from binary data. +/.readint % <pos> <nbytes> .readint <int> +{ string ReadString .cvbsi +} bind def + +% Read the glyph data for a given CID. +% The CIDFont is currentdict. +/.readglyphdata % <cid> .readglyphdata <subfont> <string|null> +{ currentdict /GlyphDirectory .knownget + { dup type /arraytype eq + { 1 index exch get } + { 1 index exch .knownget not { null } if } + ifelse + dup null eq + { FDepVector 0 get exch } + { FDBytes 0 eq + { FDepVector 0 get exch } + { % Note: FDBytes > 1 is not supported. + dup 0 get FDepVector exch get + exch dup length 1 sub 1 exch getinterval + } + ifelse + } + ifelse + } + { FDBytes GDBytes add mul CIDMapOffset add + dup FDBytes .readint exch + FDBytes add dup GDBytes .readint + exch GDBytes add FDBytes add GDBytes .readint + % Stack: fd pos nextpos + 1 index sub dup 0 eq + { pop pop pop FDepVector 0 get null } + { string ReadString exch FDepVector exch get exch } + ifelse + } + ifelse +} bind def + +% ------ CIDFontType 0 ------ % + +% Read some Subrs for the current Type 1 subfont. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.readsubrs % <Subrs> <start> .readsubrs <Subrs> +{ 1 SubrCount 1 sub + { dup SDBytes mul SubrMapOffset add + dup SDBytes .readint exch SDBytes add SDBytes .readint + 1 index sub string ReadString 2 index 3 1 roll put + } + for +} bind def + +% Ensure that all the Subrs for the current Type 1 subfont are loaded. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.loadsubrs +{ currentdict /SubrMapOffset .knownget + { Subrs 0 get null ne + { pop % We've already loaded the Subrs. + } + { SubrCache 1 index .knownget + { % We've already loaded some Subrs at this offset. + % Make sure we've got as many as we need. + dup length SubrCount lt + { % We need to load more. + SubrCount array exch 1 index copy length .readsubrs + SubrCache 3 -1 roll 2 index put + } + if + } + { % We haven't loaded any Subrs at this offset yet. + SubrCount array 0 .readsubrs + SubrCache 3 -1 roll 2 index put + } + ifelse + Subrs copy pop + } + ifelse + } + if +} bind def + +% BuildGlyph procedure for CIDFontType 0. +% ****** WHY NOT USE .type1execchar FOR THIS? ****** +% The name %Type9BuildGlyph is known to the interpreter. +/.cid0buildstring 10 string def +(%Type9BuildGlyph) cvn % <cidfont> <cid> %Type9BuildGlyph - +{ .currentglobal 3 1 roll 1 index gcheck .setglobal + 1 index begin + dup .readglyphdata dup null eq + { %**** HANDLE NOTDEF **** + } + if + % Stack: cidfont cid subfont charstring +dup null eq { pop pop pop pop } { %**** WRONG **** + 4 -1 roll pop + exch dup /Private get begin .loadsubrs end + 3 -1 roll //.cid0buildstring cvs cvn 3 1 roll + dup /CharStrings get 3 index 4 -1 roll put + setfont + 1000 0 setcharwidth %**** WRONG **** + 0 0 moveto glyphshow +} ifelse %**** WRONG **** + end + .setglobal +} bind def + +% ------ CIDFontType 2 ------ % + +% BuildGlyph procedure for CIDFontType 2. +% ****** ADD THE OUTLINE STRING AS AN ARGUMENT TO .type42execchar. ****** +% The name %Type11BuildGlyph is known to the interpreter. +(%Type11BuildGlyph) cvn % <cidfont> <cid> %Type11BuildGlyph - +{ .currentglobal 3 1 roll 1 index gcheck .setglobal + 1 index begin + dup GDBytes mul GDBytes string CIDMap .stringsreadstring .cvbsi + % Stack: cidfont cid glyphindex +%**************** GlyphDirectory is not supported yet. +( + currentdict /GlyphDirectory .knownget +) pop false + { dup type /arraytype eq + { 1 index exch get } + { 1 index exch .knownget not { null } if } + ifelse + dup null eq + { %**** HANDLE NOTDEF + } + if + 1 index exch .type42execchar + } + { 1 index exch .type42execchar + } + ifelse + end + .setglobal +} bind def + +% ---------------- Define resources ---------------- % + +languagelevel exch 2 .setlanguagelevel + +% Define the CIDInit ProcSet resource. +% The ProcSet dictionary is still on the stack. + +/CMap /Generic /Category findresource dup length dict .copydict +/Category defineresource pop + % We might have loaded CMap support already. +/CIDInit /ProcSet 2 copy resourcestatus { + pop pop findresource dup length 4 index length add dict .copydict + 4 -1 roll exch .copydict +} { + 3 -1 roll +} ifelse exch defineresource pop + +% Define the CIDFont resource category. + +/CIDFont /Generic /Category findresource dup length dict .copydict +dup /InstanceType /dicttype put +dup /DefineResource { + dup /CIDFontType get dup 9 add /FontType exch 3 index 3 1 roll put + //.definecidfont exch get exec + /Generic /Category findresource /DefineResource get exec +} put +/Category defineresource pop + +currentdict /.definecidfont undef + +% Add the new FontType resources. + +9 1 11 { dup /FontType defineresource pop } for + +% Add the new FMapType resource. + +9 dup /FMapType defineresource pop + +% Define the CIDMap resource category. +% These aren't documented, but it's clear what they are for: +% to give names to CIDMaps for CIDFontType 2 fonts. + +/CIDMap /Generic /Category findresource dup length dict .copydict +dup /.CheckResource { + % Allow either a string or an array of strings. + dup type dup /stringtype eq + { pop true + } + { dup /arraytype eq exch /packedarraytype eq or + { true exch { type /stringtype ne { pop false exit } if } forall + } + { false + } + ifelse + } + ifelse +} bind put +/Category defineresource pop + +.setlanguagelevel |