You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.4 KiB

1 month ago
  1. % Copyright (C) 2001-2023 Artifex Software, Inc.
  2. % All Rights Reserved.
  3. %
  4. % This software is provided AS-IS with no warranty, either express or
  5. % implied.
  6. %
  7. % This software is distributed under license and may not be copied,
  8. % modified or distributed except as expressly authorized under the terms
  9. % of the license contained in the file LICENSE in this distribution.
  10. %
  11. % Refer to licensing information at http://www.artifex.com or contact
  12. % Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  13. % CA 94129, USA, for further information.
  14. %
  15. % Construct an inverse map from CIDs to codes.
  16. % Create an inverse map from CIDs to code values.
  17. % We only use this for 16-bit Unicode, so it has some limitations.
  18. % After invoking .cmap2code, loading a CMap file prints out the map
  19. % instead of doing what it usually does. For example:
  20. %
  21. % gs -dNODISPLAY -dBATCH lib/cid2code.ps -c .cmap2code\
  22. % -f Resource/CMap/UniJIS-UCS2-H > mapfile
  23. /.cmap2codedict 10 dict begin
  24. /begincmap {
  25. mark
  26. } def
  27. /endcmap {
  28. % Stack: mark code_lo1 code_hi1 cid1 ...
  29. 20 dict begin
  30. /depth counttomark 3 sub def
  31. % Do a first pass to determine the maximum CID.
  32. 0 0 3 depth {
  33. 1 add /d exch def
  34. d index d 2 add index 1 get add d 3 add index 1 get sub .max
  35. } for
  36. 1 add /ncid exch def
  37. /map ncid 2 mul string def
  38. % Now fill in the map.
  39. 0 3 depth {
  40. /d exch def
  41. d index 2 mul /cid2 exch def
  42. d 1 add index /hi exch def
  43. d 2 add index 2 string copy /lo exch def
  44. lo 1 get 1 hi 1 get {
  45. map cid2 lo 0 get put
  46. map cid2 1 add 3 -1 roll put
  47. /cid2 cid2 2 add def
  48. } for
  49. } for
  50. % Print the map.
  51. (%stdout) (w) file
  52. dup (<) print
  53. dup /ASCIIHexEncode filter
  54. dup map writestring
  55. closefile
  56. () = flush
  57. closefile
  58. end
  59. } def
  60. %/begincodespacerange
  61. /endcodespacerange {cleartomark} def
  62. %/usecmap
  63. %/beginbfchar
  64. /endbfchar {cleartomark} def
  65. %/beginbfrange
  66. /endbfrange {cleartomark} def
  67. %/begincidchar
  68. /endcidchar {
  69. counttomark 2 idiv { dup counttomark 1 add 3 roll } repeat pop
  70. } def
  71. %/begincidrange
  72. /endcidrange {
  73. counttomark 1 add -1 roll pop
  74. } def
  75. %/beginnotdefchar
  76. /endnotdefchar {cleartomark} def
  77. %/beginnotdefrange
  78. /endnotdefrange {cleartomark} def
  79. currentdict end readonly def
  80. /.cmap2code { % - .cmap2code -
  81. /CIDInit /ProcSet findresource dup length dict copy
  82. .cmap2codedict { 3 copy put pop pop } forall
  83. /CIDInit exch /ProcSet defineresource pop
  84. } def
  85. % Extract and print reverse mapping information from a cid2code.txt file.
  86. /.printhex2 { % <int16> .printhex2 -
  87. (<) print
  88. 16#10000 add 16 =string cvrs 1 4 getinterval print
  89. (>) print
  90. } def
  91. /.cid2code { % <cmaptemplate> <file> <column> .cid2code -
  92. 30 dict begin
  93. /column exch def
  94. (r) file /f exch def
  95. (%!) =
  96. (/CIDInit /ProcSet findresource begin 12 dict begin begincmap) =
  97. % Print the information from the template.
  98. {
  99. exch ==only ( ) print
  100. dup type /dicttype eq {
  101. dup length =only ( dict dup begin) = {
  102. ( ) print exch ===only ( ) print ===only ( def) =
  103. } forall (end def) =
  104. } {
  105. ===only
  106. } ifelse ( def) =
  107. } forall
  108. % Read the data from the cid2code.txt file.
  109. {
  110. f =string readline pop (CID\t) anchorsearch { pop pop exit } if pop
  111. } loop
  112. /map [ {
  113. f =string readline not { pop exit } if
  114. column { (\t) search pop pop pop } repeat
  115. (\t) search { exch pop exch pop } if
  116. (,) search { exch pop exch pop } if
  117. dup length 4 ne { pop (*) } if
  118. dup (*) eq { pop (0000) } if
  119. (16#) exch concatstrings cvi
  120. } loop ] def
  121. % Print the code space range(s).
  122. /maxcid map length 1 sub def
  123. mark maxcid
  124. dup 255 and 255 eq {
  125. 0 exch
  126. } {
  127. dup 16#ff00 and exch 0 2 index 1 sub
  128. } ifelse
  129. counttomark 2 idiv dup =only ( begincodespacerange) = {
  130. exch .printhex2 .printhex2 () =
  131. } repeat (endcodespacerange) =
  132. % Print the map data.
  133. 0 1 100 maxcid {
  134. /lo exch def
  135. /hi lo 99 add maxcid .min def
  136. 0 lo 1 hi { map exch get 0 ne { 1 add } if } for
  137. dup 0 eq {
  138. pop
  139. } {
  140. =only ( begincidchar) = lo 1 hi {
  141. map 1 index get dup 0 eq { pop pop } { exch .printhex2 = } ifelse
  142. } for (endcidchar) =
  143. } ifelse
  144. } for
  145. % Wrap up.
  146. (endcmap CMapName currentdict /CMap defineresource pop end end) =
  147. f closefile
  148. end
  149. } bind def