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.

282 lines
8.0 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. % Redefine CIDFont category with cidfmap .
  16. languagelevel 2 .setlanguagelevel
  17. 4 dict begin
  18. /CategoryName /CIDFont def
  19. /MapFileName (cidfmap) def
  20. /IsMyRecord % <raw_record> -> <raw_record> bool
  21. { % Only for client's needs.
  22. dup type /stringtype eq exch
  23. dup type /nametype eq 3 -1 roll or
  24. } .internalbind def
  25. /RecordVirtualMethods 3 dict begin
  26. /MakeInstance % <Name> <record> MakeInstance <Name> <Instance> <size>
  27. { % We know that currentdict is the category.
  28. /Substitute get dup type /stringtype eq
  29. {
  30. (r) file dup cvx exec closefile
  31. dup
  32. } if
  33. FindResource % /Name <<CIDFont>>
  34. dup length dict copy % /Name <<CIDFont>>
  35. 1 index ResourceStatus pop exch pop % /Name <<CIDFont>> size
  36. } .internalbind def
  37. /GetFilePath % <scratch> <Name> <record> GetFilePath <filepath>
  38. { % We know that currentdict is the category.
  39. exch pop
  40. /Substitute get dup type /stringtype eq not
  41. {
  42. exch ResourceFileName
  43. } if
  44. } .internalbind def
  45. /GetSize % <Name> <record> GetSize <size>
  46. { % We know that currentdict is the category.
  47. dup /Substitute get dup type /stringtype eq
  48. {
  49. % The simplest solution is to instantiate the resource
  50. pop //MakeInstance exec
  51. 3 1 roll pop pop
  52. }
  53. {
  54. exch pop
  55. ResourceStatus {
  56. exch pop exch pop
  57. } {
  58. /undefinedresource signalerror
  59. } ifelse
  60. }ifelse
  61. } .internalbind def
  62. /GetCSI % <record> GetCSI null
  63. % <record> GetCSI dict
  64. { % We know that currentdict is the category.
  65. RESMPDEBUG { (cidfm GetCSI beg ) = } if
  66. dup /Substitute get dup type /stringtype eq
  67. {
  68. pop
  69. dup /Name get exch //MakeInstance exec
  70. pop exch pop
  71. /CIDSystemInfo get
  72. }
  73. {
  74. exch pop % /Name
  75. GetCIDSystemInfoFromMap
  76. } ifelse
  77. RESMPDEBUG { (cidfm GetCSI end ) print dup = } if
  78. } .internalbind def
  79. /IsActive % <record> IsActive <bool>
  80. { pop //true
  81. } .internalbind def
  82. currentdict end def
  83. % This is the default definition of our fallback CIDFont
  84. /DefaultCIDFallBack
  85. <<
  86. /Path
  87. systemdict /CIDFSubstPath .knownget
  88. {
  89. (/) concatstrings
  90. }
  91. {
  92. (CIDFSUBSTPATH) getenv
  93. {
  94. (/) concatstrings
  95. }
  96. {
  97. currentsystemparams /GenericResourceDir get (CIDFSubst/) concatstrings
  98. } ifelse
  99. } ifelse
  100. systemdict /CIDFSubstFont .knownget not
  101. {
  102. (CIDFSUBSTFONT) getenv not
  103. {
  104. (DroidSansFallback.ttf)
  105. } if
  106. } if
  107. % If CIDFSubstFont looks like a path/file (rather than just file)
  108. % use it without the CIDFSubstPath string
  109. dup .file_name_directory_separator rsearch
  110. {pop pop pop exch pop}
  111. {pop concatstrings}
  112. ifelse
  113. % The CSI data just has to be valid, the substition machinery will
  114. % generally overwrite it with appropriate values for the missing font.
  115. /CSI [(Identity) 0]
  116. /RecordVirtualMethods //RecordVirtualMethods
  117. /FileType /TrueType
  118. (CIDFSUBSTFONTID) getenv
  119. {
  120. /SubfontID exch cvi
  121. } if
  122. >> def
  123. % <dir.../base.extn> .basename <dir>
  124. /.splitdirname {
  125. (/) rsearch { //true } { (\\) rsearch } ifelse
  126. {exch concatstrings exch pop //true}{//false} ifelse
  127. } .internalbind def
  128. % <file> .addcidfmappath -
  129. /.addcidfmpermitpath
  130. {
  131. .filename
  132. {
  133. //.splitdirname exec
  134. {dup def} if
  135. } if
  136. } .internalbind def
  137. /VerifyMap % <raw_map> VerifyMap -
  138. {
  139. % This is where we insert the default fallback into the map
  140. % checking first to see if there is a user specified alternative
  141. dup /CIDFallBack known not{
  142. //DefaultCIDFallBack dup /Path get status
  143. {
  144. pop pop pop pop
  145. /CIDFallBack exch 2 index 3 1 roll put
  146. }
  147. {
  148. pop
  149. }ifelse
  150. } if
  151. % Remove any mappings for which we cannot find the font file
  152. dup length dict begin
  153. dup
  154. {
  155. % if we have a name1->name2 mapping, follow the "trail",
  156. % so if the name2 mapping is known in the .map dict, retrieve
  157. % that map value and loop round until we either reach a map
  158. % which references a TTF (i.e. a dictionary record) or we have
  159. % a name not known in the .map, in which case we have to resort
  160. % to the normal Postscript "resourcestatus".
  161. {
  162. dup type /nametype eq
  163. {
  164. dup 3 index exch .knownget
  165. { exch pop }
  166. {
  167. /CIDFont resourcestatus
  168. { pop pop pop }
  169. { 2 index exch .undef }
  170. ifelse
  171. exit
  172. } ifelse
  173. }
  174. {
  175. dup type /dicttype eq
  176. {
  177. /Path .knownget
  178. {
  179. .libfile
  180. {
  181. dup //.addcidfmpermitpath exec closefile pop}
  182. {
  183. {(r) file} //.internalstopped exec
  184. {pop pop 2 index exch .undef}
  185. {dup //.addcidfmpermitpath exec closefile pop} ifelse
  186. } ifelse
  187. }
  188. {2 index exch .undef}
  189. ifelse
  190. exit
  191. } if
  192. } ifelse
  193. } loop
  194. } forall
  195. currentdict end
  196. {exch pop /PermitFileReading exch .addcontrolpath} forall
  197. % Checks for vicious substitution cycles.
  198. dup length dict copy % <<map>>
  199. dup length dict % <<map>> <<temp>>
  200. { % Choose a random record :
  201. //true 2 index { % <<map>> <<temp>> true /Name /Subs
  202. 3 2 roll pop //false exit % <<map>> <<temp>> /Name /Subs false
  203. } forall
  204. { exit % <<map>> <<temp>>
  205. } if % <<map>> <<temp>> /Name /Subs
  206. % Move the substitution chain to <<temp>>, checking for a cycle :
  207. 3 index 2 index undef % <<map>> <<temp>> /Name /Subs
  208. exch 2 index exch 0 put % <<map>> <<temp>> /Subs
  209. { //IsMyRecord exec not {
  210. % Not a substitution, the chain terminates.
  211. pop exit % <<map>> <<temp>>
  212. } if % <<map>> <<temp>> /Subs
  213. 1 index 1 index known {
  214. (Vicious substitution cycle in map file with the entry ) print =string cvs print ( .) =
  215. /VerifyMap cvx /undefinedresource signalerror
  216. } if % <<map>> <<temp>> /Subs
  217. 1 index 1 index 0 put
  218. dup 3 index exch .knownget not { % <<map>> <<temp>> /Subs
  219. % No more substitutions, the chain terminates.
  220. pop exit % <<map>> <<temp>>
  221. } if % <<map>> <<temp>> /Subs /Subs1
  222. exch % <<map>> <<temp>> /Subs1 /Subs
  223. 3 index exch undef % <<map>> <<temp>> /Subs1
  224. } loop
  225. % Not cycled, now purge the <<temp>> :
  226. { % Choose a random record :
  227. //true 1 index { % <<map>> <<temp>> true /Name /Subs
  228. 3 2 roll pop //false exit % <<map>> <<temp>> /Name /Subs false
  229. } forall
  230. { exit % <<map>> <<temp>>
  231. } if % <<map>> <<temp>> /Name /Subs
  232. % Remove it :
  233. pop 1 index exch undef % <<map>> <<temp>>
  234. } loop
  235. } loop
  236. pop pop
  237. } .internalbind def
  238. currentdict /.splitdirname undef
  239. currentdict /.addcidfmpermitpath undef
  240. /PreprocessRecord % <map> <Name> <raw_record> PreprocessRecord <map> <Name> <record> <bool>
  241. {
  242. //IsMyRecord exec {
  243. 1 dict begin
  244. /Substitute exch def
  245. dup /Name exch def
  246. /RecordVirtualMethods //RecordVirtualMethods def
  247. currentdict end
  248. //true
  249. } {
  250. //false
  251. } ifelse
  252. } .internalbind def
  253. currentdict end
  254. /MappedCategoryRedefiner /ProcSet findresource /Redefine get exec
  255. .setlanguagelevel