gs_cidfn.ps 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. % Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This file is part of AFPL Ghostscript.
  4. %
  5. % AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  6. % distributor accepts any responsibility for the consequences of using it, or
  7. % for whether it serves any particular purpose or works at all, unless he or
  8. % she says so in writing. Refer to the Aladdin Free Public License (the
  9. % "License") for full details.
  10. %
  11. % Every copy of AFPL Ghostscript must include a copy of the License, normally
  12. % in a plain ASCII text file named PUBLIC. The License grants you the right
  13. % to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14. % conditions described in the License. Among other things, the License
  15. % requires that the copyright notice and this notice be preserved on all
  16. % copies.
  17. % $Id: gs_cidfn.ps,v 1.18 2000/12/08 23:35:38 lpd Exp $
  18. % ProcSet for implementing CIDFont and CIDMap resources.
  19. % When this is run, systemdict is still writable.
  20. % ---------------- Defining CIDFont resources ---------------- %
  21. % Define a CIDFont resource. This is the defineresource implementation for
  22. % the CIDFont resource category.
  23. /.checkfonttype { % <cidfont> <fonttype> .checkfonttype <cidfont> <new?>
  24. 1 index /FID known {
  25. 1 index /FontType get ne {
  26. /definefont cvx /invalidfont signalerror
  27. } if false
  28. } {
  29. 1 index /FontType 3 -1 roll put true
  30. } ifelse
  31. } bind def
  32. /.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
  33. .cidfonttypes
  34. 30 dict begin
  35. % The key in .cidfonttypes is the CIDFontType value;
  36. % the value is a procedure that takes a font name and the CIDFont dictionary
  37. % and replaces the latter with a real font.
  38. % ------ CIDFontType 0 (FontType 9) ------ %
  39. % We add the following entries to the CIDFont dictionary, in addition to
  40. % the ones documented by Adobe:
  41. % SubrCache - dictionary for caching Subr arrays
  42. % For CIDFonts where we read the data from disk incrementally:
  43. % GlyphData is 0 (arbitrary)
  44. % DataSource - a ReusableStreamDecode filter for the data
  45. % We also add a FID entry, and possibly a Subrs entry, to each element of
  46. % FDArray.
  47. dup 0 {
  48. 9 .checkfonttype {
  49. /CIDInit /ProcSet findresource begin
  50. .completefont9
  51. end
  52. } if
  53. 1 index exch .buildfont9 exch pop
  54. } bind put
  55. % Add entries to a new CIDFontType 0 font per documentation (FontMatrix)
  56. % or for .buildfont9 (FDArray.Private.Subrs).
  57. /.completefont9 { % <cidfont0> .completefont9 <cidfont0>
  58. currentglobal 3 1 roll dup gcheck setglobal
  59. dup /FontMatrix known not {
  60. dup /FontMatrix [0.001 0 0 0.001 0 0] put
  61. dup /FDArray get {
  62. /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
  63. } forall
  64. } if
  65. dup /FDArray get {
  66. % Read the Subrs if necessary.
  67. dup /Private get dup /Subrs known not {
  68. dup /SubrCount .knownget {
  69. % Stack: font Private SubrCount
  70. currentglobal 3 1 roll 1 index gcheck setglobal
  71. array 1 index /Subrs 3 -1 roll put
  72. % Stack: font global Private
  73. 2 index begin begin .loadsubrs end end
  74. setglobal
  75. } {
  76. pop
  77. } ifelse readonly pop
  78. } {
  79. pop pop
  80. } ifelse
  81. } forall
  82. 3 -1 roll setglobal
  83. } bind def
  84. % Read some Subrs for the current Type 1 subfont.
  85. % The subfont's Private dict is currentdict; the CIDFont itself is the
  86. % next dictionary on the stack.
  87. /.readsubrs { % <Subrs> <start> .readsubrs <Subrs>
  88. 1 SubrCount 1 sub {
  89. dup SDBytes mul SubrMapOffset add
  90. dup SDBytes .readint exch SDBytes add SDBytes .readint
  91. 1 index sub string ReadString 2 index 3 1 roll put
  92. } for
  93. } bind def
  94. % Ensure that all the Subrs for the current Type 1 subfont are loaded.
  95. % The subfont's Private dict is currentdict; the CIDFont itself is the
  96. % next dictionary on the stack.
  97. /.loadsubrs {
  98. Subrs length 0 ne {
  99. SubrCache SubrMapOffset .knownget {
  100. % We've already loaded some Subrs at this offset.
  101. % Make sure we've got as many as we need.
  102. dup length SubrCount lt {
  103. % We need to load more.
  104. SubrCount array exch 1 index copy length .readsubrs
  105. SubrCache SubrMapOffset 2 index put
  106. } if
  107. } {
  108. % We haven't loaded any Subrs at this offset yet.
  109. SubrCount array 0 .readsubrs
  110. SubrCache SubrMapOffset 2 index put
  111. } ifelse
  112. Subrs copy pop
  113. } if
  114. } bind def
  115. % ------ CIDFontType 1 (FontType 10) ------ %
  116. dup 1 {
  117. 10 .checkfonttype pop
  118. 1 index exch .buildfont10 exch pop
  119. } bind put
  120. % ------ CIDFontType 2 (FontType 11) ------ %
  121. dup 2 {
  122. 11 .checkfonttype pop
  123. 1 index exch .buildfont11 exch pop
  124. } bind put
  125. pop % .cidfonttypes
  126. % ---------------- Reading CIDFontType 0 files ---------------- %
  127. /StartData { % <(Binary)|(Hex)> <datalength> StartData -
  128. % (currentdict is CID font dict)
  129. % If we're loading a resource file and the data format is
  130. % binary, we can just save a pointer to the data and load it
  131. % incrementally.
  132. mark {
  133. % Previous versions of this code made provisions for
  134. % reading hex-encoded data incrementally. Since hex data
  135. % doesn't seem to be used in practice, we no longer bother.
  136. 2 index (Binary) ne { stop } if
  137. currentfile .currentresourcefile ne { stop } if
  138. % Hack: the pdfwrite driver relies on finalization to write
  139. % out fonts. However, the font may be finalized after the
  140. % resource file, in which case the resource file will be
  141. % closed. So if the current output device is pdfwrite,
  142. % don't use incremental loading.
  143. currentdevice .devicename /pdfwrite eq { stop } if
  144. currentfile fileposition
  145. } .internalstopped {
  146. % File is not positionable, or uses hex data.
  147. % Load the data now.
  148. cleartomark exch (Hex) eq
  149. { { currentfile exch readhexstring pop } }
  150. { { currentfile exch readstring pop } }
  151. ifelse exch
  152. % Stack: readproc length
  153. dup 65400 le {
  154. % readstring with a 0-length string causes a rangecheck,
  155. % but a data length of 0 is allowed.
  156. string dup () ne { 1 index exec } if
  157. } {
  158. mark 3 1 roll {
  159. % Stack: mark str ... readproc length
  160. dup 0 eq { pop exit } if
  161. dup 65400 min dup string 3 index exec
  162. % Stack: mark str ... readproc length newstrlen newstr
  163. 4 1 roll sub
  164. } loop
  165. counttomark 1 add 1 roll ]
  166. } ifelse
  167. /GlyphData exch def
  168. % If we were reading hex data, skip past the >.
  169. 2 get { readhexstring } 0 get eq {
  170. currentfile 0 (>) .subfiledecode dup flushfile closefile
  171. } if
  172. } {
  173. % File is positionable and binary, just save a pointer.
  174. % Stack: (Binary) length -mark- pos
  175. /GlyphData 0 def
  176. exch pop 3 -1 roll pop exch
  177. % Stack: pos length
  178. /DataSource currentfile 2 index () .subfiledecode true .reusablestream def
  179. currentfile 3 1 roll add setfileposition
  180. } ifelse
  181. /SubrCache 10 dict def
  182. CIDFontName currentdict /CIDFont defineresource pop
  183. end % CID font dict
  184. end % resource category dict
  185. } bind def
  186. % Some Adobe fonts include the line
  187. % /Setup /cid_Setup load def
  188. % This is apparently included only to prevent proper, conforming PostScript
  189. % interpreters (as opposed to ATM or a special Adobe font loader) from
  190. % loading the font, since Setup is not referenced anywhere else in the file.
  191. /cid_Setup { } def
  192. currentdict end
  193. % ---------------- Rendering ---------------- %
  194. % ------ Generic ------ %
  195. % Read a string at a given offset in a "file" (binary file or
  196. % GlyphData in RAM).
  197. /ReadString { % <pos> <string> ReadString <string>
  198. GlyphData 0 eq {
  199. % Read from the file.
  200. DataSource 3 -1 roll setfileposition
  201. DataSource exch readstring pop
  202. } {
  203. % Read from a string or an array of strings.
  204. GlyphData .stringsreadstring
  205. } ifelse
  206. } bind def
  207. /.stringsreadstring % <pos> <string> <strings> .stringsreadstring
  208. % <vmstring>
  209. { dup type /stringtype eq
  210. { 3 1 roll length getinterval
  211. }
  212. { { % Stack: pos string glyphdata
  213. dup 0 get length dup 4 index gt { exit } if
  214. 4 -1 roll exch sub 3 1 roll
  215. dup length 1 sub 1 exch getinterval
  216. }
  217. loop
  218. % Stack: pos string glyphdata glyphdata[0]length
  219. % We know no request can span more than 2 strings.
  220. 3 index 3 index length add 1 index le
  221. { % Request fits in a single string: just return a substring.
  222. pop 0 get 3 1 roll length getinterval
  223. }
  224. { % Request spans 2 strings. Copy the first part.
  225. 1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
  226. 2 index copy
  227. % Copy the second part.
  228. % Stack: pos str glyphdata str1
  229. length exch 1 get 0 3 index length
  230. 3 index sub getinterval 2 index 3 1 roll putinterval
  231. exch pop
  232. }
  233. ifelse
  234. }
  235. ifelse
  236. } bind def
  237. % Interpret a byte string as a (big-endian) integer.
  238. /.cvbsi % <bytes> .cvbsi <int>
  239. { 0 exch { exch 8 bitshift add } forall
  240. } bind def
  241. % Read an integer from binary data.
  242. /.readint % <pos> <nbytes> .readint <int>
  243. { string ReadString .cvbsi
  244. } bind def
  245. % ------ CIDFontType 0 ------ %
  246. /.readglyphdata {
  247. currentfont exch .type9mapcid
  248. FDArray exch get exch
  249. } bind def
  250. % BuildGlyph procedure for CIDFontType 0.
  251. % The name %Type9BuildGlyph is known to the interpreter.
  252. /.cid0buildstring 10 string def
  253. (%Type9BuildGlyph) cvn { % <cidfont> <cid> %Type9BuildGlyph -
  254. .currentglobal 3 1 roll 1 index gcheck .setglobal
  255. 1 index begin
  256. dup .readglyphdata dup null eq {
  257. % Substitute CID 0. **** WRONG ****
  258. pop pop 0 .readglyphdata
  259. } if
  260. % Stack: cidfont cid subfont charstring
  261. dup null eq { pop pop pop pop } { %**** WRONG ****
  262. 4 -1 roll pop
  263. 3 1 roll exch dup 4 -1 roll 0 0 moveto
  264. 3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse
  265. } ifelse %**** WRONG ****
  266. end
  267. .setglobal
  268. } bind def
  269. % ------ CIDFontType 2 ------ %
  270. % BuildGlyph procedure for CIDFontType 2.
  271. % The name %Type11BuildGlyph is known to the interpreter.
  272. (%Type11BuildGlyph) cvn { % <cidfont> <cid> %Type11BuildGlyph -
  273. % We must be prepared for out-of-range CIDs.
  274. 2 copy { .type11mapcid } .internalstopped {
  275. pop /CharStrings get /.notdef get
  276. } if
  277. % Stack: cidfont cid glyphindex
  278. 1 index exch .type42execchar
  279. } bind def
  280. % ---------------- Define resources ---------------- %
  281. languagelevel exch 2 .setlanguagelevel
  282. % Define the CIDInit ProcSet resource.
  283. % The ProcSet dictionary is still on the stack.
  284. % We might have loaded CMap support already. However, Adobe's
  285. % protected font downloader defines a CIDInit ProcSet that will be
  286. % loaded from the filesystem later, so we must check specifically
  287. % for the ProcSet being defined in VM.
  288. /CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse {
  289. pop pop findresource dup length 4 index length add dict .copydict
  290. 4 -1 roll exch .copydict
  291. } {
  292. 3 -1 roll
  293. } ifelse exch defineresource pop
  294. % Define the CIDFont resource category.
  295. % We break out .buildcidfont because it appears that at least for
  296. % Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
  297. % category with only a CIDFontType and no FontType.
  298. /.buildcidfont { % <name> <fontdict> .buildcidfont
  299. % <name> <cidfont>
  300. dup /CIDFontType get //.cidfonttypes exch get exec
  301. } odef
  302. /CIDFont /Generic /Category findresource dup length dict .copydict
  303. dup /InstanceType /dicttype put
  304. dup /DefineResource {
  305. .buildcidfont
  306. /Generic /Category findresource /DefineResource get exec
  307. } put
  308. % CIDFonts may be defined in CFF OpenType files.
  309. % Check for this here.
  310. /.loadcidfontresource {
  311. dup .ResourceFile {
  312. {.loadfont} .execasresource
  313. } {
  314. dup /undefinedresource signalerror
  315. } ifelse
  316. } bind def
  317. dup /.LoadResource {
  318. currentglobal {
  319. .loadcidfontresource
  320. } {
  321. true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
  322. } ifelse
  323. } bind put
  324. /Category defineresource pop
  325. % Add the new FontType resources.
  326. 9 1 11 { dup /FontType defineresource pop } for
  327. % Add the new FMapType resource.
  328. 9 dup /FMapType defineresource pop
  329. % Define the CIDMap resource category.
  330. % These aren't documented, but it's clear what they are for:
  331. % to give names to CIDMaps for CIDFontType 2 fonts.
  332. /CIDMap /Generic /Category findresource dup length dict .copydict
  333. dup /.CheckResource {
  334. % Allow a string, an array of strings, or (as of Adobe release 3011)
  335. % a dictionary.
  336. dup type dup dup /stringtype eq exch /dicttype eq or {
  337. pop true
  338. } {
  339. dup /arraytype eq exch /packedarraytype eq or {
  340. true exch { type /stringtype eq and } forall
  341. } {
  342. false
  343. } ifelse
  344. } ifelse
  345. } bind put
  346. /Category defineresource pop
  347. .setlanguagelevel