/usr/share/ghostscript/9.26/Resource/Init/gs_cmap.ps is in libgs9-common 9.26a~dfsg-0+deb9u1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | % Copyright (C) 2001-2018 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% Refer to licensing information at http://www.artifex.com or contact
% Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato,
% CA 94945, U.S.A., +1(415)492-9861, for further information.
%
% ProcSet for implementing CMap resources.
% When this is run, systemdict is still writable.
% NOTE: Rearranged fonts are not implemented yet.
[
/CMERGE_DEBUG
/USE_CIDCHAR_AS_RANGE
] {dup where {pop pop} { currentdict exch //false def pop } ifelse} forall
% ---------------- Public operators ---------------- %
/.rewriteTempMapsNotDef {
%
% Before building .CodeMapData from .TempMaps,
% we need to replace dst type codes in the notdef map with the value 3,
% which corresponds to CODE_VALUE_NOTDEF, see gxfcmap.h .
%
CMAPDEBUG { (rewriting TempMapsNotDef\n) print flush } if
.TempMaps 2 get
dup length 0 gt {
0 get
CMAPDEBUG { (...original...\n) print flush } if
1 5 2 index length 1 sub {
{ 1 index exch get 2 3 put } stopped
{ CMAPDEBUG { (cannot rewrite\n) print flush } if }
{ CMAPDEBUG { (rewrite\n) print flush } if } ifelse
} for
} if
pop
CMAPDEBUG { (...FINISHED...\n) print } if
} bind def
/.composefontdict { % <name> <cmap|cmapname> <fonts> composefont <name> <font_dict>
10 dict begin
/CMap 2 index dup type /dicttype ne { /CMap findresource } if def
/FDepVector 1 index cvlit def % temporarily
/Encoding [ 0 1 FDepVector length 1 sub { } for ] def
/FontInfo 1 dict def % for .processToUnicode in pdf_font.ps .
/FDepVector [ 0 1 FDepVector length 1 sub {
% Stack: name cmap[name] fonts /FDepVector [ fonts... i
FDepVector 1 index get
dup type /dicttype ne {
dup /CIDFont resourcestatus {
pop pop /CIDFont
} {
/Font
} ifelse findresource
} if
exch CMap /FontMatrices get dup length 2 index gt {
exch get dup //null eq { pop } { makefont } ifelse
} {
pop pop
} ifelse
} for ] readonly def
/FMapType 9 def
/FontMatrix matrix def
/FontName 3 index def
CMap /WMode .knownget { /WMode exch def } if
/FontType 0 def
pop pop currentdict end
} bind odef
% composefont doesn't appear in CMap files -- it's documented in
% the "PostScript Language Reference Manual Supplement".
/composefont { % <name> <cmap|cmapname> <fonts> composefont <font>
.composefontdict /Font defineresource
} bind def
% ---------------- CMap operators ---------------- %
40 dict begin
% Our internal .CodeMapData structure closely mirrors the structures
% defined in gxfcmap.h (q.v.). () indicate a string, [] indicate an array,
% ? indicates a Boolean, # indicates an integer, {} for grouping.
% [[[(first) (last) ...]+] % code space ranges
% [[(prefix) (key_size,?is_range,value_type,value_size) (keys...)
% {(values...) | [value ...]} #font_index ]+] % code mappings
% ...]
% <<same>> % notdef mappings
% ]
% FontMatrices is the array of matrices defined by begin/endusematrix.
% All of the arrays and strings are read-only after they have been built.
%
% Note that the code in zfcmap.c that constructs the C structures from
% the PostScript structures has intimate knowledge of the above format.
% ****** NOTE: The code currently only handles "well-behaved" CMaps:
% - CID values only (no bfchars), 16-bit
% - Entries (both code space and map) must be sorted
% - Only the last byte must vary in each map range, except for
% the identity mapping
% ------ Font-level operators ------ %
/begincmap { % - begincmap -
/.CodeMapData [[[]] [[]] [[]]] def
/FontMatrices [] def
/.FontIndex 0 def
/.TempMaps [20 dict 50 dict 50 dict] def
/CodeMap //null def % for .buildcmap
} bind def
/endcmap { % - endcmap -
.rewriteTempMapsNotDef
CMAPDEBUG {
2 (*** undefined charmap ***)
1 (*** defined charmap ***)
0 (*** code space ranges ***)
3 { =
.TempMaps exch get
0 1 2 index length 1 sub {
dup //== exec (\t) print
1 index exch get //== exec
} for
pop
} repeat
} if
/.CodeMapData dup load [ exch
.TempMaps aload pop begin begin begin
{
[ exch aload pop
0 1 currentdict length 1 sub {
currentdict exch get
} for
]
end
} forall
] .endmap def
CMAPDEBUG {
(*** Content of .CodeMapData ***) =
0 .CodeMapData { exch dup //== exec 1 add exch (\t) print //== exec } forall
pop
} if
currentdict /.TempMaps undef
/FontMatrices FontMatrices .endmap def
} bind def
/.endmap { % <map> .endmap <map>
dup type /arraytype eq {
% This might be a shared read-only array inherited via usecmap.
% Don't try to update its elements if this is the case.
dup wcheck {
0 1 2 index length 1 sub {
2 copy 2 copy get .endmap put pop
} for readonly
} if
} {
dup type /stringtype eq { readonly } if
} ifelse
} bind def
/.appendmap { % -mark- <elt> ... <array#> .appendmap -
.TempMaps exch get counttomark 1 add 1 roll
] 1 index length exch put
} bind def
/begincodespacerange { % <count> begincodespacerange -
pop mark
} bind def
/endcodespacerange { % <code_lo> <code_hi> ... endcodespacerange -
0 .appendmap
} bind def
/usecmap { % <CMap_name> usecmap -
/CMap findresource dup
% Copy the top level of .CodeMapData
/.CodeMapData exch /.CodeMapData get copyarray def
/FontMatrices exch /FontMatrices get copyarray def
} bind def
/usefont { % <fontID> usefont -
/.FontIndex exch def
} bind def
/beginusematrix { % <fontID> beginusematrix -
FontMatrices wcheck not FontMatrices length 2 index le or {
FontMatrices length 1 index 1 add .max array
dup 0 FontMatrices putinterval
/FontMatrices exch def
} if
} bind def
/endusematrix { % <matrix> endusematrix -
FontMatrices 3 1 roll put
} bind def
% ------ Rearranged font operators ------ %
/beginrearrangedfont { % <font_name> <font*> beginrearrangedfont -
10 dict begin
/.FontNames exch def
/.FontName exch def
begincmap
} bind def
/endrearrangedfont { % - endrearrangedfont -
(REARRANGED FONTS NOT IMPLEMENTED YET.) = flush
.FontName .FontNames 0 get findfont end definefont pop
} bind def
% ------ Character name/code selector operators ------ %
/beginbfchar { % <count> beginbfchar -
pop mark
} bind def
/endbfchar { % <code> <to_code|charname> ... endbfchar
counttomark 2 idiv {
counttomark -2 roll % process in correct order
.addbfchar
} repeat 1 .appendmap
} bind def
/beginbfrange { % <count> beginbfrange -
pop mark
} bind def
/endbfrange { % <code_lo> <code_hi> <to_code|(charname*)> ...
% endbfrange -
counttomark 3 idiv {
counttomark -3 roll % process in correct order
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 { % <code> <to_code|charname> .addbfchar
% <prefix> <params> <key> <value> <font_index>
1 index exch .addbfrange
} bind def
/.addbfrange { % <code_lo> <code_hi> <to_code|charname>
% .addbfrange <<same as .addbfchar>>
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 { % <count> begincidchar -
pop mark
} bind def
/endcidchar { % <code> <cid> ... endcidchar -
1 .endmapchars
} bind def
/begincidrange { % <count> begincidrange -
pop mark
} bind def
/endcidrange { % <code_lo> <code_hi> <cid_base> ... endcidrange -
1 .endmapranges
} bind def
/.endmapchars { % -mark- <code> <cid> ... <map#> .endmapchars -
counttomark 1 add 1 roll
counttomark 2 idiv {
counttomark -2 roll % process in correct order
exch % <cid> <code>
% Construct prefix, params, key, value, font_index
dup length 1 eq { % 1-byte
<00 00 00 02> () % <prefix> <param> <null_key>
} { % 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 % <prefix> <param> <code>
dup length % <prefix> <param> <code> N
1 sub % <prefix> <param> <code> N-1
dup % <prefix> <param> <code> N-1 N-1
3 index % <prefix> <param> <code> N-1 N-1 <param>
exch % <prefix> <param> <code> N-1 <param> N-1
0 exch % <prefix> <param> <code> N-1 <param> 0 N-1
put % <prefix> <param'> <code> N-1
1 exch % <prefix> <param'> <code> 1 N-1
getinterval % <prefix> <param'> <key>
USE_CIDCHAR_AS_RANGE {
dup length 2 mul string % <key> <dkey>
dup % <key> <dkey> <dkey>
2 index % <key> <dkey> <dkey> <key>
0 exch putinterval % <key> <dkey'>
dup % <key> <dkey'> <dkey'>
3 -1 roll % <dkey'> <dkey'> <key>
dup length % <dkey'> <dkey'> <key> N-1
exch putinterval % <dkey''>
} if
} ifelse
4 -1 roll % <prefix> <param'> <key> <cid>
.endmapvalue % <prefix> <param'> <key> <hex_cid> <font_idx>
% 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- <code_lo> <code_hi> <cid_base> ... <map#>
% .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 % <cid_base> <code_lo> <code_hi>
% prefix key
% 1-byte code: () .
% 1-byte range: () .
% N-byte code: . (*)
% N-byte range: (*) (*)
dup 2 index eq { % <code_lo> == <code_hi>
% 0: prefix_len for 1-byte code
% 1: prefix_len for N-byte code
dup length 1 eq { 0 } { 1 } ifelse
} { % <code_lo> != <code_hi>
% calculate prefix_len for *-byte range
dup length 1 sub % <cid_base> <code_lo> <code_hi> <code_len-1>
0 % initial value for N
{ % <cid_base> <code_lo> <code_hi> (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 <code_len-1>
} 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 { % <cid> .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 { % <count> beginnotdefchar -
pop mark
} bind def
/endnotdefchar { % <code> <cid> ... endnotdefchar -
2 .endmapchars
} bind def
/beginnotdefrange { % <count> beginnotdefrange -
pop mark
} bind def
/endnotdefrange { % <code_lo> <code_hi> <cid> ... 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
% An interior `stopped' might have reset VM allocation to local.
//true .setglobal
{ pop pop 3 -1 roll }
{ dup length 4 index length add dict .copydict 4 -1 roll exch .copydict }
ifelse exch defineresource pop
.setlanguagelevel
|