... endbfchar counttomark 2 idiv { counttomark -2 roll % process in correct order .addbfchar } repeat 1 .appendmap } bind def /beginbfrange { % beginbfrange - pop mark } bind def /endbfrange { % ... % endbfrange - counttomark 3 idiv { counttomark -3 roll % process in correct order dup type dup /arraytype eq exch /packedarraytype eq or { % Array value, split up. exch pop { % Stack: code to_code|charname 1 index exch .addbfchar % Increment the code. As noted above, we require % that only the last byte vary, but we still must % mask it after incrementing, in case the last % value was 0xff. % Stack: code prefix params key value fontindex 6 -1 roll dup length string copy dup dup length 1 sub 2 copy get 1 add 255 and put } forall pop } { % Single value, handle directly. .addbfrange } ifelse } repeat 1 .appendmap } bind def /.addbfchar { % .addbfchar % 1 index exch .addbfrange } bind def /.addbfrange { % % .addbfrange <> 4 string dup 3 3 index type /nametype eq { 2 index 2 1 put % dst = CODE_VALUE_GLYPH, see gxfcmap.h . 4 -1 roll 1 array astore 4 1 roll 4 } { 2 index 2 2 put % dst = CODE_VALUE_CHARS, see gxfcmap.h . 3 index length } ifelse put % Stack: code_lo code_hi value params 3 index 3 index eq { % Single value. 3 -1 roll pop exch () exch } { % Range. dup 0 4 index length put dup 1 1 put 4 2 roll 1 index dup length 1 sub 0 exch getinterval 5 1 roll % prefix % Stack: prefix value params code_lo code_hi concatstrings 3 -1 roll } ifelse .FontIndex } bind def % ------ CID selector operators ------ % /begincidchar { % begincidchar - pop mark } bind def /endcidchar { % ... endcidchar - 1 .endmapchars } bind def /begincidrange { % begincidrange - pop mark } bind def /endcidrange { % ... endcidrange - 1 .endmapranges } bind def /.endmapchars { % -mark- ... .endmapchars - counttomark 1 add 1 roll counttomark 2 idiv { counttomark -2 roll % process in correct order exch % % Construct prefix, params, key, value, font_index dup length 1 eq { % 1-byte <00 00 00 02> () % } { % N-byte dup 0 1 getinterval exch % make 1-byte prefix 4 string dup 0 USE_CIDCHAR_AS_RANGE { <00 01 00 02> % skelton for param } { <00 00 00 02> % skelton for param } ifelse putinterval exch % dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
.addbfchar % 1 index exch .addbfrange } bind def /.addbfrange { % % .addbfrange <> 4 string dup 3 3 index type /nametype eq { 2 index 2 1 put % dst = CODE_VALUE_GLYPH, see gxfcmap.h . 4 -1 roll 1 array astore 4 1 roll 4 } { 2 index 2 2 put % dst = CODE_VALUE_CHARS, see gxfcmap.h . 3 index length } ifelse put % Stack: code_lo code_hi value params 3 index 3 index eq { % Single value. 3 -1 roll pop exch () exch } { % Range. dup 0 4 index length put dup 1 1 put 4 2 roll 1 index dup length 1 sub 0 exch getinterval 5 1 roll % prefix % Stack: prefix value params code_lo code_hi concatstrings 3 -1 roll } ifelse .FontIndex } bind def % ------ CID selector operators ------ % /begincidchar { % begincidchar - pop mark } bind def /endcidchar { % ... endcidchar - 1 .endmapchars } bind def /begincidrange { % begincidrange - pop mark } bind def /endcidrange { % ... endcidrange - 1 .endmapranges } bind def /.endmapchars { % -mark- ... .endmapchars - counttomark 1 add 1 roll counttomark 2 idiv { counttomark -2 roll % process in correct order exch % % Construct prefix, params, key, value, font_index dup length 1 eq { % 1-byte <00 00 00 02> () % } { % N-byte dup 0 1 getinterval exch % make 1-byte prefix 4 string dup 0 USE_CIDCHAR_AS_RANGE { <00 01 00 02> % skelton for param } { <00 00 00 02> % skelton for param } ifelse putinterval exch % dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
... endcidchar - 1 .endmapchars } bind def /begincidrange { % begincidrange - pop mark } bind def /endcidrange { % ... endcidrange - 1 .endmapranges } bind def /.endmapchars { % -mark- ... .endmapchars - counttomark 1 add 1 roll counttomark 2 idiv { counttomark -2 roll % process in correct order exch % % Construct prefix, params, key, value, font_index dup length 1 eq { % 1-byte <00 00 00 02> () % } { % N-byte dup 0 1 getinterval exch % make 1-byte prefix 4 string dup 0 USE_CIDCHAR_AS_RANGE { <00 01 00 02> % skelton for param } { <00 00 00 02> % skelton for param } ifelse putinterval exch % dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
... .endmapchars - counttomark 1 add 1 roll counttomark 2 idiv { counttomark -2 roll % process in correct order exch % % Construct prefix, params, key, value, font_index dup length 1 eq { % 1-byte <00 00 00 02> () % } { % N-byte dup 0 1 getinterval exch % make 1-byte prefix 4 string dup 0 USE_CIDCHAR_AS_RANGE { <00 01 00 02> % skelton for param } { <00 00 00 02> % skelton for param } ifelse putinterval exch % dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
% Construct prefix, params, key, value, font_index dup length 1 eq { % 1-byte <00 00 00 02> () % } { % N-byte dup 0 1 getinterval exch % make 1-byte prefix 4 string dup 0 USE_CIDCHAR_AS_RANGE { <00 01 00 02> % skelton for param } { <00 00 00 02> % skelton for param } ifelse putinterval exch % dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
dup length % N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N 1 sub % N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 dup % N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 N-1 3 index % N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 N-1 exch % N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 N-1 0 exch % N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 0 N-1 put % N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
N-1 1 exch % 1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
1 N-1 getinterval % USE_CIDCHAR_AS_RANGE { dup length 2 mul string % dup % 2 index % 0 exch putinterval % dup % 3 -1 roll % dup length % N-1 exch putinterval % } if } ifelse 4 -1 roll % .endmapvalue % % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge! char\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges CMERGE_DEBUG { ( prefix:) print 4 index =only ( param:) print 3 index =only ( key:) print 2 index =only ( hex_cid:) print 1 index =only ( font_idx:) print 0 index //== exec flush } if } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapranges { % -mark- ... % .endmapranges - counttomark 1 add 1 roll counttomark 3 idiv { counttomark -3 roll % process in correct order % Construct prefix, params, key_lo, key_hi, value, font_index 3 1 roll % % prefix key % 1-byte code: () . % 1-byte range: () . % N-byte code: . (*) % N-byte range: (*) (*) dup 2 index eq { % == % 0: prefix_len for 1-byte code % 1: prefix_len for N-byte code dup length 1 eq { 0 } { 1 } ifelse } { % != % calculate prefix_len for *-byte range dup length 1 sub % 0 % initial value for N { % (code_len-1) N dup 2 index ge { exit } if % if (N >= len - 1) exit 3 index 1 index get % N-th byte of code_lo 3 index 2 index get % N-th byte of code_hi eq { 1 add } { exit } ifelse } loop exch pop % discard } ifelse % cid_base code_lo code_hi prefix_len % Althogh Adobe CPSI with native CID/CMap support accept % multi-dimensional range specification in notdef & cidrange % (and CID is calculated as relative position in multi-dimensional % range), but older CPSI & ATM cannot handle it. % % GS accepts such specification, but it's recommended to keep % from using this feature for notdef & cidrange. % Following is a disabler of this feature. % ------------------------------------------------------------- % counttomark 1 add index % get map# % 0 ne { % if not codespacerange % 1 index length % get code length % 1 index % get prefix length % sub % calculate key length % 1 gt { % if (key_len > 1), % (.endmapranges error) = flush % (multi-dimensional range specification is used out of codespacerange) % = flush % (/) =only % CMapName CMapName length string cvs =only % (: <) =only % 2 index (%stdout) (w) file exch writehexstring % (> <) =only % 1 index (%stdout) (w) file exch writehexstring % (>\n) =only flush % quit % } if % } if % ------------------------------------------------------------- 1 index exch 0 exch getinterval % cid_base code_lo code_hi prefix dup length 3 index length exch sub % cid_base code_lo code_hi prefix range_len dup 255 gt { (too long coderange specification for current GS\n) print /.endmapranges cvx /rangecheck signalerror } if <00 01 00 02> 4 string copy % create initialized param dup 0 4 -1 roll put % put range_len into param % get key_hi 3 -1 roll dup length 3 index length dup 3 1 roll sub getinterval % get key_lo 4 -1 roll dup length 4 index length dup 3 1 roll sub getinterval % make "keys" (concatenated key_lo + key_hi) exch concatstrings % 4 -1 roll .endmapvalue % See if we can merge with the previous value. % The prefix, params, and font index must match. % prefix params keys value fontindex counttomark 5 gt { % 2 (or more) ranges (1 range = 5 item) 4 index 10 index eq % compare prefix 4 index 10 index eq and % compare params 1 index 7 index eq and % compare fontindex { CMAPDEBUG { (merge!\n) print } if pop 4 2 roll pop pop % prefix params keys value fontindex keys2 value2 5 -1 roll 3 -1 roll concatstrings % prefix params value fontindex value2 keys' 4 -1 roll 3 -1 roll concatstrings % prefix params fontindex keys' values' 3 -1 roll } if } if % end of 2 (or more) ranges } repeat counttomark 2 add -1 roll .appendmap } bind def /.endmapvalue { % .endmapvalue (hi,lo) .FontIndex 2 string dup 0 3 index -8 bitshift put % value dup 1 4 -1 roll 255 and put .FontIndex % font_index } bind def % ------ notdef operators ------ % /beginnotdefchar { % beginnotdefchar - pop mark } bind def /endnotdefchar { % ... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel
... endnotdefchar - 2 .endmapchars } bind def /beginnotdefrange { % beginnotdefrange - pop mark } bind def /endnotdefrange { % ... endnotdefrange - 2 .endmapranges } bind def % ---------------- Resource category definition ---------------- % currentdict end languagelevel exch 2 .setlanguagelevel /CMap /Generic /Category findresource dup length dict .copydict dup /InstanceType /dicttype put dup /DefineResource { % The AdobePS5 Windows driver emits code that attempts to % create CMaps without the required CMapName entry. % Work around this here. dup /CMapName known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup gcheck 2 index gcheck not and { exch .currentglobal exch //true .setglobal dup length string copy exch .setglobal exch } if dup /CMapName 3 index put } if % Adobe PS CET 23-25 and others define an almost empty CMap. Tolerate this. % With the above, we can actually tolerate: /name << >> defineresource dup /CIDSystemInfo known not { dup wcheck not { .currentglobal exch dup wcheck .setglobal dup length dict .copydict exch .setglobal } if dup /CIDSystemInfo [ //null ] put } if dup /CodeMap .knownget { //null eq { .buildcmap } if } if /Generic /Category findresource /DefineResource get exec } bind executeonly put /Category defineresource pop % We might have loaded CID font support already. /CIDInit /ProcSet 2 copy { findresource } //.internalstopped exec % 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 currentdict /.rewriteTempMapsNotDef .undef .setlanguagelevel