diff options
Diffstat (limited to 'Master/xemtex/gslib/gs_cidfn.ps')
-rw-r--r-- | Master/xemtex/gslib/gs_cidfn.ps | 702 |
1 files changed, 702 insertions, 0 deletions
diff --git a/Master/xemtex/gslib/gs_cidfn.ps b/Master/xemtex/gslib/gs_cidfn.ps new file mode 100644 index 00000000000..e4b0ed2dc16 --- /dev/null +++ b/Master/xemtex/gslib/gs_cidfn.ps @@ -0,0 +1,702 @@ +% Copyright (C) 1995, 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_cidfn.ps,v 1.18.4.5.2.1 2003/04/12 14:02:38 giles Exp $ +% 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. + +/.checkfonttype { % <cidfont> <fonttype> .checkfonttype <cidfont> <new?> + 1 index /FID known { + 1 index /FontType get ne { + /definefont cvx /invalidfont signalerror + } if false + } { + 1 index /FontType 3 -1 roll put true + } ifelse +} bind def + +/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse +.cidfonttypes + +30 dict begin + +% The key in .cidfonttypes is the CIDFontType value; +% the value is a procedure that takes a font name and the CIDFont dictionary +% and replaces the latter with a real font. + +% ------ CIDFontType 0 (FontType 9) ------ % + +% We add the following entries to the CIDFont dictionary, in addition to +% the ones documented by Adobe: +% SubrCache - dictionary for caching Subr arrays +% For CIDFonts where we read the data from disk incrementally: +% GlyphData is 0 (arbitrary) +% DataSource - a ReusableStreamDecode filter for the data +% We also add a FID entry, and possibly a Subrs entry, to each element of +% FDArray. + +dup 0 { + 9 .checkfonttype { + /CIDInit /ProcSet findresource begin + .completefont9 + end + } if + 1 index exch .buildfont9 exch pop +} bind put + +% Add entries to a new CIDFontType 0 font per documentation (FontMatrix) +% or for .buildfont9 (FDArray.Private.Subrs). +/.completefont9 { % <cidfont0> .completefont9 <cidfont0> + currentglobal 3 1 roll dup gcheck setglobal + 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 { + % Read the Subrs if necessary. + dup /Private get dup /Subrs known not { + dup /SubrCount .knownget { + % Stack: font Private SubrCount + currentglobal 3 1 roll 1 index gcheck setglobal + array 1 index /Subrs 3 -1 roll put + % Stack: font global Private + 2 index begin begin .loadsubrs end end + setglobal + } { + pop + } ifelse readonly pop + } { + pop pop + } ifelse + } forall + 3 -1 roll setglobal +} bind def + +% 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 { + Subrs length 0 ne { + SubrCache SubrMapOffset .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 SubrMapOffset 2 index put + } if + } { + % We haven't loaded any Subrs at this offset yet. + SubrCount array 0 .readsubrs + SubrCache SubrMapOffset 2 index put + } ifelse + Subrs copy pop + } if +} bind def + +% ------ CIDFontType 1 (FontType 10) ------ % + +dup 1 { + 10 .checkfonttype pop + 1 index exch .buildfont10 exch pop +} bind put + +% ------ CIDFontType 2 (FontType 11) ------ % + +dup 2 { + 11 .checkfonttype pop + 1 index exch .buildfont11 exch pop +} bind put + +pop % .cidfonttypes + +% ---------------- Reading CIDFontType 0 files ---------------- % + +/StartData { % <(Binary)|(Hex)> <datalength> StartData - + % (currentdict is CID font dict) + % If we're loading a resource file and the data format is + % binary, we can just save a pointer to the data and load it + % incrementally. + mark { + % Previous versions of this code made provisions for + % reading hex-encoded data incrementally. Since hex data + % doesn't seem to be used in practice, we no longer bother. + 2 index (Binary) ne { stop } if + currentfile .currentresourcefile ne { stop } if + % Hack: the pdfwrite driver relies on finalization to write + % out fonts. However, the font may be finalized after the + % resource file, in which case the resource file will be + % closed. So if the current output device is pdfwrite, + % don't use incremental loading. + currentdevice .devicename /pdfwrite eq { stop } if + currentfile fileposition + } .internalstopped { + % File is not positionable, or uses hex data. + % Load the data now. + cleartomark exch (Hex) eq + { { currentfile exch readhexstring pop } } + { { currentfile exch readstring pop } } + ifelse exch + % Stack: readproc length + dup 65400 le { + % readstring with a 0-length string causes a rangecheck, + % but a data length of 0 is allowed. + string dup () ne { 1 index exec } if + } { + mark 3 1 roll { + % Stack: mark str ... readproc length + dup 0 eq { pop exit } if + dup 65400 .min dup string 3 index exec + % Stack: mark str ... readproc length newstrlen newstr + 4 1 roll sub + } loop + counttomark 1 add 1 roll ] + } ifelse + /GlyphData exch def + % If we were reading hex data, skip past the >. + 2 get { readhexstring } 0 get eq { + currentfile 0 (>) .subfiledecode dup flushfile closefile + } if + } { + % File is positionable and binary, just save a pointer. + % Stack: (Binary) length -mark- pos + /GlyphData 0 def + exch pop 3 -1 roll pop exch + % Stack: pos length + /DataSource currentfile 2 index () .subfiledecode true .reusablestream def + currentfile 3 1 roll add setfileposition + } ifelse + /SubrCache 10 dict def + CIDFontName currentdict /CIDFont defineresource pop + end % CID font dict + end % resource category dict +} bind def + +% Some Adobe fonts include the line +% /Setup /cid_Setup load def +% This is apparently included only to prevent proper, conforming PostScript +% interpreters (as opposed to ATM or a special Adobe font loader) from +% loading the font, since Setup is not referenced anywhere else in the file. +/cid_Setup { } def + +currentdict end + +% ---------------- Rendering ---------------- % + +% ------ Generic ------ % + +% Read a string at a given offset in a "file" (binary file or +% GlyphData in RAM). +/ReadString { % <pos> <string> ReadString <string> + GlyphData 0 eq { + % Read from the file. + DataSource 3 -1 roll setfileposition + DataSource exch readstring pop + } { + % Read from a string or an array of strings. + GlyphData .stringsreadstring + } ifelse +} 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 + +% ------ CIDFontType 0 ------ % + +/.readglyphdata { + currentfont exch .type9mapcid + FDArray exch get exch +} bind def + +% BuildGlyph procedure for CIDFontType 0. +% 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 { + % Substitute CID 0. **** WRONG **** + pop pop 0 .readglyphdata + } if + % Stack: cidfont cid subfont charstring + dup null eq { pop pop pop pop } { %**** WRONG **** + 4 -1 roll pop + 3 1 roll exch dup 4 -1 roll 0 0 moveto + 3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse + } ifelse %**** WRONG **** + end + .setglobal +} bind def + +% ------ CIDFontType 2 ------ % + +% BuildGlyph procedure for CIDFontType 2. +% The name %Type11BuildGlyph is known to the interpreter. +(%Type11BuildGlyph) cvn { % <cidfont> <cid> %Type11BuildGlyph - + % We must be prepared for out-of-range CIDs. + 2 copy { .type11mapcid } .internalstopped { + pop /CharStrings get /.notdef get + } if + % Stack: cidfont cid glyphindex + 1 index exch .type42execchar +} bind def + +% ---------------- Define resources ---------------- % + +languagelevel exch 2 .setlanguagelevel + +% Define the CIDInit ProcSet resource. +% The ProcSet dictionary is still on the stack. + +% We might have loaded CMap support already. However, Adobe's +% protected font downloader defines a CIDInit ProcSet that will be +% loaded from the filesystem later, so we must check specifically +% for the ProcSet being defined in VM. +/CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse { + 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. +% We break out .buildcidfont because it appears that at least for +% Type 32 (CIDFontType 4) fonts, the font can be registered in the Font +% category with only a CIDFontType and no FontType. +/.buildcidfont { % <name> <fontdict> .buildcidfont + % <name> <cidfont> + dup /CIDFontType get //.cidfonttypes exch get exec +} odef + +/.loadcidfontwithoutpop { + dup 4 string .peekstring pop dup (ttcf) eq exch (\000\001\000\000) eq or { + .loadcjkvttcidfont + } { + /CIDFont /Category findresource /.Instances get + dup length 2 div cvi dict .copydict exch + .loadfont + % Stack: <<original-.Instances>> + /CIDFont /Category findresource /.Instances get {% forall + % <<original-.Instances>> key value + 2 index 2 index known { + pop pop + } { + pop exch pop /CIDFont findresource exit + } ifelse + } forall + dup /CIDFontName known not { + {Internal Error in .loadcidfontwithoutpop} stop + } if + } ifelse +} bind def + +/.loadcidfont { + .loadcidfontwithoutpop pop +} bind def + +% Define the name of the CID font map file. +/defaultcidfontmap (CIDFnmap) def +userdict /CIDFontmap 10 dict put + +% <dict> <file> .readCIDFontmap <dict> +% Code from gs_fonts.ps::.readFontmap +/.readCIDFontmap { + { dup token not { closefile exit } if + % This is a hack to get around the absurd habit of MS-DOS editors + % of adding an EOF character at the end of the file. + dup (\032) eq { pop closefile exit } if + 1 index token not + { (CIDFontmap entry for ) print dup =only + ( has no associated file or alias name! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + dup type dup /stringtype eq exch /nametype eq or not + { (CIDFontmap entry for ) print 1 index =only + ( has an invalid file or alias name! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + % stack: dict file cidfontname filename|aliasname + 1 index type /stringtype eq + 1 index type /nametype eq and 1 index xcheck and + 1 index /run eq 2 index /.runlibfile eq or and { + % This is an inclusion entry. + pop findlibfile { exch pop } { file } ifelse + 2 index exch .readCIDFontmap pop + } { + % This is a real entry. + % stack: dict file cidfontname filename|aliasname + + % Before staring a game, we need a hack. + % Some CJK pdf file contains a cidfontname that cannot + % be represented as a nametype literal. Instead, the + % cidfontname is represented as a string literal. + % If a cidfontname is represented as a stringtype object, + % it must be converted to a nametype object. + % We handle such a case here. + exch dup type /stringtype eq {cvn} if exch + + % stack: dict file cidfontname filename|aliasname + % Read and pop tokens until a semicolon. + { 2 index token not + { (CIDFontmap entry for ) print 1 index =only + ( ends prematurely! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + dup /; eq { pop 3 index 3 1 roll .growput exit } if + % Format: + % /CIDFontname (file) ttc-index ; + % /CIDFontname (file) /Code->CID-dict ; + % /CIDFontname (file) ttc-index /Code->CID-dict ; + % + % e.g. + % /HG-MinchoL (hgminchol.ttc) 1 /Adobe-Japan1-Unicode ; + % /HG-PMinchoL (hgminchol.ttc) 2 /Adobe-Japan1-Unicode ; + % /HG-MinchoL-J2 (hgminchol.ttc) 1 /Adobe-Japan2-Unicode ; + % /HG-PGothicB (hggothicb.ttc) 2 ; + % /HG-GothicB-J2 (hggothicb.ttc) /Adobe-Japan2-Unicode ; + % + % CID Fontmap entry is stored into CIDFontmap dict as an array. + % Array format: + % [filename ttc-index] + % [filename /Code->CID-dict] + % [filename ttc-index /Code->CID-dict] + % + % Type: + % filename: string + % ttc-index: integer + % /Code->CID-dict: name + % + % stack: dict file cidfontname filename something + 1 index type /nametype eq { + (CIDFontmap entry for ) print 2 index =only + (defines an alias! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + % stack: dict file cidfontname filename something + exch [ exch 3 -1 roll + % stack: dict file cidfontname [ filename something + dup type /integertype eq { + % stack: dict file cidfontname [ filename int + % Read next token + 4 index token not + { (CIDFontmap entry for ) print 3 index =only + ( ends prematurely! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + } if + % stack: dict file cidfontname [ filename int something + % or dict file cidfontname [ filename something + dup /; eq not 1 index type /nametype eq and { + % stack: dict file cidfontname [ filename /Code->CID + % or dict file cidfontname [ filename int /Code->CID + % Read next token + counttomark 2 eq {4} {5} ifelse index token not + { (CIDFontmap entry for ) print + counttomark 2 eq {3} {4} ifelse index =only + ( ends prematurely! Giving up.) = flush + {.readCIDFontmap} 0 get 1 .quit + } if + } if + % stack: dict file cidfontname [ filename int /Code->CID something + % or dict file cidfontname [ filename /Code->CID something + dup /; eq { + pop ] + 3 index 3 1 roll .growput exit + } if + pop + } loop + } ifelse + } loop +} bind def + +% <file> .loadCIDFontmap - +/.loadCIDFontmap { + userdict /CIDFontmap get exch + .readCIDFontmap pop +} bind def + +% Code from .loadinitialfonts +/.loadinitialcidfonts + { NOCIDFONTMAP not + { /CIDFONTMAP where + { pop [ CIDFONTMAP .pathlist ] + { + dup VMDEBUG findlibfile + { exch pop .loadCIDFontmap } + { /undefinedfilename signalerror } + ifelse + } + } + { LIBPATH + { + defaultcidfontmap 1 index .filenamedirseparator + exch concatstrings concatstrings dup VMDEBUG + (r) { file } .internalstopped + { pop pop } { .loadCIDFontmap } ifelse + } + } + ifelse forall + } + if + %%% Do nothing + } bind def + +.loadinitialcidfonts + +/CIDFontmapHandler << + /nametype { + /CIDFont findresource + /CIDFont defineresource pop + } bind + /stringtype { + findlibfile { + exch pop + % Define CIDFont with a name defined in the font file + .loadcidfontwithoutpop + % Define CIDFont with a name define in CIDFontmap + dup length 0 ne { + dup /CIDFontName get 2 index eq { + % Avoid duplicated defineresource for the same CIDFont + pop pop + } { + % Give a name different from the name defined in the file + /CIDFont defineresource pop + } ifelse + } { + pop pop + } ifelse + } { + /undefinedresource signalerror + } ifelse + } bind + /arraytype { + % Replace filename in the array with file + dup 0 get + findlibfile { + 3 1 roll pop + copyarray dup 3 1 roll 0 + 3 -1 roll put + % Expand array + aload pop .loadcjkvttcidfont + /CIDFont defineresource pop + } { + /undefinedresource signalerror + } ifelse + } bind +>> def + +%%% CIDFontmap Public Interface +% /CIDFontName .CIDFontmapKnown true|false +/.CIDFontmapKnown { + userdict /CIDFontmap get exch known +} bind def + +% /CIDFontName .CIDFontmapKnownget value true +% /CIDFontName .CIDFontmapKnownget false +/.CIDFontmapKnownget { + userdict /CIDFontmap get exch .knownget +} bind def + +% /CIDFontName value .CIDFontmapRunHandler - +/.CIDFontmapRunHandler { + dup CIDFontmapHandler exch type get .execasresource +} bind def + +% proc .CIDFontmapForAll - +/.CIDFontmapForAll { + CIDFontmap exch forall +} bind def + +% proc .CIDFontmapForAllKey - +/.CIDFontmapForAllKey { + [ /pop cvx 3 -1 roll /exec cvx ] cvx .CIDFontmapForAll +} bind def + +/CIDFont /Generic /Category findresource dup length dict .copydict +dup /InstanceType /dicttype put +dup /DefineResource { + .buildcidfont + /Generic /Category findresource /DefineResource get exec +} put +/.originalresourceforall 1 index /ResourceForAll get def +dup /ResourceForAll { + currentglobal false setglobal + % (template) (proc) (scratch) g + [ % (template) (proc) (scratch) g [ + % + % 1. Gather CIDFont name in /Resource/CIDFont + % + 4 index % (template) (proc) (scratch) g [ (template) + {cvn} % (template) (proc) (scratch) g [ (template) {cvn} + 4 index % (template) (proc) (scratch) g [ (template) {cvn} (scratch) + .originalresourceforall + % (template) (proc) (scratch) g [ ... + % + % 2. Gather CIDFont name in CIDFontmap + % + { + dup length string cvs + dup % (template) (proc) (scratch) g [ ... (Key) (Key) + counttomark 4 add index + % (template) (proc) (scratch) g [ ... (Key) (Key) (template) + .stringmatch { + cvn + % (template) (proc) (scratch) g [ ... /Key + % 3. Remove duplicated /Key + counttomark -1 1 { + index 1 index eq { + pop exit % Duplicated + } if + } for + } { + pop + } ifelse + } .CIDFontmapForAllKey + ] + exch setglobal + % + % 4. Build extended procedure + % + % (template) (proc) (scratch) [CIDFontmapKeys] + 4 -1 roll pop + % (proc) (scratch) [CIDFontmapKeys] + 3 1 roll + % [CIDFontmapKeys] (proc) (scratch) + [ exch {cvs} aload pop + % [CIDFontmapKeys] (proc) [ (scratch) -cvs- + 4 -1 roll aload pop ] cvx + % [CIDFontmapKeys] proc++ + % + % 5. Exec + % + forall +} put + +% CIDFonts may be defined in CFF OpenType files. +% Check for this here. +/.loadcidfontresource { + dup .ResourceFile { + {.loadcidfont} .execasresource + } { + pop dup + .CIDFontmapKnownget { + .CIDFontmapRunHandler + } { + dup /undefinedresource signalerror + } ifelse + } ifelse +} bind def +dup /.LoadResource { + currentglobal { + .loadcidfontresource + } { + true setglobal {.loadcidfontresource} stopped false setglobal {stop} if + } ifelse +} bind put +dup /.ResourceFileStatus { + dup .CIDFontmapKnown { + pop 2 -1 true + } { + .ResourceFile { closefile 2 -1 true } { pop false } ifelse + } ifelse +} bind put + +/Category defineresource pop + +% 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 a string, an array of strings, or (as of Adobe release 3011) + % a dictionary. + dup type dup dup /stringtype eq exch /dicttype eq or { + pop true + } { + dup /arraytype eq exch /packedarraytype eq or { + true exch { type /stringtype eq and } forall + } { + false + } ifelse + } ifelse +} bind put +/Category defineresource pop + +.setlanguagelevel |