% Copyright (C) 1995, 1996, 1997, 1998, 1999 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.% $Id: gs_cmap.ps,v 1.1 2000/03/09 08:40:39 lpd Exp $% ProcSet for implementing CMap resources.% When this is run, systemdict is still writable.% NOTE: Rearranged fonts are not implemented yet.% ---------------- Public operators ---------------- %% composefont doesn't appear in CMap files -- it's documented in% the "PostScript Language Reference Manual Supplement"./composefont { % <name> <cmap|cmapname> <fonts> composefont <font> 10 dict begin /CMap 2 index dup type /dicttype ne { /CMap findresource } if def /FDepVector 1 index cvlit def % temporarily /Encoding [ 0 1 FDepVector length 1 sub { } for ] def /FDepVector [ 0 1 FDepVector length 1 sub { % Stack: name cmap[name] fonts /FDepVector [ fonts... i FDepVector 1 index get dup type /dicttype ne { dup /CIDFont resourcestatus { pop pop /CIDFont findresource } { /Font findresource } ifelse } if exch CMap /FontMatrices get dup length 2 index gt { exch get dup null eq { pop } { makefont } ifelse } { pop pop } ifelse } for ] readonly def /FMapType 9 def /FontMatrix matrix def /FontName 3 index def /CMap load /WMode .knownget { /WMode exch def } if /FontType 0 def pop pop currentdict end /Font defineresource} bind odef% ---------------- CMap operators ---------------- %40 dict begin% Our internal .CodeMaps structure is an array of two arrays: array 0% is the map for defined characters, array 1 is the map for notdefs.% Both are multi-level arrays indexed by the successive bytes of the% character code. Each value is either a sub-array, null, a character name,% a CID (an integer), or a character code (expressed as a byte string).% .FontIndices is a similar array holding the corresponding usefont values,% except that if the only font index is 0, the .FontIndices element is 0.% FontMatrices is the array of matrices defined by begin/endusematrix.% All of the arrays and strings are read-only after they have been built.%% Note that the code in zfcmap.c that constructs the C structures from% the PostScript structures has intimate knowledge of the above format.% ------ Font-level operators ------ %/begincmap { % - begincmap - /.CodeMaps [256 array 256 array] def /.FontIndices [0 0] def /FontMatrices [] def /.FontIndex 0 def} bind def/endcmap { % - endcmap - /.CodeMaps .CodeMaps .endmap def /.FontIndices .FontIndices .endmap def /FontMatrices FontMatrices .endmap def /CodeMap null def % for .buildcmap currentdict end .buildcmap begin} bind def/begincodespacerange { % <count> begincodespacerange - pop mark} bind def/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange - counttomark 2 idiv { .CodeMaps { 3 copy .addcodespacerange pop } forall pop pop } repeat pop} bind def/.addcodespacerange { % <code_lo> <code_hi> <map> .addcodespacerange - 2 index length 1 eq { 2 { 3 -1 roll 0 get } repeat 1 exch { 2 copy 0 put pop } for pop } { 2 index 0 get 1 3 index 0 get 6 -2 roll 2 { 1 1 index length 1 sub getinterval 6 1 roll } repeat % Stack: lo hi map lo0 1 hi0 { 2 copy get null eq { 2 copy 256 array put } if 4 copy get .addcodespacerange pop } for pop pop pop } ifelse} bind def/.endmap { % <map> .endmap <map> dup type /arraytype eq { % This might be a shared read-only array inherited via usecmap. % Don't try to update its elements if this is the case. dup wcheck { dup { .endmap exch } forall astore readonly } if } { dup type /stringtype eq { readonly } if } ifelse} bind def/usecmap { % <CMap_name> usecmap - /CMap findresource dup /.CodeMaps get dup length array copy /.CodeMaps exch def /.FontIndices get /.FontIndices exch def} bind def/usefont { % <fontID> usefont - /.FontIndex exch def} bind def/beginusematrix { % <fontID> beginusematrix - FontMatrices wcheck not FontMatrices length 2 index le or { FontMatrices length 1 index 1 add .max array dup 0 FontMatrices putinterval /FontMatrices exch def } if} bind def/endusematrix { % <matrix> endusematrix - FontMatrices 3 1 roll put} bind def% ------ Rearranged font operators ------ %/beginrearrangedfont { % <font_name> <font*> beginrearrangedfont - 10 dict begin /.FontNames exch def /.FontName exch def begincmap} bind def/endrearrangedfont { % - endrearrangedfont - (REARRANGED FONTS NOT IMPLEMENTED YET.) = flush FontName .FontNames 0 get findfont end definefont pop} bind def% ------ Character name/code selector operators ------ %/beginbfchar { % <count> beginbfchar - pop mark} bind def/endbfchar { % <code> <to_code|charname> ... endbfchar .endmapchar} bind def/beginbfrange { % <count> beginbfrange - pop mark} bind def/endbfrange { % <code_lo> <code_hi> <to_code|(charname*)> ... % endbfrange - counttomark 3 idiv { counttomark -3 roll % process in correct order .addbfrange } repeat pop} bind def/.addbfrange { % <code_lo> <code_hi> <to_code|(charname*)> % .addbfrange dup type /stringtype eq { { dup length string copy dup dup length 1 sub 2 copy get 1 add put } .addcharrange } { 2 dict begin /codes 1 index def 0 get { pop codes dup dup length 1 sub 1 exch getinterval /codes exch def dup length 0 gt { 0 get } if } .addcharrange end } ifelse} bind def% ------ CID selector operators ------ %/begincidchar { % <count> begincidchar - pop mark} bind def/endcidchar { % <code> <cid> ... endcidchar - .endmapchar} bind def/begincidrange { % <count> begincidrange - pop mark} bind def/endcidrange { % <code_lo> <code_hi> <cid_base> ... endcidrange - counttomark 3 idiv { counttomark -3 roll % process in correct order { 1 add } .addcharrange } repeat pop} bind def/.endmapchar { % -mark- <code> <value> ... .endmapchar - counttomark 2 idiv { counttomark -2 roll % process in correct order 1 index exch { } .addcharrange } repeat pop} bind def/.addcharrange { % <code_lo> <code_hi> <value_base> <next_proc> % .addcharrange - 0 .putmaprange} bind def/.putmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <0|1> % .putmaprange - 5 1 roll % Most CMaps don't involve multiple fonts. % For this reason, we create .FontIndices lazily. .FontIndices 5 index get 0 eq .FontIndex 0 ne and { % Create .FontIndices now. .CodeMaps 5 index get .makecodespace .FontIndices 6 index 3 -1 roll put } if .FontIndices 5 index get 0 ne { 3 index 3 index .FontIndex { } .FontIndices 9 index get .addmaprange .FontIndices 7 index 3 -1 roll put pop } if .CodeMaps 5 index get .addmaprange .CodeMaps 3 index 3 -1 roll put pop pop} bind def/.makecodespace { % <array|other> .makecodespace - dup type /arraytype eq { [ exch { .makecodespace } forall ] } { pop 0 } ifelse} bind def/.addmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <map> % .addmaprange <value_next> <map> % We may be updating a (partly) read-only map from another CMap. % If so, implement copy-on-write. dup wcheck not { dup length array copy } if 4 index length 1 eq { 2 { 5 -1 roll 0 get } repeat 1 exch { % Stack: value proc map code 2 copy 5 index put pop 3 -1 roll 2 index exec 3 1 roll } for } { 4 index 0 get 1 5 index 0 get 8 -2 roll 2 { 1 1 index length 1 sub getinterval 8 1 roll } repeat % Stack: lo hi next proc map lo0 1 hi0 { 6 copy get .addmaprange % Stack: lo hi oldnext proc map i next submap exch 6 1 roll 5 -1 roll pop % Stack: lo hi next proc map i submap 3 copy put pop pop } for 5 -2 roll pop pop } ifelse exch pop} bind def% ------ notdef operators ------ %/beginnotdefchar { % <count> beginnotdefchar - pop mark} bind def/endnotdefchar { % <code> <cid> ... endnotdefchar - counttomark 2 idiv { counttomark -2 roll % process in correct order 1 index exch .addnotdefrange } repeat pop} bind def/beginnotdefrange { % <count> beginnotdefrange - pop mark} bind def/endnotdefrange { % <code_lo> <code_hi> <cid> ... endnotdefrange - counttomark 3 idiv { counttomark -3 roll % process in correct order .addnotdefrange } repeat pop} bind def/.addnotdefrange { % <code_lo> <code_hi> <cid_base> .addnotdefrange - { } 1 .putmaprange} bind def% ---------------- Resource category definition ---------------- %currentdict endlanguagelevel exch 2 .setlanguagelevel/CMap /Generic /Category findresource dup length dict .copydict/Category defineresource pop % We might have loaded CID font support already./CIDInit /ProcSet 2 copy { findresource } .internalstopped % An interior `stopped' might have reset VM allocation to local.true .setglobal { pop pop 3 -1 roll } { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }ifelse exch defineresource pop.setlanguagelevel
% Copyright (C) 1995, 1996, 1997, 1998, 1999 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.
% $Id: gs_cmap.ps,v 1.1 2000/03/09 08:40:39 lpd Exp $
% ProcSet for implementing CMap resources.
% When this is run, systemdict is still writable.
% NOTE: Rearranged fonts are not implemented yet.
% ---------------- Public operators ---------------- %
% composefont doesn't appear in CMap files -- it's documented in
% the "PostScript Language Reference Manual Supplement".
/composefont { % <name> <cmap|cmapname> <fonts> composefont <font>
10 dict begin
/CMap 2 index dup type /dicttype ne { /CMap findresource } if def
/FDepVector 1 index cvlit def % temporarily
/Encoding [ 0 1 FDepVector length 1 sub { } for ] def
/FDepVector [ 0 1 FDepVector length 1 sub {
% Stack: name cmap[name] fonts /FDepVector [ fonts... i
FDepVector 1 index get
dup type /dicttype ne {
dup /CIDFont resourcestatus {
pop pop /CIDFont findresource
} {
/Font findresource
} ifelse
} if
exch CMap /FontMatrices get dup length 2 index gt {
exch get dup null eq { pop } { makefont } ifelse
} {
pop pop
} ifelse
} for ] readonly def
/FMapType 9 def
/FontMatrix matrix def
/FontName 3 index def
/CMap load /WMode .knownget { /WMode exch def } if
/FontType 0 def
pop pop currentdict end /Font defineresource
} bind odef
% ---------------- CMap operators ---------------- %
40 dict begin
% Our internal .CodeMaps structure is an array of two arrays: array 0
% is the map for defined characters, array 1 is the map for notdefs.
% Both are multi-level arrays indexed by the successive bytes of the
% character code. Each value is either a sub-array, null, a character name,
% a CID (an integer), or a character code (expressed as a byte string).
% .FontIndices is a similar array holding the corresponding usefont values,
% except that if the only font index is 0, the .FontIndices element is 0.
% FontMatrices is the array of matrices defined by begin/endusematrix.
% All of the arrays and strings are read-only after they have been built.
%
% Note that the code in zfcmap.c that constructs the C structures from
% the PostScript structures has intimate knowledge of the above format.
% ------ Font-level operators ------ %
/begincmap { % - begincmap -
/.CodeMaps [256 array 256 array] def
/.FontIndices [0 0] def
/FontMatrices [] def
/.FontIndex 0 def
} bind def
/endcmap { % - endcmap -
/.CodeMaps .CodeMaps .endmap def
/.FontIndices .FontIndices .endmap def
/FontMatrices FontMatrices .endmap def
/CodeMap null def % for .buildcmap
currentdict end .buildcmap begin
} bind def
/begincodespacerange { % <count> begincodespacerange -
pop mark
} bind def
/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange -
counttomark 2 idiv {
.CodeMaps { 3 copy .addcodespacerange pop } forall pop pop
} repeat pop
} bind def
/.addcodespacerange { % <code_lo> <code_hi> <map> .addcodespacerange -
2 index length 1 eq
{ 2 { 3 -1 roll 0 get } repeat 1 exch
{ 2 copy 0 put pop } for pop
}
{ 2 index 0 get 1 3 index 0 get
6 -2 roll
2 { 1 1 index length 1 sub getinterval 6 1 roll } repeat
% Stack: lo hi map lo0 1 hi0
{ 2 copy get null eq { 2 copy 256 array put } if
4 copy get .addcodespacerange pop
}
for pop pop pop
}
ifelse
} bind def
/.endmap { % <map> .endmap <map>
dup type /arraytype eq {
% This might be a shared read-only array inherited via usecmap.
% Don't try to update its elements if this is the case.
dup wcheck {
dup { .endmap exch } forall astore readonly
} if
} {
dup type /stringtype eq { readonly } if
} ifelse
} bind def
/usecmap { % <CMap_name> usecmap -
/CMap findresource
dup /.CodeMaps get dup length array copy /.CodeMaps exch def
/.FontIndices get /.FontIndices exch def
} bind def
/usefont { % <fontID> usefont -
/.FontIndex exch def
} bind def
/beginusematrix { % <fontID> beginusematrix -
FontMatrices wcheck not FontMatrices length 2 index le or {
FontMatrices length 1 index 1 add .max array
dup 0 FontMatrices putinterval
/FontMatrices exch def
} if
} bind def
/endusematrix { % <matrix> endusematrix -
FontMatrices 3 1 roll put
} bind def
% ------ Rearranged font operators ------ %
/beginrearrangedfont { % <font_name> <font*> beginrearrangedfont -
10 dict begin
/.FontNames exch def
/.FontName exch def
begincmap
} bind def
/endrearrangedfont { % - endrearrangedfont -
(REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
FontName .FontNames 0 get findfont end definefont pop
} bind def
% ------ Character name/code selector operators ------ %
/beginbfchar { % <count> beginbfchar -
pop mark
} bind def
/endbfchar { % <code> <to_code|charname> ... endbfchar
.endmapchar
} bind def
/beginbfrange { % <count> beginbfrange -
pop mark
} bind def
/endbfrange { % <code_lo> <code_hi> <to_code|(charname*)> ...
% endbfrange -
counttomark 3 idiv {
counttomark -3 roll % process in correct order
.addbfrange
} repeat pop
} bind def
/.addbfrange { % <code_lo> <code_hi> <to_code|(charname*)>
% .addbfrange
dup type /stringtype eq {
{ dup length string copy dup dup length 1 sub 2 copy get 1 add put }
.addcharrange
} {
2 dict begin /codes 1 index def 0 get
{ pop codes dup dup length 1 sub 1 exch getinterval /codes exch def
dup length 0 gt { 0 get } if
}
.addcharrange end
} ifelse
} bind def
% ------ CID selector operators ------ %
/begincidchar { % <count> begincidchar -
pop mark
} bind def
/endcidchar { % <code> <cid> ... endcidchar -
.endmapchar
} bind def
/begincidrange { % <count> begincidrange -
pop mark
} bind def
/endcidrange { % <code_lo> <code_hi> <cid_base> ... endcidrange -
counttomark 3 idiv {
counttomark -3 roll % process in correct order
{ 1 add } .addcharrange
} repeat pop
} bind def
/.endmapchar { % -mark- <code> <value> ... .endmapchar -
counttomark 2 idiv {
counttomark -2 roll % process in correct order
1 index exch { } .addcharrange
} repeat pop
} bind def
/.addcharrange { % <code_lo> <code_hi> <value_base> <next_proc>
% .addcharrange -
0 .putmaprange
} bind def
/.putmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <0|1>
% .putmaprange -
5 1 roll
% Most CMaps don't involve multiple fonts.
% For this reason, we create .FontIndices lazily.
.FontIndices 5 index get 0 eq .FontIndex 0 ne and {
% Create .FontIndices now.
.CodeMaps 5 index get .makecodespace
.FontIndices 6 index 3 -1 roll put
} if
.FontIndices 5 index get 0 ne {
3 index 3 index .FontIndex { } .FontIndices 9 index get .addmaprange
.FontIndices 7 index 3 -1 roll put pop
} if
.CodeMaps 5 index get .addmaprange
.CodeMaps 3 index 3 -1 roll put pop
pop
} bind def
/.makecodespace { % <array|other> .makecodespace -
dup type /arraytype eq {
[ exch { .makecodespace } forall ]
} {
pop 0
} ifelse
} bind def
/.addmaprange { % <code_lo> <code_hi> <value_base> <next_proc> <map>
% .addmaprange <value_next> <map>
% We may be updating a (partly) read-only map from another CMap.
% If so, implement copy-on-write.
dup wcheck not { dup length array copy } if
4 index length 1 eq
{ 2 { 5 -1 roll 0 get } repeat 1 exch
{ % Stack: value proc map code
2 copy 5 index put pop
3 -1 roll 2 index exec 3 1 roll
} for
}
{ 4 index 0 get 1 5 index 0 get
8 -2 roll
2 { 1 1 index length 1 sub getinterval 8 1 roll } repeat
% Stack: lo hi next proc map lo0 1 hi0
{ 6 copy get .addmaprange
% Stack: lo hi oldnext proc map i next submap
exch 6 1 roll 5 -1 roll pop
% Stack: lo hi next proc map i submap
3 copy put pop pop
}
for 5 -2 roll pop pop
}
ifelse exch pop
} bind def
% ------ notdef operators ------ %
/beginnotdefchar { % <count> beginnotdefchar -
pop mark
} bind def
/endnotdefchar { % <code> <cid> ... endnotdefchar -
counttomark 2 idiv {
counttomark -2 roll % process in correct order
1 index exch .addnotdefrange
} repeat pop
} bind def
/beginnotdefrange { % <count> beginnotdefrange -
pop mark
} bind def
/endnotdefrange { % <code_lo> <code_hi> <cid> ... endnotdefrange -
counttomark 3 idiv {
counttomark -3 roll % process in correct order
.addnotdefrange
} repeat pop
} bind def
/.addnotdefrange { % <code_lo> <code_hi> <cid_base> .addnotdefrange -
{ } 1 .putmaprange
} bind def
% ---------------- Resource category definition ---------------- %
currentdict end
languagelevel exch 2 .setlanguagelevel
/CMap /Generic /Category findresource dup length dict .copydict
/Category defineresource pop
% We might have loaded CID font support already.
/CIDInit /ProcSet 2 copy { findresource } .internalstopped
% An interior `stopped' might have reset VM allocation to local.
true .setglobal
{ pop pop 3 -1 roll }
{ dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
ifelse exch defineresource pop
.setlanguagelevel