星火微课系统客户端
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863
  1. % Copyright (C) 1994, 2000 Aladdin Enterprises. All rights reserved.
  2. %
  3. % This software is provided AS-IS with no warranty, either express or
  4. % implied.
  5. %
  6. % This software is distributed under license and may not be copied,
  7. % modified or distributed except as expressly authorized under the terms
  8. % of the license contained in the file LICENSE in this distribution.
  9. %
  10. % For more information about licensing, please refer to
  11. % http://www.ghostscript.com/licensing/. For information on
  12. % commercial licensing, go to http://www.artifex.com/licensing/ or
  13. % contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  14. % San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  15. % $Id: pdf_font.ps 10722 2010-02-08 16:45:18Z ken $
  16. % PDF font operations.
  17. % Since PDF font are not unique and can collide with external font resources
  18. % or each other, use font dictionaries obtained from PDF directly, never
  19. % register them as resources or look them up by name. Use findfont oparator
  20. % for non-embedded fonts only. CIDFont resources still use the old logic
  21. % described below.
  22. % Finding a font by name can't give a proper result when PDF font names aren't unique.
  23. % But it is only the way to obtain a font in Postscript after a font file is executed.
  24. % Therefore using a FontName (and findfont) is allowed only
  25. % immediately after a font file is executed.
  26. % In all other cases the font to be found by a pointer through PDF structures.
  27. %
  28. % This ideal logics can't work for documents,
  29. % which define a font resource with an embedded font,
  30. % and another font resource with same BaseFont but with no embedded font
  31. % (and possibly with no font descriptor).
  32. % Our testbase does contain such examples.
  33. % In this case we do find font by FontName (with findfont),
  34. % since there is no other way to get a reasonable result.
  35. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  36. .currentglobal true .setglobal
  37. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  38. GS_PDF_ProcSet begin
  39. pdfdict begin
  40. % We cache the PostScript font in an additional element of the
  41. % font resource dictionary, called PSFont.
  42. % ---------------- Encodings ---------------- %
  43. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  44. % Apply a list of differences to an Encoding.
  45. % Note that the differences may cause the array to grow.
  46. /updateencoding { % <encoding|null> <differences> updateencoding <enc'>
  47. % Calculate the length of the result.
  48. % in case the incoming Encoding is null, use .notdefEncoding
  49. exch dup null eq { pop .notdefEncoding } if
  50. 0 0 3 index {
  51. dup type /nametype ne { exch pop oforce } { pop 1 add } ifelse
  52. % Differences list may not be in order, update the largest_index
  53. % stack: <Differences> <encoding> <largest_index> <at_index>
  54. 2 copy lt { exch pop dup } if % at_index is new largest
  55. } forall
  56. pop 1 index length .max array dup 0 4 -1 roll putinterval
  57. exch 0 exch {
  58. % Stack: enc' code element
  59. dup type /nametype ne
  60. { exch pop oforce }
  61. { 3 copy put pop 1 add }
  62. ifelse
  63. } forall pop
  64. } bdef
  65. /good_encoding_names <<
  66. /MacRomanEncoding 0 /MacExpertEncoding 0 /WinAnsiEncoding 0
  67. >> readonly def
  68. /known_symbolic_fonts <<
  69. /Wingdings2 0
  70. >> readonly def
  71. % Get the Encoding for a font.
  72. /getencoding % <base-encoding> <font-resource> getencoding <enc>
  73. { dup /Encoding knownoget
  74. { dup type /nametype eq
  75. {
  76. % The published PDF specification says the Encoding name
  77. % "must be" one of the 3 predefined Encodings, implying
  78. % that an error should occur if it isn't. However, Acrobat
  79. % Reader simply ignores unknown names, and since there are
  80. % some buggy applications that rely on this, we do the same.
  81. //good_encoding_names 1 index known {
  82. exch /BaseFont knownoget not { 0 } if
  83. % Ignore named encodings for known symbolic fonts. See bug 690135.
  84. //known_symbolic_fonts exch known {
  85. pop
  86. } {
  87. exch pop findencoding
  88. } ifelse
  89. } {
  90. pop pop
  91. } ifelse
  92. }
  93. { exch pop
  94. dup type /arraytype eq
  95. { exch pop
  96. ( **** Warning: Encoding is an array, not name or dictionary.\n) pdfformaterror
  97. }
  98. { dup /BaseEncoding knownoget
  99. { dup / eq
  100. { pop
  101. ( **** Warning: Ignoring bad BaseEncoding name.\n) pdfformaterror
  102. % as found in a PDF file from J.D.Edwards OneWorld (B7333), bug 687786
  103. }
  104. { findencoding 3 -1 roll pop exch }
  105. ifelse
  106. }
  107. if
  108. /Differences knownoget { updateencoding } if
  109. }
  110. ifelse
  111. }
  112. ifelse
  113. } {
  114. pop
  115. ( **** Warning: Encoding not present.\n) pdfformaterror
  116. }
  117. ifelse
  118. } bdef
  119. currentdict /good_encoding_names undef
  120. currentdict /known_symbolic_fonts undef
  121. /checkGlyphNames2Unicode % <dict> checkGlyphNames2Unicode -
  122. {
  123. PDFDEBUG {
  124. dup /FontInfo .knownget {
  125. /GlyphNames2Unicode .knownget {
  126. (Has GlyphNames2Unicode) =
  127. pop % { exch == ==} forall
  128. } if
  129. } if
  130. } if
  131. pop
  132. } bind def
  133. % Define a font using it's FontName as the key.
  134. % Adjust a font according to the Encoding and Widths in the font resource.
  135. /adjustfont { % <font-resource> <font> adjustfont <font'>
  136. getfontencoding
  137. 3 copy .processToUnicode
  138. getfontmetrics 5 -1 roll pop .updatefont { .completefont } if
  139. } bind def
  140. % Get the (possibly modified) encoding of a font.
  141. /getfontencoding { % <font-resource> <font> getfontencoding
  142. % <font-resource> <font> <Encoding|null>
  143. % Ignore encoding when TrueType is requested
  144. % and loaded. All other cases are left unchanged.
  145. dup /FontType get 42 eq
  146. 2 index /Subtype get /TrueType eq and {
  147. //null
  148. } {
  149. 1 index /Encoding known {
  150. dup /Encoding knownoget { 2 index getencoding } { //null } ifelse
  151. } {
  152. //null
  153. } ifelse
  154. } ifelse
  155. } bdef
  156. % Returns true if the current glyph is in the Differences array at
  157. % the specified index value. This is needed because the Widths
  158. % array may map to the same glyph at different positions from the
  159. % Encoding. We want to use the Width that was associated with the
  160. % one specified in the Encoding::Differences list.
  161. /match_in_diff % <Differences> <index> <glyphname> match_in_diff <bool>
  162. { false 4 1 roll 0 4 -1 roll % stack: false index glyphname at_index==0 Differences
  163. { exch 1 index type /nametype ne {
  164. % stack: false index glyphname Diff_element at_index
  165. pop % Diff_element is new at_index
  166. } {
  167. % stack: false index glyphname Diff_element at_index
  168. exch 2 index eq {
  169. % stack: false index glyphname at_index
  170. dup 3 index eq {
  171. true 5 1 roll % stack: true false index glyphname at_index
  172. pop exit
  173. } if
  174. } if
  175. 1 add % at_index++ stack: false index glyphname at_index'
  176. } ifelse
  177. } forall
  178. % stack: true false index glyphname
  179. % or : false index glyphname at_index
  180. pop pop pop
  181. } bdef
  182. /unique_name { % <dict> </root> unique_name </unique>
  183. %
  184. % Note : this function interacts with pdf_write_encoding in src/gdevpdtw.c
  185. % and with copied_drop_extension_glyphs in src\gxfcopy.c
  186. % by adding a reserved substring (~GS~).
  187. %
  188. .namestring % <<>> (root)
  189. 0 1 65535 {
  190. 5 string cvs % <<>> (root) (0)
  191. (~GS~) exch concatstrings
  192. 1 index exch % <<>> (root) (root) (~GS~0)
  193. concatstrings % <<>> (root) (root~GS~0)
  194. dup % <<>> (root) (root~GS~0) (root~GS~0)
  195. 3 index exch % <<>> (root) (root~GS~0) <<>> (root~GS~0)
  196. known not {
  197. exch pop exit % <<>> (root~GS~0)
  198. } if
  199. pop
  200. } for
  201. exch pop cvn % /root0
  202. } bdef
  203. % Get the metrics of a font, if specified.
  204. /getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics
  205. % <font-resource> <font> <Encoding|null>
  206. % <Metrics|null> <GlyphMap|null>
  207. 2 index /Widths known {
  208. dup //null eq { pop dup /Encoding get } if
  209. 7 dict begin
  210. dup length dict
  211. /Metrics exch def
  212. /Encoding exch def
  213. /GlyphMap //null def
  214. exch
  215. dup /Widths oget /Widths exch def
  216. % Stack: font font-res
  217. % Note that widths are always based on a 1000-unit
  218. % character space, but the FontMatrix may specify
  219. % some other scale factor. Compensate for this here,
  220. % by scaling the Widths if necessary.
  221. 0.001 2 index /FontMatrix get 0 get
  222. dup 0 eq {
  223. % FontMatrix.xx == 0, so we cannot scale down by xx.
  224. % - FontMatrix[0] == 0 implies either FontMatrix[1] <> 0 or
  225. % FontMatrix cannot be inverted. In the 1st case we have
  226. % FontMatrixNonHV == true and will render text with cshow + xshow.
  227. % In the 2nd case, metrics in the PDF Font object cannot be enforced
  228. % [by altering metrics in PS glyph space].
  229. % HACK:
  230. % - we scale down by FontMatrix[1];
  231. % - given the format of Metrics entries we use, wy = 0 in glyph space;
  232. % - as a result, the cshow procedure receives as wy the value we
  233. % need for wx (all of this in PS user space).
  234. pop
  235. 2 index /FontMatrix get 1 get
  236. dup 0 eq { pop 1 } if % sorry, no way to enforce PDF metrics by altering the font
  237. } if
  238. div
  239. % Stack: font font-res mscale
  240. /FirstChar 2 index /FirstChar knownoget not {
  241. ( **** Warning: /FirstChar attribute is missing, assuming 0.\n) pdfformaterror
  242. 0
  243. } if def
  244. /LastChar 2 index /LastChar knownoget not {
  245. ( **** Warning: /LastChar attribute is missing, assuming 255.\n) pdfformaterror
  246. 255
  247. } if def
  248. Encoding length LastChar le {
  249. ( **** Warning: Font Encoding array size is smaller than character range.\n)
  250. pdfformaterror
  251. } if
  252. 1 index /FontDescriptor knownoget {
  253. /MissingWidth knownoget not { 0 } if
  254. }
  255. { 1000
  256. }
  257. ifelse /MissingWidth exch def
  258. Widths length LastChar FirstChar sub le {
  259. ( **** Warning: Font Widths array size is smaller than character range.\n)
  260. pdfformaterror
  261. /Widths [Widths aload length LastChar FirstChar sub exch sub MissingWidth exch {dup} repeat] def
  262. } if
  263. FirstChar
  264. 0 Encoding
  265. { % Stack: font font-res mscale first-char index charname
  266. 1 index FirstChar lt { MissingWidth } {
  267. 1 index LastChar gt { MissingWidth } { Widths 2 index FirstChar sub get } ifelse
  268. } ifelse
  269. % Stack: font font-res mscale first-char index charname width
  270. 4 index mul
  271. % The following 'loop' is only context for 'exit'.
  272. {
  273. % Work around a bug in pdfTeX, which can generate Encoding
  274. % vectors containing nulls :
  275. 1 index //null eq { exit } if
  276. Metrics 2 index .knownget {
  277. 1 index ne
  278. } {
  279. //false
  280. } ifelse {
  281. % Two or more Encoding elements refer same glyph name,
  282. % and Widths specify different wihts for it.
  283. % Since a Postscript font can't have different
  284. % Metrics for same glyph name,
  285. % we generate an unique name, and create a new
  286. % Charstrings entry with same glyph value.
  287. GlyphMap //null eq {
  288. /Encoding Encoding dup length array copy def
  289. /GlyphMap 4 dict def
  290. } if
  291. % To prevent too many new names, check whether
  292. % we can use one already created for same glyph.
  293. //true
  294. GlyphMap { % f r s c i n w b n1 n2
  295. 4 index eq { % f r s c i n w b n1
  296. dup Metrics exch get % f r s c i n w b n1 w1
  297. 3 index eq { % f r s c i n w b n1
  298. 4 3 roll pop % f r s c i w b n1
  299. 3 1 roll pop % f r s c i n1 w
  300. Encoding 3 index 3 index put
  301. //false % f r s c i n1 w b
  302. exit
  303. } {
  304. pop
  305. } ifelse
  306. } { % f r s c i n w b n1
  307. pop
  308. } ifelse
  309. } forall % f r s c i n w b
  310. { % Do create a new name.
  311. Metrics 2 index //unique_name exec % f r s c i n w nn
  312. Encoding 4 index 2 index put
  313. GlyphMap 1 index 5 -1 roll put % f r s c i w nn
  314. exch
  315. % Stack: font font-res mscale first-char index new_name width
  316. } if
  317. } if
  318. 2 copy Metrics 3 1 roll put
  319. exit
  320. } loop
  321. pop pop
  322. 1 add
  323. }
  324. forall pop pop pop
  325. exch Encoding Metrics GlyphMap end
  326. } {
  327. //null //null
  328. } ifelse
  329. } bdef
  330. currentdict /unique_name undef
  331. currentdict /match_in_diff undef
  332. /ToUnicodeCMapReader 3 dict begin
  333. /defineresource % <name> <dict> <cat-name> defineresource <dict>
  334. {
  335. pop
  336. dup userdict exch /.lastToUnicode exch put
  337. exch pop
  338. } bind def
  339. /CIDSystemInfo
  340. {
  341. ( **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
  342. /CIDSystemInfo
  343. } bind def % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
  344. /CMapName
  345. {
  346. ( **** Warning: ToUnicode CMap has no CMapName.\n\
  347. See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\n) pdfformaterror
  348. /CMap1 % arbitrary, PDF defineresource tolerates non-unique names
  349. } bind def % A work around incorrect ToUnicode CMap generated by GS before rev. 6201.
  350. currentdict end readonly def
  351. /string2number % <string> string2number <number>
  352. { 0 exch dup 0 exch 1 exch length 1 sub { % n () i
  353. 1 index exch get % n () v
  354. 3 2 roll 256 mul add exch % v+n*256 ()
  355. } for
  356. pop % N
  357. } bind def
  358. /copy&def % <key> <value> <bool> copy&def -
  359. {
  360. { true
  361. } {
  362. currentdict gcheck {
  363. dup gcheck not
  364. } {
  365. false
  366. } ifelse
  367. } ifelse
  368. { currentglobal currentdict gcheck setglobal
  369. exch dup length string copy exch
  370. setglobal
  371. } if
  372. def
  373. } bind def
  374. /.convert_ToUnicode-into-g2u % <GlyphNames2Unicode> <Encoding|null> <CMap> .convert_ToUnicode-into-g2u -
  375. {
  376. PDFDEBUG {
  377. (.convert_ToUnicode-into-g2u beg) =
  378. } if
  379. 3 2 roll begin
  380. /.CodeMapData get % About the data format see gs_cmap.ps, the comment after "CMap operators".
  381. 1 get % code maps
  382. {
  383. PDFDEBUG {
  384. dup ==
  385. } if
  386. dup length 1 sub 0 exch 5 exch { % e [] i
  387. 2 copy get % e [] i (prefix)
  388. string2number % e [] i prefix
  389. 2 index 2 index 1 add get % e [] i prefix (key_size,?is_range,value_type,value_size)
  390. dup 0 get 8 mul % e [] i prefix (key_size,?is_range,value_type,value_size) key_size*8
  391. 3 2 roll exch bitshift exch % e [] i prefix<<key_size*8 (key_size,?is_range,value_type,value_size)
  392. dup 0 get exch 3 get % e [] i offset key_size value_size
  393. 4 index 4 index 2 add get % e [] i offset key_size value_size (keys)
  394. 5 index 5 index 3 add get % e [] i offset key_size value_size (keys) (values)
  395. PDFDEBUG {
  396. ( offset=) print 4 index =string cvs print
  397. ( key_size=) print 3 index =string cvs print
  398. ( value_size=) print 2 index =
  399. ( keys=) print 1 index ==
  400. ( values=) print dup ==
  401. } if
  402. 1 index length 0 eq {
  403. % A single pair.
  404. exch pop exch pop exch pop exch % e [] i (values) offset
  405. 4 index null ne {
  406. 4 index length 1 index gt {
  407. 4 index exch get
  408. } if
  409. } if % e [] i (values) cid|name
  410. exch
  411. PDFDEBUG {
  412. ( defined single: ) print 1 index =string cvs print ( ) print dup ==
  413. } if
  414. false copy&def % e [] i
  415. pop % e []
  416. } {
  417. % A range. % e [] i offset key_size value_size (keys) (values)
  418. dup length string copy % protect the original string from modifications below.
  419. 0 4 index 2 mul 3 index length 1 sub { % e [] i offset key_size value_size (keys) (values) j
  420. 2 index 1 index 6 index getinterval
  421. string2number % e [] i offset key_size value_size (keys) (values) j keyL
  422. PDFDEBUG {
  423. ( keyL=) print dup =string cvs print
  424. } if
  425. 3 index 2 index 7 index add 7 index getinterval
  426. string2number % e [] i offset key_size value_size (keys) (values) j keyL keyH
  427. PDFDEBUG {
  428. ( keyH=) print dup =
  429. } if
  430. 3 2 roll 6 index idiv 5 index mul % e [] i offset key_size value_size (keys) (values) keyL keyH J
  431. 3 index exch 6 index getinterval % e [] i offset key_size value_size (keys) (values) keyL keyH (valueL)
  432. 3 1 roll 1 exch { % e [] i offset key_size value_size (keys) (values) (value) k
  433. 9 index null ne {
  434. 9 index exch get % e [] i offset key_size value_size (keys) (values) (value) name
  435. } if % e [] i offset key_size value_size (keys) (values) (value) cid|name
  436. 1 index % e [] i offset key_size value_size (keys) (values) (value) cid|name (value)
  437. PDFDEBUG {
  438. ( defined from range: ) print 1 index =string cvs print ( ) print dup ==
  439. } if
  440. true copy&def % e [] i offset key_size value_size (keys) (values) (value)
  441. % Assuming the lowest byte of 'value' changes, others don't.
  442. dup dup length 1 sub % e [] i offset key_size value_size (keys) (values) (value) (value) l
  443. 2 copy get % e [] i offset key_size value_size (keys) (values) (value) (value) l v
  444. % Modulo 256 increment prevents a rangecheck error when the result is stored in a string.
  445. % The adjustment can happen only at the end of the loop where the string is discarded. Bug 688535.
  446. 1 add 255 and put % e [] i offset key_size value_size (keys) (values) (value')
  447. } for % e [] i offset key_size value_size (keys) (values) (value)
  448. } for
  449. pop pop pop pop pop pop pop % e []
  450. } ifelse
  451. } for
  452. pop % e
  453. } forall
  454. end
  455. pop %
  456. PDFDEBUG {
  457. (.convert_ToUnicode-into-g2u end) =
  458. } if
  459. } bind def
  460. /.processToUnicode % <font-resource> <font-dict> <encoding|null> .processToUnicode -
  461. {
  462. % Currently pdfwrite is only device which can handle GlyphNames2Unicoide to
  463. % generate a ToUnicode CMaps. So don't bother with other devices.
  464. currentdevice .devicename /pdfwrite eq {
  465. PDFDEBUG {
  466. (.processToUnicode beg) =
  467. } if
  468. 2 index /ToUnicode knownoget {
  469. dup type /dicttype eq { dup /File known not } { //true } ifelse {
  470. % We undefine wrong /Length and define /File in stream dictionaries.
  471. % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
  472. ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformaterror
  473. pop
  474. } {
  475. /PDFScanRules .getuserparam dup //null eq {
  476. pop //PDFScanRules_null
  477. } {
  478. 1 dict dup /PDFScanRules 4 -1 roll put
  479. } ifelse
  480. //PDFScanRules_true setuserparams
  481. PDFfile fileposition 3 -1 roll
  482. //false resolvestream
  483. //ToUnicodeCMapReader begin
  484. % Following Acrobat we ignore everything outside
  485. % begincodespacerange .. endcmap.
  486. dup 0 (begincodespacerange) /SubFileDecode filter flushfile
  487. /CIDInit /ProcSet findresource begin 12 dict begin
  488. /CMapType 2 def
  489. mark exch % emulate 'begincodespacerange'
  490. 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
  491. endcmap
  492. userdict /.lastToUnicode currentdict put
  493. end end end
  494. PDFfile exch setfileposition
  495. setuserparams
  496. 1 index /FontInfo .knownget not {
  497. currentglobal 2 index dup gcheck setglobal
  498. /FontInfo 5 dict dup 5 1 roll .forceput
  499. setglobal
  500. } if
  501. dup /GlyphNames2Unicode .knownget not {
  502. true % No existing G2U, make one
  503. } {
  504. dup wcheck {
  505. false % Existing, writeable G2U, don't make new one
  506. } {
  507. pop true % Existing read only G2U, make new one
  508. } ifelse
  509. } ifelse
  510. {
  511. currentglobal exch dup gcheck setglobal
  512. dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
  513. 3 2 roll setglobal
  514. } if % font-res font-dict encoding|null font-info g2u
  515. exch pop exch % font-res font-dict g2u encoding|null
  516. userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
  517. .convert_ToUnicode-into-g2u % font-res font-dict
  518. //null % font-res font-dict null
  519. } ifelse
  520. } if
  521. PDFDEBUG {
  522. (.processToUnicode end) =
  523. } if
  524. } if
  525. pop pop pop
  526. } bind def
  527. % ---------------- Descriptors ---------------- %
  528. % Partial descriptors for the 14 built-in fonts. Note that
  529. % from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
  530. % object has undergone a subtle change in its meaning which has serious
  531. % consequences for searching with Acrobat:
  532. % In PDF 1.1, the flag meant: Font has StandardEncoding
  533. % In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
  534. /standardfontdescriptors mark
  535. /Courier mark /Flags 16#23 .dicttomark
  536. /Courier-Oblique 1 index
  537. /Courier-Bold 1 index
  538. /Courier-BoldOblique 1 index
  539. /Helvetica mark /Flags 16#20 .dicttomark
  540. /Helvetica-Oblique 1 index
  541. /Helvetica-Bold 1 index
  542. /Helvetica-BoldOblique 1 index
  543. /Times-Roman mark /Flags 16#22 .dicttomark
  544. /Times-Bold 1 index
  545. /Times-Italic mark /Flags 16#62 .dicttomark
  546. /Times-BoldItalic 1 index
  547. /Symbol mark /Flags 16#4 .dicttomark
  548. /ZapfDingbats 1 index
  549. .dicttomark readonly def
  550. % ---------------- Utilities ---------------- %
  551. /.pdforigfontcache_g 20 dict def
  552. currentglobal false setglobal
  553. systemdict /.pdforigfontcache_l 20 dict .forceput
  554. setglobal
  555. % Find an original font, using cache to prevent adjustfont to accumulate changes.
  556. /pdffindcachedfont { % <font_name> pdffindcachedfont <font>
  557. dup //.pdforigfontcache_g exch .knownget {
  558. exch pop
  559. } {
  560. dup .pdforigfontcache_l exch .knownget {
  561. exch pop
  562. } {
  563. dup findfont dup
  564. dup gcheck { //.pdforigfontcache_g } { .pdforigfontcache_l } ifelse
  565. % Stack : font_name font font cache
  566. 4 2 roll .growput
  567. } ifelse
  568. } ifelse
  569. } bind def
  570. % Add original font to cache to prevent adjustfont to accumulate changes.
  571. /pdfaddcachedfont { % <font_name> pdfaddcachedfont <font>
  572. dup findfont dup % name font font
  573. dup gcheck { //.pdforigfontcache_g } {.pdforigfontcache_l} ifelse
  574. 4 2 roll % font d name font
  575. put % font
  576. } bind def
  577. /.remove_font_name_prefix { % <name> .remove_font_name_prefix <name>
  578. dup .namestring (+) search {
  579. true exch
  580. { dup 65 lt exch 90 gt or {
  581. pop false exit
  582. } if
  583. } forall
  584. { pop exch pop cvn
  585. } {
  586. pop pop
  587. } ifelse
  588. } {
  589. pop
  590. } ifelse
  591. } bind def
  592. % Find a font (except for embedded ones), and adjust its encoding if necessary.
  593. /.pdfdfndict mark
  594. /defaultfontname /Helvetica
  595. .dicttomark readonly def
  596. /pdffindfont { % <font-resource> <fontname> pdffindfont <font>
  597. % If the font isn't available, synthesize one based on
  598. % its descriptor.
  599. dup /Font resourcestatus {
  600. pop pop pdffindcachedfont
  601. } {
  602. 1 index /FontDescriptor knownoget {
  603. % Stack: font-res fontname fontdesc
  604. dup /Flags oget
  605. dup 16#40 and -6 bitshift % 1, oblique/italic
  606. 1 index 16#40000 and -17 bitshift add % 2, bold
  607. exch 16#2 and 2 bitshift add % 8, serif
  608. % We should look at the fixed flag, too.
  609. % Stack: font-res fontname fontdesc properties
  610. % Even though /FontName is a required key in FontDescriptor dict
  611. % (As of the PDF 1.4 Reference Manual), In the case of missing
  612. % /FontName key, we substitue /BaseFont for the value of /FontName.
  613. % Yet another case of broken PDF's that Adobe Reader accepts.
  614. 1 index dup /FontName known {
  615. /FontName oget
  616. dup type /nametype ne {
  617. ( **** /FontName attribute in FontDescriptor is not a name.\n)
  618. pdfformaterror
  619. cvn
  620. } if
  621. } {
  622. ( **** FontDescriptor missing required /FontName key. BaseFont name used.\n)
  623. pdfformaterror
  624. pop 2 index % grab the BaseFont from the stack.
  625. } ifelse
  626. .remove_font_name_prefix
  627. exch
  628. % Analyzes font name and extract "Bold" and "Narrow" properties
  629. % which are not described by the FontDescriptor Flags.
  630. 0 2 index .fontnameproperties 6 and or
  631. % Rebind the default font name to Helvetica so that
  632. % fonts with no properties are handled correctly.
  633. //.pdfdfndict begin .substitutefontname end
  634. % Stack: font-res fontname fontdesc substname|null
  635. Fontmap 1 index known not {
  636. % No available good substitution, use the standard one.
  637. pop 1 index .substitutefont
  638. } if
  639. dup 3 index ne QUIET not and {
  640. (Substituting font ) print dup =only
  641. ( for ) print 2 index =only (.) = flush
  642. } if
  643. pdffindcachedfont
  644. % Stack: font-res fontname fontdesc font
  645. % If this is a small-caps font, replace the CharString
  646. % entries for a..z.
  647. exch /Flags oget 16#20000 and 0 ne {
  648. true .copyfontdict
  649. dup /CharStrings 2 copy get dup length dict .copydict
  650. % stack: font-res fontname font font /CharStrings CharStringsdict
  651. 5 index /FirstChar get 97 .max
  652. 6 index /LastChar get 122 .min 1 exch {
  653. % Stack: font-res fontname font' font' /CharStrings charstrings code
  654. % Note that this only remaps a-z, not accented characters.
  655. 6 index /Widths oget 1 index 8 index /FirstChar get sub oget
  656. 1 string dup 0 5 -1 roll put
  657. % Stack: font-res font' font' /CharStrings charstrings code
  658. % width (x)
  659. 2 index exch dup cvn exch
  660. dup 0 2 copy get 32 sub put 4 -1 roll {
  661. % Stack: operand (X) width
  662. 0 setcharwidth exch pop
  663. currentfont /FontMatrix get matrix invertmatrix concat
  664. 0.7 dup scale 0 0 moveto show
  665. } /exec cvx 4 packedarray cvx put
  666. } for put
  667. } if
  668. dup /FontName get 2 index ne {
  669. true .copyfontdict
  670. 2 copy exch /FontName exch put
  671. } if
  672. exch pop .completefont
  673. } {
  674. % No descriptor available, use the default algorithm.
  675. pdffindcachedfont
  676. } ifelse
  677. } ifelse
  678. exch pop
  679. } bdef
  680. % ---------------- Type 1 fonts ---------------- %
  681. /buildType1 % <Type1-font-resource> buildType1 <font>
  682. { dup /BaseFont get pdffindfont
  683. } bdef
  684. % Read an embedded Type 1 font.
  685. /readfontfilter { % <proc> readfontfilter <filter>
  686. 0 () /SubFileDecode filter
  687. } bdef
  688. % Adobe Acrobat doesn't skip space characters after eexec
  689. /eexec_pdf_param_dict mark
  690. .eexec_param_dict {} forall
  691. /keep_spaces true
  692. .dicttomark readonly def
  693. % When Type 1 font reading procedure is executing, a copy of this dictionary is current.
  694. % We have to do something special about embedded fonts that execute definefont
  695. % more than once -- that is the function of topFontDict.
  696. % The whole type1 stream can be executed directly. There's no need to process
  697. % Length1, 2, 3 keys.
  698. /readtype1dict 10 dict dup begin
  699. /definefont {
  700. exch pop
  701. /topFontDict where {
  702. { /FontType % in PLRM order
  703. /FontMatrix
  704. /FontName
  705. /FontInfo
  706. /WMode
  707. /Encoding
  708. /FontBBox
  709. /UniqueID
  710. /XUID
  711. /PaintType
  712. /StrokeWidth
  713. /Metrics
  714. /Metrics2
  715. /CDevProc
  716. /CharStrings
  717. /Private
  718. /WeightVector
  719. } {
  720. 2 copy .knownget {
  721. % Stack: font topFontDict /key val
  722. 3 index 3 1 roll put
  723. dup /MisplacedKey 0 put
  724. } {
  725. pop
  726. } ifelse
  727. } forall
  728. /MisplacedKey known {
  729. ( **** Warning: Type 1 font defines some of the keys in the external scope.\n)
  730. pdfformaterror
  731. } if
  732. } if
  733. dup /UniqueID .knownget {
  734. dup dup 0 lt exch 16#ffffff gt or {
  735. ( **** Warning: Ignoring invalid /UniqueID = ) exch =string cvs
  736. concatstrings (\n) concatstrings pdfformaterror
  737. dup /UniqueID undef
  738. } {
  739. pop
  740. } ifelse
  741. } if
  742. .completefont
  743. } bdef
  744. /undef_proc_warning {
  745. /Repaired true store % flag that we have warnings
  746. UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put
  747. } bdef
  748. /missing-type1-procs 6 dict begin
  749. /-| { string currentfile exch readstring pop /-| //undef_proc_warning exec } executeonly bdef
  750. /RD { string currentfile exch readstring pop /RD //undef_proc_warning exec } executeonly bdef
  751. /|- { noaccess def /|- //undef_proc_warning exec } executeonly bdef
  752. /ND { noaccess def /ND //undef_proc_warning exec } executeonly bdef
  753. /| { noaccess put /| //undef_proc_warning exec } executeonly bdef
  754. /NP { noaccess put /NP //undef_proc_warning exec } executeonly bdef
  755. currentdict end readonly def
  756. /eexec {
  757. % Assume the font dictionary is directly below the file on the stack
  758. count 0 gt { /topFontDict 2 index cvlit store } if
  759. //eexec_pdf_param_dict /eexecDecode filter
  760. //missing-type1-procs begin
  761. /userdict .systemvar begin
  762. //systemdict begin
  763. readtype1dictcopy begin cvx stopped
  764. currentfile flushfile % Skip the trailer after return from eexec, bug 690701.
  765. { currentdict end //missing-type1-procs eq { exit } if } loop
  766. { stop } if
  767. } bdef
  768. /readonly-op-dict <<
  769. /stringtype 0
  770. /arraytype 0
  771. /packedarraytype 0
  772. /dicttype 0
  773. >> readonly def
  774. /readonly { % bug 689617
  775. dup type //readonly-op-dict exch known {
  776. readonly
  777. } {
  778. ( **** Warning: Type 1 font applies operator readonly to a wrong type.\n)
  779. pdfformaterror
  780. } ifelse } .bind def
  781. /prev_get /get load def
  782. /get {
  783. dup /FontName eq {
  784. % No warning, probably FontName is defined elsewhere; see definefont above.
  785. .knownget not { /Missing } if
  786. } {
  787. dup /UniqueID eq {
  788. % We don't want fonts to check /UniqueID and do 'restore'.
  789. pop pop 16#FEDCBA98 % Arbitrary and invalid value
  790. } {
  791. prev_get
  792. } ifelse
  793. } ifelse
  794. } bdef
  795. /prev_begin /begin load def
  796. /begin {
  797. dup //systemdict eq { pop 0 dict } if
  798. prev_begin
  799. } bdef
  800. { /undef_proc_warning /missing-type1-procs /readonly-op-dict }
  801. { currentdict exch undef } forall
  802. end readonly def
  803. currentdict /eexec_pdf_param_dict .undef
  804. /readtype1 { % <font-resource> <stream-dict> readtype1 <font>
  805. 1 index exch % res res stream
  806. PDFfile fileposition 3 1 roll % res pos res stream
  807. dup /PFB known exch % res pos res pfb? stream
  808. true resolvestream % res pos res pfb? file
  809. exch {
  810. //false /PFBDecode filter
  811. } if
  812. % Some buggy embedded fonts leave extra junk on the stack,
  813. % so we have to make a closure that records the stack depth
  814. % in a fail-safe way. This code also removes the mark when
  815. % the implied cleartomark is not executed, i.e. Length3 == 0.
  816. % Also restore dictstack depth.
  817. %
  818. //systemdict begin
  819. //readtype1dict dup length 3 add dict copy begin
  820. 1 index /BaseFont oget /savedFontName exch def
  821. /topFontDict null def
  822. /readtype1dictcopy currentdict def
  823. { cvx exec } aload pop count 2 sub 3 packedarray cvx exec
  824. % clean up the dictstack
  825. { currentdict /topFontDict known not { end } { exit } ifelse } loop
  826. count exch sub { pop } repeat
  827. PDFfile 3 -1 roll setfileposition
  828. pop pop
  829. currentdict end end /topFontDict get
  830. } bdef
  831. % ---------------- Type 3 fonts ---------------- %
  832. /buildType3 { % <Type3-font-resource> buildType3 <font>
  833. 8 dict begin
  834. /FontType 3 def
  835. % If the font does not contain a Resources entry, then we use
  836. % the resources from our current context. Page 391 of the PDF
  837. % 1.6 spec says that the Resources dict is optional and if not
  838. % present then we should use the Resources for the page.
  839. % However we have a test file (687989) which uses a Type3 font
  840. % inside a form XObject and the desired Resources are in the
  841. % XObject dict and not in the Page dict. So we are going to
  842. % the parent object to find resources instead of only going to
  843. % the page dict when a font does not specify its required
  844. % resources.
  845. /Resources 1 index /Resources knownoget {
  846. oforce
  847. } {
  848. LocalResources
  849. } ifelse def
  850. /FontBBox 1 index /FontBBox get cvx def
  851. /FontMatrix 1 index /FontMatrix oget def
  852. /CharProcs 1 index /CharProcs oget def
  853. 1 index /Widths knownoget {
  854. /Widths exch def
  855. /FirstChar 1 index /FirstChar oget def
  856. /LastChar 1 index /LastChar oget def
  857. } if
  858. /FontName 1 index /Name knownoget not { /PDFType3Untitled } if def
  859. /Encoding .notdefEncoding 2 index getencoding def
  860. % We have to define BuildChar rather than BuildGlyph:
  861. % there is no PDF equivalent of glyphshow, and we need
  862. % the character code to access the Widths.
  863. /BuildChar {
  864. % Stack: font charcode
  865. 1 index begin 3 dict begin
  866. /Font 3 -1 roll def /CharCode 1 index def
  867. Encoding exch get CharProcs exch knownoget {
  868. { //false resolvestream
  869. % Stack: filepos stream
  870. % Don't let setgcolor set the color inside the BuildGlyph
  871. % procedure, because this causes an /undefined error.
  872. q //null /FillColor gput //null /StrokeColor gput
  873. Font /Resources get exch pdfopdict .pdfruncontext
  874. Q
  875. } PDFfile fileposition 2 .execn % Keep pdfcount valid.
  876. PDFfile exch setfileposition
  877. } {
  878. % PDF Type 3 fonts don't use .notdef
  879. % d1 implementation adjusts the width as needed
  880. 0 0 0 0 0 0
  881. pdfopdict /d1 get exec
  882. } ifelse
  883. end end
  884. } bdef
  885. dup currentdict Encoding .processToUnicode
  886. currentdict end .completefont exch pop
  887. } bdef
  888. /.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'>
  889. % Enforce the metrics, in glyph space, to the values found in the PDF Font object
  890. % - force wy == 0 (assumed, and not stored in the PDF font)
  891. % Even though PDF1.3-1.7 specifications state that this must be 0,
  892. % Distiller sometimes creates Type3 fonts with non-zero wy. We set
  893. % it to 0 since this is apparently what Acrobat Reader 4 and 5 do.
  894. % PDF1.2 does not mention this restriction, it only says
  895. % "see setcharwidth/ setcachedevice in the PostScript Reference".
  896. % - get wx from the Widths array (do nothing if not present)
  897. pop 0
  898. /Widths where {
  899. begin
  900. CharCode FirstChar ge CharCode LastChar le and {
  901. exch pop Widths CharCode FirstChar sub get exch
  902. } if end
  903. } if
  904. } bdef
  905. % ---------------- TrueType fonts ---------------- %
  906. /TTfonts mark
  907. /Arial /Helvetica
  908. /Arial,Italic /Helvetica-Oblique
  909. /Arial,Bold /Helvetica-Bold
  910. /Arial,BoldItalic /Helvetica-BoldOblique
  911. /CourierNew /Courier
  912. /CourierNew,Bold /Courier-Bold
  913. /TimesNewRoman /Times-Roman
  914. /TimesNewRoman,Italic /Times-Italic
  915. /TimesNewRoman,Bold /Times-Bold
  916. /TimesNewRoman,BoldItalic /Times-BoldItalic
  917. .dicttomark readonly def
  918. /buildTrueType { % <TrueType-font-resource> buildTrueType <font>
  919. dup /BaseFont oget
  920. dup /Font resourcestatus dup { exch pop exch pop } if not
  921. TTfonts 2 index known and {
  922. dup TTfonts exch get
  923. QUIET not {
  924. (Substituting font ) print dup =only
  925. ( for ) print 1 index =only (.) = flush
  926. } if
  927. exch 3 1 roll pdffindfont
  928. true .copyfontdict
  929. 2 copy exch /FontName exch put
  930. exch pop .completefont
  931. } {
  932. pdffindfont
  933. } ifelse
  934. } bdef
  935. % Read an embedded TrueType font.
  936. /readtruetype { % <font-resource> <stream-dict> readtruetype <font>
  937. 1 index exch
  938. PDFfile fileposition 3 1 roll
  939. //true resolvestream readfontfilter
  940. % Stack: filepos fontres stream
  941. 1 index /Subtype get /CIDFontType2 eq {
  942. 1 index /BaseFont get % Use the BaseFont name for the font. Otherwise we
  943. % would use the name table, or a manufactured name.
  944. .loadttcidfont
  945. % Stack: filepos fontres cidfont
  946. } {
  947. % filepos fontres stream
  948. 1 index /FontDescriptor oget
  949. /Flags get 4 and 0 ne {
  950. //true % symbolic
  951. } {
  952. 1 index /Encoding oknown not % no encoding => symbolic
  953. } ifelse
  954. dup {
  955. //null
  956. } {
  957. StandardEncoding
  958. 3 index getencoding
  959. } ifelse % filepos fontres stream is_symbolic Encoding
  960. dup 4 index exch % filepos fontres stream is_symbolic Encoding fontres Encoding
  961. /prebuilt_encoding exch put % filepos fontres stream is_symbolic Encoding
  962. .loadpdfttfont
  963. } ifelse
  964. exch pop
  965. PDFfile 3 -1 roll setfileposition
  966. % Ignore both the Encoding and the Widths.
  967. exch pop
  968. } bdef
  969. % ---------------- Type 0 fonts ---------------- %
  970. % Predefine the known CMaps, but only create them on demand.
  971. /knownCMaps mark
  972. /Identity-H { /Identity-H 0 makeIdentityCMap }
  973. /Identity-V { /Identity-V 1 makeIdentityCMap }
  974. .dicttomark def
  975. /makeIdentityCMap { % <cmapname> <wmode> .makeIdentityCMap -
  976. .currentglobal true .setglobal 3 1 roll
  977. /CIDInit /ProcSet findresource begin
  978. 12 dict begin
  979. begincmap
  980. /WMode exch def
  981. /CMapName exch def
  982. /CIDSystemInfo 3 dict dup begin
  983. /Registry (Adobe) def
  984. /Ordering (Identity) def
  985. /Supplement 0 def
  986. end def
  987. %/CMapName (see above)
  988. /CMapVersion 1 def
  989. /CMapType 1 def
  990. %WMode (see above)
  991. % The PDF documentation says that these CMaps map CIDs
  992. % "1 to 65,536". This is a misprint for 0 to 65,535.
  993. 1 begincodespacerange
  994. % <0001> <00ff> <0100> <ffff>
  995. <0000> <ffff>
  996. endcodespacerange
  997. 1 begincidrange
  998. % <0001> <00ff> 1 <0100> <ffff> 256
  999. <0000> <ffff> 0
  1000. endcidrange
  1001. endcmap
  1002. CMapName currentdict /CMap defineresource
  1003. knownCMaps CMapName 2 index put
  1004. end % CMap
  1005. end % CIDInit ProcSet
  1006. exch .setglobal
  1007. } bdef
  1008. /CMap_read_dict 3 dict begin
  1009. /defineresource % <name> <dict> <cat-name> defineresource <dict>
  1010. {
  1011. pop
  1012. /.last_CMap_def 1 index store
  1013. exch pop
  1014. } bdef
  1015. /CIDSystemInfo
  1016. {
  1017. ( **** Warning: CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
  1018. /CIDSystemInfo
  1019. } bdef % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
  1020. /CMapName
  1021. {
  1022. ( **** Warning: CMap has no CMapName.\n\
  1023. See the comment to revision 6201 in gs/doc/ps2pdf.htm#Problems .\n) pdfformaterror
  1024. /CMap1 % arbitrary, PDF defineresource tolerates non-unique names
  1025. } bdef % A work around incorrect ToUnicode CMap generated by GS before rev. 6201.
  1026. currentdict end readonly def
  1027. % Read embedded CMap stream.
  1028. % Following Acrobat we ignore everything outside
  1029. % begincodespacerange .. endcmap.
  1030. /read_CMap { % <name> <1> <stream> read_CMap <CMap>
  1031. % <2> <stream> read_CMap <CMap>
  1032. dup 0 (begincodespacerange) /SubFileDecode filter flushfile
  1033. //CMap_read_dict begin
  1034. /CIDInit /ProcSet findresource begin
  1035. 12 dict begin
  1036. /.last_CMap_def currentdict def % establish binding
  1037. /CMapType 3 -1 roll def
  1038. mark exch % emulate 'begincodespacerange'
  1039. 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
  1040. endcmap
  1041. /.last_CMap_def load
  1042. { currentdict end //CMap_read_dict eq { exit } if } loop
  1043. dup /.last_CMap_def undef
  1044. dup /CMapType get 1 eq {
  1045. /CMap defineresource
  1046. } if
  1047. } bdef
  1048. currentdict /CMap_read_dict undef
  1049. /buildType0 { % <Type0-font-resource> buildType0 <font>
  1050. dup /BaseFont get % FontName
  1051. 1 index /Encoding oget
  1052. dup type /nametype eq {
  1053. dup /CMap resourcestatus {
  1054. pop pop /CMap findresource
  1055. } {
  1056. knownCMaps 1 index .knownget
  1057. { exch pop exec } { /undefined signalerror } ifelse
  1058. } ifelse
  1059. } {
  1060. PDFfile fileposition exch
  1061. dup /CMapName oget exch
  1062. //true resolvestream
  1063. 1 exch read_CMap
  1064. exch PDFfile exch setfileposition
  1065. } ifelse % CMap
  1066. [
  1067. 3 index /DescendantFonts oget { exec resourcefont } forall
  1068. ] % subfonts
  1069. .composefontdict % composefont must insert FontInfo dictionary - see gs_cmap.ps .
  1070. % Stack: fontres name font
  1071. 3 copy exch pop null .processToUnicode
  1072. exch pop .completefont % Stack: fontres font
  1073. 1 index /FontMatrix knownoget {
  1074. dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
  1075. 1 index exch makefont exch /FontName get exch
  1076. exch pop .completefont
  1077. } {
  1078. pop
  1079. } ifelse
  1080. } if exch pop
  1081. } bdef
  1082. % ---------------- CIDFontType0/2 fonts ---------------- %
  1083. % Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
  1084. % arrays and using a (currently very inefficient) CDevProc.
  1085. % For detail, refer "PDF Reference" 2nd ed., p314 "5.6.3 CIDFonts".
  1086. % It notes default DW is 0, but Acrobat Reader uses 1000 as default.
  1087. % If DW is 0, currentpoint does not move by default in rendering text
  1088. % horizontally, the result is unreadable. You can check it by Acrobat.
  1089. /.pdfDefaultDW 1000 def
  1090. /.pdfDefaultDW2 [ 880 -1000 ] def
  1091. /addCIDmetrics { % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
  1092. dup length 5 add dict .copydict
  1093. dup /FID undef
  1094. dup /UniqueID undef
  1095. dup /XUID undef
  1096. % Insert the widths into the font.
  1097. % Stack: pdfresource newfont
  1098. 1 index /DW knownoget {
  1099. 1 index /DW 3 -1 roll put
  1100. } {
  1101. dup /DW .pdfDefaultDW put
  1102. } ifelse
  1103. 1 index /W knownoget {
  1104. //false 1 index { xcheck or } forall {
  1105. oforce_array
  1106. } if
  1107. dup 2 index /W 3 -1 roll put
  1108. .pdfMakeInternalW 1 index /.internalW 3 -1 roll put
  1109. } if
  1110. 1 index /DW2 knownoget {
  1111. 1 index /DW2 3 -1 roll put
  1112. } {
  1113. dup /DW2 .pdfDefaultDW2 put
  1114. } ifelse
  1115. 1 index /W2 knownoget {
  1116. //false 1 index { xcheck or } forall {
  1117. oforce_array
  1118. } if
  1119. dup 2 index /W2 3 -1 roll put
  1120. .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
  1121. } if
  1122. dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
  1123. exch pop
  1124. } bdef
  1125. /.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
  1126. % convert /W or /W2 to internal expression
  1127. %
  1128. % mtx_array: original /W or /W2 array
  1129. % item_size: number of metrics values per CID
  1130. %
  1131. % for detail of the metrics list format in PDF,
  1132. % refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
  1133. %
  1134. % format of single entry in internal expression
  1135. %
  1136. % [
  1137. % [cid_begin cid_end]
  1138. % value_is_varied (bool)
  1139. % [ [values for cid_begin...]
  1140. % [values for cid_begin + 1]
  1141. % ... ]
  1142. % ]
  1143. %
  1144. 7 dict
  1145. begin
  1146. /itemSize exch def
  1147. /M exch def % original /W or /W2
  1148. /Msize M length def
  1149. /Mi { M i get } def % W[i]
  1150. /Mi1 { M i 1 add get } def % W[i + 1]
  1151. /putMTXEntry <<
  1152. /arraytype {
  1153. [
  1154. [Mi Mi Mi1 length itemSize idiv add 1 sub]
  1155. true
  1156. [
  1157. 0 itemSize Mi1 length 1 sub {
  1158. [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
  1159. } for
  1160. ]
  1161. ]
  1162. /i i 2 add def
  1163. }
  1164. /integertype {
  1165. [
  1166. [Mi Mi1]
  1167. false
  1168. [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
  1169. ]
  1170. /i i 2 add itemSize add def
  1171. }
  1172. >> def
  1173. /i 0 def
  1174. [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
  1175. end
  1176. } def
  1177. /.pdfMakeInternalW { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
  1178. /.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
  1179. /.pdfGetMTXByCID { % <internalMTXArray> <cid>
  1180. % .pdfGetMTXByCID
  1181. % { <MTXEntry> true | false }
  1182. % get values for given CID from internal format of /W or /W2
  1183. exch
  1184. {
  1185. {
  1186. dup 0 get {} forall % Stack: <cid> <entry> <cid_0> <cid_1>
  1187. 3 index lt { pop pop false exit } if
  1188. 2 index exch sub dup 0 lt { pop pop false exit } if
  1189. 1 index 1 get not { pop 0 } if
  1190. exch 2 get exch get true exit
  1191. } loop
  1192. { exit } if
  1193. } forall
  1194. dup type /arraytype eq { exch pop true } { pop false } ifelse
  1195. } def
  1196. % Apply the [D]W[2] metrics to a character before displaying.
  1197. /CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury>
  1198. % <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
  1199. % <w0x'> ... <vy'>
  1200. begin % push <font> to currentdict
  1201. % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
  1202. 5 1 roll pop pop pop pop
  1203. % get FontMatrix that applies to this CID
  1204. % (needs to convert [D]W[2] values to glyph space)
  1205. currentdict /FontMatrix get
  1206. % if the currentfont is a CIDFontType 0 CIDFont,
  1207. % we need FDArray font's FontMatrix too
  1208. FontType 9 eq {
  1209. currentdict 2 index .type9mapcid
  1210. % <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <FontMatrix> (charstring) <FDArray#>
  1211. exch pop currentdict /FDArray get exch get /FontMatrix get
  1212. % <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <FontMatrix> <FontMatrix2>
  1213. matrix concatmatrix
  1214. } if
  1215. % preserve this FontMatrix at bottom of the stack
  1216. 8 1 roll
  1217. % Stack: <FontMatrix> <w0x> <w0y> <llx> <lly> <urx> <ury> <cid>
  1218. {
  1219. currentdict /DW .knownget not { % no DW
  1220. .pdfDefaultDW exit % replace <w0x> by defaultDW
  1221. } if
  1222. currentdict /.internalW .knownget not { % no W
  1223. exit % use already-stacked DW
  1224. } if
  1225. dup length 0 eq { % W is null array
  1226. pop % discard unusable W
  1227. exit % use already-stacked DW
  1228. } if
  1229. % W is finite array, try to get W_cid
  1230. 2 index .pdfGetMTXByCID { % got W, discard DW
  1231. exch pop {} forall
  1232. exit
  1233. } if
  1234. exit
  1235. } loop
  1236. 0 % <w0y'>
  1237. % Stack: <FontMatrix> <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
  1238. 9 -2 roll pop pop % discard <w0x> <w0y>
  1239. 7 2 roll % put <w0x'> <w0y'>
  1240. % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
  1241. 0 % <w1x'>
  1242. exch % put <w1x'>
  1243. % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
  1244. {
  1245. currentdict /DW2 .knownget not { % no DW2, use defaultDW2
  1246. .pdfDefaultDW2 exit
  1247. } if
  1248. currentdict /.internalW2 .knownget not { % has DW2, no W2
  1249. exit % use already-stacked DW2
  1250. } if
  1251. dup length 0 eq { % W2 is null array
  1252. pop % discard unusable W2
  1253. exit % use already-stacked DW2
  1254. } if
  1255. 2 index .pdfGetMTXByCID { % got W2_cid, discard DW2
  1256. exch pop
  1257. exit
  1258. } if
  1259. % could not get W2_cid
  1260. exit
  1261. } loop
  1262. exch pop % discard <cid>
  1263. % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury>
  1264. % <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
  1265. dup length 2 eq { % this is DW2
  1266. aload pop
  1267. exch 8 index 2 div % <vx'> = <w0x'> / 2
  1268. exch
  1269. } { % assume W2
  1270. aload pop
  1271. } ifelse
  1272. % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'>
  1273. % now, convert each metrics valude (1000th of text space) to glyph space
  1274. 10 -2 roll
  1275. % Stack: <FontMatrix> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'> <w0x'> <w0y'>
  1276. 3 {
  1277. 10 index idtransform exch 1000 div exch 1000 div
  1278. 6 2 roll
  1279. } repeat
  1280. 10 2 roll
  1281. % Stack: <FontMatrix> <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'>
  1282. 11 -1 roll pop
  1283. % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <w1y'> <vx'> <vy'>
  1284. end % recover currentdict
  1285. } def
  1286. % <string> <match> tailmatch ==> <pre> true
  1287. % ==> <string> false
  1288. /tailmatch {
  1289. 2 copy length 1 index length .min
  1290. dup 2 index length exch sub exch getinterval
  1291. 1 index eq {
  1292. length 1 index length exch sub
  1293. 0 exch getinterval true
  1294. } {
  1295. pop false
  1296. } ifelse
  1297. } bind def
  1298. /makeboldfont {
  1299. 16 dict begin
  1300. /strokewidth exch def
  1301. /basecidfont exch def
  1302. /FontMatrix [ 1 0 0 1 0 0 ] def
  1303. /CIDFontName /.boldfont def
  1304. /CIDFontType 1 def
  1305. /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
  1306. /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
  1307. /CIDSystemInfo dup basecidfont exch get def
  1308. /FontBBox [ basecidfont /FontBBox get cvx exec
  1309. 4 2 roll basecidfont /FontMatrix get transform
  1310. 4 2 roll basecidfont /FontMatrix get transform
  1311. ] def
  1312. /tmpstr 2 string def
  1313. /BuildGlyph {
  1314. gsave
  1315. exch begin
  1316. dup 256 idiv tmpstr exch 0 exch put
  1317. 256 mod tmpstr exch 1 exch put
  1318. rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
  1319. { basefont-V } { basefont-H } ifelse setfont
  1320. strokewidth setlinewidth
  1321. 1 setlinejoin
  1322. newpath
  1323. 0 0 moveto tmpstr false charpath stroke
  1324. 0 0 moveto tmpstr show
  1325. currentpoint setcharwidth
  1326. end
  1327. grestore
  1328. } bind def
  1329. currentdict
  1330. end
  1331. dup /CIDFontName get exch /CIDFont defineresource
  1332. } bind def
  1333. % <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
  1334. % CIDFont-resource is not modified.
  1335. /findCIDFont {
  1336. {
  1337. dup /CIDFont resourcestatus {
  1338. pop pop /CIDFont findresource
  1339. exit
  1340. } if
  1341. .remove_font_name_prefix
  1342. dup dup length string cvs
  1343. (,Bold) tailmatch {
  1344. exch pop
  1345. cvn findCIDFont 0.03 makeboldfont
  1346. exit
  1347. } if
  1348. (,Italic) tailmatch {
  1349. exch pop
  1350. cvn findCIDFont
  1351. [ 1 0 0.3 1 0 0 ] makefont
  1352. exit
  1353. } if
  1354. (,BoldItalic) tailmatch {
  1355. exch pop
  1356. cvn findCIDFont 0.03 makeboldfont
  1357. [ 1 0 0.3 1 0 0 ] makefont
  1358. exit
  1359. } if
  1360. QUIET not {
  1361. (Can't find CID font ") print dup =string cvs print (".) =
  1362. } if
  1363. pop
  1364. 1 index /CIDSystemInfo oget begin Registry (-) Ordering end
  1365. concatstrings concatstrings
  1366. cvn
  1367. QUIET not {
  1368. (Substituting CID font ) print dup ==only
  1369. ( for ) print 1 index ==only (, see doc/Use.htm#CIDFontSubstitution.) =
  1370. } if
  1371. exch pop
  1372. dup /CIDFont resourcestatus {
  1373. pop pop /CIDFont findresource exit
  1374. } if
  1375. QUIET not {
  1376. (The substitute CID font ") print dup =string cvs print
  1377. (" is not provided either. Will exit with error.) =
  1378. } if
  1379. /findresource cvx /undefined signalerror
  1380. } loop
  1381. } bdef
  1382. /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
  1383. dup /BaseFont get findCIDFont exch pop
  1384. } bdef
  1385. /buildCIDType2 { % <CIDFontType2-font-resource> buildCIDType2 <font>
  1386. dup /BaseFont get findCIDFont exch pop
  1387. } bdef
  1388. /processCIDToGIDMap { % <fontres> <cidfont> processCIDToGIDMap <fontres> <cidfont>
  1389. 1 index /CIDToGIDMap knownoget {
  1390. PDFfile fileposition 4 1 roll
  1391. dup /Identity eq {
  1392. pop
  1393. } {
  1394. true resolvestream
  1395. % Stack: filepos fontres font mapstream
  1396. % Can't know the length of the decompressed stream, so allocate a big buffer...
  1397. dup 65534 string readstring {
  1398. % Length exceeded max string size, use an array of two strings
  1399. 1 index 65534 string readstring pop % maybe a null string - not important.
  1400. 2 array astore
  1401. % Stack: filepos fontres font mapstream array
  1402. dup 1 get length 65534 add
  1403. } {
  1404. dup length
  1405. } ifelse
  1406. 2 idiv
  1407. % Stack: filepos fontres font mapstream array/string CIDCount
  1408. 3 index exch /CIDCount exch put
  1409. exch closefile exch
  1410. dup /CIDMap 4 -1 roll put
  1411. } ifelse
  1412. 3 2 roll PDFfile exch setfileposition
  1413. } if
  1414. } bdef
  1415. % Adjust a CIDFontType0 DW[2] in the font resource.
  1416. /adjustCIDType0 { % <font-resource> <font> adjustfont <font'>
  1417. addCIDmetrics
  1418. dup /CIDFontName get exch /CIDFont defineresource
  1419. } bind def
  1420. % Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource.
  1421. /adjustCIDType2 { % <font-resource> <font> adjustfont <font'>
  1422. addCIDmetrics
  1423. dup /CIDFontType get 2 eq { % OpenType CFF font converts to CIDFontType 0
  1424. processCIDToGIDMap % that ignores CIDMap.
  1425. } if
  1426. dup /CIDFontName get exch /CIDFont defineresource
  1427. } bind def
  1428. % ---------------- Other embedded fonts ---------------- %
  1429. /fontloadprocs mark
  1430. /Type1C /readType1C cvx
  1431. /CIDFontType0C /readCIDFontType0C cvx
  1432. .dicttomark readonly def
  1433. % Read an embedded compressed font.
  1434. /readType1C { % <font-resource> <stream-dict> readType1C <font>
  1435. 1 index exch
  1436. PDFfile fileposition 3 1 roll
  1437. dup true resolvestream dup readfontfilter
  1438. % Stack: pos resource streamdict stream filter
  1439. 3 index /FontDescriptor oget /FontName oget
  1440. 1 index
  1441. /FontSetInit /ProcSet findresource begin //true //false ReadData
  1442. { exch pop exit } forall
  1443. 7 1 roll
  1444. closefile closefile pop
  1445. PDFfile 3 -1 roll setfileposition
  1446. pop pop
  1447. } bdef
  1448. % Read an embedded CFF CIDFont.
  1449. /readCIDFontType0C { % <font-resource> <stream-dict> readCIDFontType0C <font>
  1450. PDFfile fileposition 3 1 roll
  1451. dup true resolvestream dup readfontfilter
  1452. % Stack: pos resource streamdict stream filter
  1453. 3 index /FontDescriptor oget /FontName oget
  1454. 1 index
  1455. /FontSetInit /ProcSet findresource begin //true //false ReadData pop
  1456. closefile closefile pop
  1457. PDFfile 3 -1 roll setfileposition
  1458. % Some broken Adobe software produces PDF files in which
  1459. % the FontName of the CFF font and the FontName in the
  1460. % FontDescriptor don't match the BaseFont in the font.
  1461. % Use the FontName, rather than the BaseFont, here.
  1462. dup /FontDescriptor oget /FontName oget /CIDFont findresource
  1463. addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  1464. } bdef
  1465. % Read an embedded OpenType font.
  1466. /readOTTOfont { % <font-resource> <stream-dict> readOTTOfont <font>
  1467. 1 index exch % res res strdict
  1468. PDFfile fileposition 3 1 roll % res pos res strdict
  1469. dup //true resolvestream % res pos res strdict stream
  1470. dup readfontfilter % res pos res strdict stream filter
  1471. 3 index /FontDescriptor oget
  1472. /FontName oget % res pos res strdict stream filter /name
  1473. 1 index .init_otto_font_file % res pos res strdict stream filter /name filter'
  1474. //true
  1475. 6 index /CIDSystemInfo known % res pos res strdict stream filter /name filter' bool bool
  1476. ReadData % res pos res strdict stream filter fontset
  1477. { exch pop exit } forall % res pos res strdict stream filter font
  1478. dup /FontType get 9 eq {
  1479. % OpenType may contain simple CFF font, which is accesed as a CIDFont by PDF.
  1480. % The font is converted to Type 9 CIDFont resource, which ignores CIDMap attribute.
  1481. % The following code just shuffles GlyphDirectory to the same effect.
  1482. 4 index /CIDToGIDMap knownoget {
  1483. dup type /dicttype eq {
  1484. 1 index /GlyphDirectory get exch % res pos res strdict stream filter font dir c2g
  1485. //true resolvestream % res pos res strdict stream filter font dir c2g_file
  1486. 256 dict begin
  1487. 0 2 index 0 get def % copy .notdef
  1488. 0 1 16#7fffffff {
  1489. 1 index read not { pop exit } if % res pos res strdict stream filter font dir c2g_file cid hi
  1490. 256 mul % res pos res strdict stream filter font dir c2g_file cid hi
  1491. 2 index read not { pop pop exit } if % res pos res strdict stream filter font dir c2g_file cid hi lo
  1492. add % res pos res strdict stream filter font dir c2g_file cid gid
  1493. dup 0 ne {
  1494. dup 4 index length lt {
  1495. 3 index exch get % res pos res strdict stream filter font dir c2g_file cid charstr
  1496. def % res pos res strdict stream filter font dir c2g_file
  1497. } {
  1498. pop pop
  1499. } ifelse
  1500. } {
  1501. pop pop
  1502. } ifelse
  1503. } for
  1504. closefile pop % res pos res strdict stream filter font
  1505. dup length dict copy % res pos res strdict stream filter font'
  1506. dup /GlyphDirectory currentdict put % res pos res strdict stream filter font'
  1507. end
  1508. dup /GlyphDirectory get 0 exch {
  1509. pop .max
  1510. } forall
  1511. 1 index exch /CIDCount exch 1 add put
  1512. } {
  1513. pop
  1514. } ifelse
  1515. } if
  1516. } if
  1517. 7 1 roll % font res pos res strdict stream filter
  1518. closefile closefile pop pop % font res pos
  1519. PDFfile exch setfileposition % font res
  1520. pop % font
  1521. } bdef
  1522. % ---------------- Font lookup ---------------- %
  1523. % Some PDF files mis-identify font type of the embedded font streams or
  1524. % include raw PFB font streams. Length1, Length2, Length3 may be wrong or
  1525. % missing. Adobe Acrobat corrects these errors transparently to the user.
  1526. %
  1527. % We ignore the font type keys and recognize the font type by the 1st 4 bytes
  1528. % of the font stream. The PFB stream is recognized by the 1st 2 bytes.
  1529. /fonttypeprocs mark % <font-resource> -proc- <font>
  1530. /Type0 //buildType0
  1531. /Type1 //buildType1
  1532. /MMType1 //buildType1
  1533. /Type3 //buildType3
  1534. /TrueType //buildTrueType
  1535. /CIDFontType0 //buildCIDType0
  1536. /CIDFontType2 //buildCIDType2
  1537. .dicttomark readonly def
  1538. /adjustfonttypes mark
  1539. /Type1 //adjustfont
  1540. /MMType1 //adjustfont
  1541. /TrueType //adjustfont
  1542. /CIDFontType0 //adjustCIDType0
  1543. /CIDFontType2 //adjustCIDType2
  1544. .dicttomark readonly def
  1545. % Bind a proc and define n names
  1546. % /name ... /name {proc} n bndef -
  1547. /bndef
  1548. { exch bind exch
  1549. { dup 3 1 roll def } repeat
  1550. pop
  1551. } bdef
  1552. % <stream> run-fonttypeproc <font>
  1553. /run-fonttypeproc {
  1554. dup /Subtype knownoget not { 0 } if % res /subtype
  1555. //fonttypeprocs 1 index known not {
  1556. ( **** Warning: Font /Subtype attribute is wrong or missing, /Type1 assumed.\n)
  1557. pdfformaterror
  1558. pop /Type1
  1559. } if
  1560. //fonttypeprocs exch get exec
  1561. } bdef
  1562. % Prototype for all procedures: <res> <desc> <stream> foo <font>
  1563. /font_tag_dict 13 dict begin
  1564. % When the font stream is absent or cannot be read we load the font by the name.
  1565. /no_stream
  1566. { pop pop
  1567. run-fonttypeproc
  1568. } bdef
  1569. /bad_stream
  1570. { ( **** Warning: Error reading font stream, loading font by the name\n)
  1571. pdfformaterror
  1572. //no_stream exec
  1573. } bdef
  1574. <8001> % PFB
  1575. { dup /PFB //true put
  1576. exch pop readtype1
  1577. } bdef
  1578. (%!PS) (%!Fo) % Type1
  1579. { exch pop readtype1
  1580. } 2 bndef
  1581. <01000401> <01000402> <01000403> <01000404> % Type 1C
  1582. <01000C02> <01000C03>
  1583. { exch pop
  1584. dup /Subtype get
  1585. fontloadprocs exch get exec
  1586. } 6 bndef
  1587. <00010000> (true) (typ1) (ttcf) % TrueType OpenType
  1588. { exch pop readtruetype
  1589. } 4 bndef
  1590. (OTTO)
  1591. { exch pop
  1592. readOTTOfont
  1593. } bdef
  1594. currentdict end readonly def
  1595. currentdict /bndef undef
  1596. /resourcefont % <font-resource> resourcefont <font>
  1597. { dup /PSFont .knownget dup {
  1598. pop /FID knownoget dup { pop type /fonttype eq } if
  1599. } if {
  1600. /PSFont get
  1601. } {
  1602. dup dup /FontDescriptor knownoget {
  1603. % font-res font-res font-desc
  1604. % The same font descriptor can be reused in a CID and non-CID contexts.
  1605. % Store CID and non-CID fonts under different keys. Bug 689301
  1606. 1 index /Subtype knownoget dup {
  1607. pop dup /CIDFontType0 eq exch /CIDFontType2 eq or
  1608. } if { /CIDFontObject } { /FontObject } ifelse
  1609. % font-res font-res font-desc /key
  1610. 2 copy .knownget {
  1611. 4 1 roll pop pop pop % font-res obj
  1612. } {
  1613. 4 1 roll % /key font-res font-res font-desc
  1614. dup /FontFile knownoget not {
  1615. dup /FontFile2 knownoget not {
  1616. dup /FontFile3 knownoget not {
  1617. //null
  1618. } if
  1619. } if
  1620. } if
  1621. % /key res res desc stream
  1622. dup //null ne {
  1623. PDFfile fileposition
  1624. mark {
  1625. 2 index //true resolvestream dup
  1626. 4 string readstring pop
  1627. exch closefile
  1628. } stopped {
  1629. cleartomark /bad_stream
  1630. } {
  1631. exch pop
  1632. } ifelse
  1633. PDFfile 3 -1 roll setfileposition
  1634. dup length 4 lt { pop /bad_stream } if
  1635. } {
  1636. /no_stream
  1637. } ifelse
  1638. % /key res res desc stream tag
  1639. //font_tag_dict 1 index known not {
  1640. dup 0 2 getinterval <8001> eq {
  1641. 0 2 getinterval % /key res res desc stream pfb_tag
  1642. } {
  1643. (12345678>\n) dup /ASCIIHexEncode filter dup 4 -1 roll writestring closefile
  1644. ( **** Warning: unrecognized font file starts with <) exch concatstrings
  1645. pdfformaterror
  1646. /no_stream % /key res res desc stream unknown_tag
  1647. } ifelse
  1648. } if
  1649. //font_tag_dict exch get exec
  1650. 1 index /FontDescriptor oget % /key res font desc
  1651. 4 -1 roll 2 index % res font desc /key font
  1652. put % Save pointer to the font.
  1653. } ifelse
  1654. } {
  1655. run-fonttypeproc
  1656. } ifelse
  1657. % Stack: font-res font
  1658. 1 index exch
  1659. 1 index /Subtype get
  1660. //adjustfonttypes exch .knownget { exec } { exch pop } ifelse
  1661. dup 3 1 roll /PSFont exch put
  1662. } ifelse
  1663. dup checkGlyphNames2Unicode
  1664. } bdef
  1665. currentdict /font_tag_dict .undef
  1666. currentdict /fonttypeprocs .undef
  1667. currentdict /adjustfonttypes .undef
  1668. drawopdict begin
  1669. /d0 {
  1670. .adjustcharwidth setcharwidth
  1671. } bdef
  1672. /d1 {
  1673. 2 copy % ... llx lly urx ury | urx ury
  1674. 0 ne exch 0 ne % ... llx lly urx ury | ury!=0 urx!=0
  1675. 3 index 6 index eq and % ... llx lly urx ury | ury!=0 (urx!=0 && llx==urx)
  1676. exch 2 index 5 index eq and or { % ... llx lly urx ury | (urx!=0 && llx==urx) || (ury!=0 && lly==ury)
  1677. % The bounding box is empty and likely incorrect. Don't cache.
  1678. pop pop pop pop .adjustcharwidth setcharwidth
  1679. } {
  1680. 6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
  1681. } ifelse
  1682. } bdef
  1683. /Tf {
  1684. 1 index Page /Font rget {
  1685. resourcefont exch Tf pop
  1686. }
  1687. { % Bug 689037
  1688. ( **** Warning: Tf refers to an unknown resource name: ) pdfformaterror
  1689. 1 index .namestring pdfformaterror
  1690. ( Assuming it's a font name.\n) pdfformaterror
  1691. Tf
  1692. } ifelse
  1693. } bdef
  1694. end
  1695. end % pdfdict
  1696. end % GS_PDF_ProcSet
  1697. .setglobal