pdf_font.ps 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  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,v 1.80 2005/09/29 15:24:53 leonardo Exp $
  16. % PDF font operations.
  17. % Finding a font by name can't give a proper result when PDF font names aren't unique.
  18. % But it is only the way to obtain a font in Postscript after a font file is executed.
  19. % Therefore using a FontName (and findfont) is allowed only
  20. % immediately after a font file is executed.
  21. % In all other cases the font to be found by a pointer through PDF structures.
  22. %
  23. % This ideal logics can't work for documents,
  24. % which define a font resource with an embedded font,
  25. % and another font resource with same BaseFont but with no embedded font
  26. % (and possibly with no font descriptor).
  27. % Our testbase does contain such examples.
  28. % In this case we do find font by FontName (with findfont),
  29. % since there is no other way to get a reasonable result.
  30. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  31. .currentglobal true .setglobal
  32. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  33. GS_PDF_ProcSet begin
  34. pdfdict begin
  35. % We cache the PostScript font in an additional element of the
  36. % font resource dictionary, called PSFont.
  37. % ---------------- Encodings ---------------- %
  38. /.notdefEncoding 256 { /.notdef } repeat 256 packedarray def
  39. % Apply a list of differences to an Encoding.
  40. % Note that the differences may cause the array to grow.
  41. /updateencoding { % <encoding|null> <differences> updateencoding <enc'>
  42. % Calculate the length of the result.
  43. % in case the incoming Encoding is null, use .notdefEncoding
  44. exch dup null eq { pop .notdefEncoding } if
  45. 0 0 3 index {
  46. dup type /nametype ne { exch pop oforce } { pop 1 add } ifelse
  47. % Differences list may not be in order, update the largest_index
  48. % stack: <Differences> <encoding> <largest_index> <at_index>
  49. 2 copy lt { exch pop dup } if % at_index is new largest
  50. } forall
  51. pop 1 index length .max array dup 0 4 -1 roll putinterval
  52. exch 0 exch {
  53. % Stack: enc' code element
  54. dup type /nametype ne
  55. { exch pop oforce }
  56. { 3 copy put pop 1 add }
  57. ifelse
  58. } forall pop
  59. } bdef
  60. % Get the Encoding for a font.
  61. /getencoding % <base-encoding> <font-resource> getencoding <enc>
  62. { /Encoding knownoget
  63. { dup type /nametype eq
  64. {
  65. % The published PDF specification says the Encoding name
  66. % "must be" one of the 3 predefined Encodings, implying
  67. % that an error should occur if it isn't. However, Acrobat
  68. % Reader simply ignores unknown names, and since there are
  69. % some buggy applications that rely on this, we do the same.
  70. dup dup dup /MacRomanEncoding eq
  71. exch /MacExpertEncoding eq or
  72. exch /WinAnsiEncoding eq or
  73. { exch pop findencoding
  74. }
  75. { pop
  76. }
  77. ifelse
  78. }
  79. { dup /BaseEncoding knownoget
  80. {
  81. dup / eq
  82. { pop
  83. ( **** Warning: Ignoring bad BaseEncoding name.\n) pdfformaterror
  84. % as found in a PDF file from J.D.Edwards OneWorld (B7333), bug 687786
  85. }
  86. {
  87. findencoding 3 -1 roll pop exch
  88. }
  89. ifelse
  90. }
  91. if
  92. /Differences knownoget { updateencoding } if
  93. }
  94. ifelse
  95. }
  96. if
  97. } bdef
  98. /checkGlyphNames2Unicode % <dict> checkGlyphNames2Unicode -
  99. {
  100. PDFDEBUG {
  101. dup /FontInfo .knownget {
  102. /GlyphNames2Unicode .knownget {
  103. (Has GlyphNames2Unicode) =
  104. pop % { exch == ==} forall
  105. } if
  106. } if
  107. } if
  108. pop
  109. } bind def
  110. % Define a font using it's FontName as the key.
  111. % Adjust a font according to the Encoding and Widths in the font resource.
  112. /adjustfont { % <font-resource> <font> adjustfont <font'>
  113. getfontencoding
  114. 3 copy .processToUnicode
  115. getfontmetrics 5 -1 roll pop .updatefont { dup /FontName get exch definefont } if
  116. } bind def
  117. % Get the (possibly modified) encoding of a font.
  118. /getfontencoding { % <font-resource> <font> getfontencoding
  119. % <font-resource> <font> <Encoding|null>
  120. 1 index /Encoding known {
  121. dup /Encoding knownoget { 2 index getencoding } { null } ifelse
  122. } {
  123. null
  124. } ifelse
  125. } bdef
  126. % Returns true if the current glyph is in the Differences array at
  127. % the specified index value. This is needed because the Widths
  128. % array may map to the same glyph at different positions from the
  129. % Encoding. We want to use the Width that was associated with the
  130. % one specified in the Encoding::Differences list.
  131. /match_in_diff % <Differences> <index> <glyphname> match_in_diff <bool>
  132. { false 4 1 roll 0 4 -1 roll % stack: false index glyphname at_index==0 Differences
  133. { exch 1 index type /nametype ne {
  134. % stack: false index glyphname Diff_element at_index
  135. pop % Diff_element is new at_index
  136. } {
  137. % stack: false index glyphname Diff_element at_index
  138. exch 2 index eq {
  139. % stack: false index glyphname at_index
  140. dup 3 index eq {
  141. true 5 1 roll % stack: true false index glyphname at_index
  142. pop exit
  143. } if
  144. } if
  145. 1 add % at_index++ stack: false index glyphname at_index'
  146. } ifelse
  147. } forall
  148. % stack: true false index glyphname
  149. % or : false index glyphname at_index
  150. pop pop pop
  151. } bdef
  152. /unique_name { % <dict> </root> unique_name </unique>
  153. %
  154. % Note : this function interacts with pdf_write_encoding in src/gdevpdtw.c
  155. % and with copied_drop_extension_glyphs in src\gxfcopy.c
  156. % by adding a reserved substring (~GS~).
  157. %
  158. .namestring % <<>> (root)
  159. 0 1 65535 {
  160. 5 string cvs % <<>> (root) (0)
  161. (~GS~) exch concatstrings
  162. 1 index exch % <<>> (root) (root) (~GS~0)
  163. concatstrings % <<>> (root) (root~GS~0)
  164. dup % <<>> (root) (root~GS~0) (root~GS~0)
  165. 3 index exch % <<>> (root) (root~GS~0) <<>> (root~GS~0)
  166. known not {
  167. exch pop exit % <<>> (root~GS~0)
  168. } if
  169. pop
  170. } for
  171. exch pop cvn % /root0
  172. } bdef
  173. % Get the metrics of a font, if specified.
  174. /getfontmetrics { % <font-resource> <font> <Encoding|null> getfontmetrics
  175. % <font-resource> <font> <Encoding|null>
  176. % <Metrics|null> <GlyphMap|null>
  177. 2 index /Widths known {
  178. dup null eq { pop dup /Encoding get } if
  179. 4 dict begin
  180. dup length dict
  181. /Metrics exch def
  182. /Encoding exch def
  183. /GlyphMap //null def
  184. exch
  185. dup /Widths oget /Widths exch def
  186. % Stack: font font-res
  187. % Note that widths are always based on a 1000-unit
  188. % character space, but the FontMatrix may specify
  189. % some other scale factor. Compensate for this here,
  190. % by scaling the Widths if necessary.
  191. 0.001 2 index /FontMatrix get 0 get div
  192. % Stack: font font-res mscale
  193. 1 index /FirstChar oget dup 1 4 index /LastChar oget
  194. { % Stack: font font-res mscale first-char index
  195. Encoding 1 index dup 2 index length ge {
  196. ( **** Warning: Font Encoding array size is smaller than character range.\n)
  197. pdfformaterror
  198. pop pop /.notdef
  199. } {
  200. get
  201. } ifelse
  202. Widths 2 index 4 index sub dup 2 index length ge {
  203. ( **** Warning: Font Widths array size is smaller than character range.\n)
  204. pdfformaterror
  205. % use MissingWidth if it's available, if not, default to 1000 (full width)
  206. pop pop 4 index /FontDescriptor knownoget {
  207. /MissingWidth knownoget not { 1000 } if
  208. } { 1000 } ifelse
  209. } {
  210. oget
  211. } ifelse
  212. % Stack: font font-res mscale first-char index charname width
  213. 4 index mul
  214. % The following 'loop' is only context for 'exit'.
  215. {
  216. % Work around a bug in pdfTeX, which can generate Encoding
  217. % vectors containing nulls :
  218. 1 index //null eq { exit } if
  219. Metrics 2 index .knownget {
  220. 1 index ne
  221. } {
  222. //false
  223. } ifelse {
  224. % Two or more Encoding elements refer same glyph name,
  225. % and Widths specify different wihts for it.
  226. % Since a Postscript font can't have different
  227. % Metrics for same glyph name,
  228. % we generate an unique name, and create a new
  229. % Charstrings entry with same glyph value.
  230. GlyphMap //null eq {
  231. /Encoding Encoding dup length array copy def
  232. /GlyphMap 4 dict def
  233. } if
  234. % To prevent too many new names, check whether
  235. % we can use one already created for same glyph.
  236. //true
  237. GlyphMap { % f r s c i n w b n1 n2
  238. 4 index eq { % f r s c i n w b n1
  239. dup Metrics exch get % f r s c i n w b n1 w1
  240. 3 index eq { % f r s c i n w b n1
  241. 4 3 roll pop % f r s c i w b n1
  242. 3 1 roll pop % f r s c i n1 w
  243. Encoding 3 index 3 index put
  244. //false % f r s c i n1 w b
  245. exit
  246. } {
  247. pop
  248. } ifelse
  249. } { % f r s c i n w b n1
  250. pop
  251. } ifelse
  252. } forall % f r s c i n w b
  253. { % Do create a new name.
  254. Metrics 2 index //unique_name exec % f r s c i n w nn
  255. Encoding 4 index 2 index put
  256. GlyphMap 1 index 5 -1 roll put % f r s c i w nn
  257. exch
  258. % Stack: font font-res mscale first-char index new_name width
  259. } if
  260. } if
  261. 2 copy Metrics 3 1 roll put
  262. exit
  263. } loop
  264. pop pop pop
  265. }
  266. for pop
  267. % Now fill in the MissingWidth for any encoded characters
  268. % that aren't in Metrics already. Note that built-in
  269. % fonts may have Widths/FirstChar/LastChar but no
  270. % FontDescriptor, so we must check for this.
  271. % Stack: font font-res mscale
  272. 1 index /FontDescriptor knownoget {
  273. Metrics exch
  274. /MissingWidth knownoget { 2 index mul } { 0 } ifelse exch
  275. Encoding {
  276. % Stack: font font-res mscale missing-width metrics charname
  277. % Work around the abovementioned pdfTeX bug.
  278. dup //null ne {
  279. 2 copy known not { 2 copy 4 index put } if pop
  280. } {
  281. pop
  282. } ifelse
  283. } forall pop pop pop
  284. } {
  285. pop
  286. } ifelse
  287. exch Encoding Metrics GlyphMap end
  288. } {
  289. //null //null
  290. } ifelse
  291. } bdef
  292. currentdict /unique_name undef
  293. currentdict /match_in_diff undef
  294. /ToUnicodeCMapReader 3 dict def
  295. //ToUnicodeCMapReader begin
  296. /defineresource % <name> <dict> <cat-name> defineresource <dict>
  297. {
  298. pop
  299. dup userdict exch /.lastToUnicode exch put
  300. exch pop
  301. } bind def
  302. /CIDSystemInfo
  303. {
  304. ( **** Warning: ToUnicode CMap has invalid syntax near CIDSystemInfo.\n) pdfformaterror
  305. /CIDSystemInfo
  306. } bind def % A work around a bug in Altona.Page_3.2002-09-27.pdf - a slash is missed.
  307. end
  308. /string2number % <string> string2number <number>
  309. { 0 exch dup 0 exch 1 exch length 1 sub { % n () i
  310. 1 index exch get % n () v
  311. 3 2 roll 256 mul add exch % v+n*256 ()
  312. } for
  313. pop % N
  314. } bind def
  315. /copy&def % <key> <value> <bool> copy&def -
  316. {
  317. { true
  318. } {
  319. currentdict gcheck {
  320. dup gcheck not
  321. } {
  322. false
  323. } ifelse
  324. } ifelse
  325. { currentglobal currentdict gcheck setglobal
  326. exch dup length string copy exch
  327. setglobal
  328. } if
  329. def
  330. } bind def
  331. /.convert_ToUnicode-into-g2u % <GlyphNames2Unicode> <Encoding|null> <CMap> .convert_ToUnicode-into-g2u -
  332. {
  333. PDFDEBUG {
  334. (.convert_ToUnicode-into-g2u beg) =
  335. } if
  336. 3 2 roll begin
  337. /.CodeMapData get % About the data format see gs_cmap.ps, the comment after "CMap operators".
  338. 1 get % code maps
  339. {
  340. PDFDEBUG {
  341. dup ==
  342. } if
  343. dup length 1 sub 0 exch 5 exch { % e [] i
  344. 2 copy get % e [] i (prefix)
  345. string2number % e [] i prefix
  346. 2 index 2 index 1 add get % e [] i prefix (key_size,?is_range,value_type,value_size)
  347. dup 0 get 8 mul % e [] i prefix (key_size,?is_range,value_type,value_size) key_size*8
  348. 3 2 roll exch bitshift exch % e [] i prefix<<key_size*8 (key_size,?is_range,value_type,value_size)
  349. dup 0 get exch 3 get % e [] i offset key_size value_size
  350. 4 index 4 index 2 add get % e [] i offset key_size value_size (keys)
  351. 5 index 5 index 3 add get % e [] i offset key_size value_size (keys) (values)
  352. PDFDEBUG {
  353. ( offset=) print 4 index =string cvs print
  354. ( key_size=) print 3 index =string cvs print
  355. ( value_size=) print 2 index =
  356. ( keys=) print 1 index ==
  357. ( values=) print dup ==
  358. } if
  359. 1 index length 0 eq {
  360. % A single pair.
  361. exch pop exch pop exch pop exch % e [] i (values) offset
  362. 4 index null ne {
  363. 4 index exch get
  364. } if % e [] i (values) cid|name
  365. exch
  366. PDFDEBUG {
  367. ( defined single: ) print 1 index =string cvs print ( ) print dup ==
  368. } if
  369. false copy&def % e [] i
  370. pop % e []
  371. } {
  372. % A range. % e [] i offset key_size value_size (keys) (values)
  373. dup length string copy % protect the original string from modifications below.
  374. 0 4 index 2 mul 3 index length 1 sub { % e [] i offset key_size value_size (keys) (values) j
  375. 2 index 1 index 6 index getinterval
  376. string2number % e [] i offset key_size value_size (keys) (values) j keyL
  377. PDFDEBUG {
  378. ( keyL=) print dup =string cvs print
  379. } if
  380. 3 index 2 index 7 index add 7 index getinterval
  381. string2number % e [] i offset key_size value_size (keys) (values) j keyL keyH
  382. PDFDEBUG {
  383. ( keyH=) print dup =
  384. } if
  385. 3 2 roll 6 index idiv 5 index mul % e [] i offset key_size value_size (keys) (values) keyL keyH J
  386. 3 index exch 6 index getinterval % e [] i offset key_size value_size (keys) (values) keyL keyH (valueL)
  387. 3 1 roll 1 exch { % e [] i offset key_size value_size (keys) (values) (value) k
  388. 9 index null ne {
  389. 9 index exch get % e [] i offset key_size value_size (keys) (values) (value) name
  390. } if % e [] i offset key_size value_size (keys) (values) (value) cid|name
  391. 1 index % e [] i offset key_size value_size (keys) (values) (value) cid|name (value)
  392. PDFDEBUG {
  393. ( defined from range: ) print 1 index =string cvs print ( ) print dup ==
  394. } if
  395. true copy&def % e [] i offset key_size value_size (keys) (values) (value)
  396. % Assuming the lowest byte of 'value' changes, others don't.
  397. dup dup length 1 sub % e [] i offset key_size value_size (keys) (values) (value) (value) l
  398. 2 copy get % e [] i offset key_size value_size (keys) (values) (value) (value) l v
  399. 1 add put % e [] i offset key_size value_size (keys) (values) (value')
  400. } for % e [] i offset key_size value_size (keys) (values) (value)
  401. } for
  402. pop pop pop pop pop pop pop % e []
  403. } ifelse
  404. } for
  405. pop % e
  406. } forall
  407. end
  408. pop %
  409. PDFDEBUG {
  410. (.convert_ToUnicode-into-g2u end) =
  411. } if
  412. } bind def
  413. /.processToUnicode % <font-resource> <font-dict> <encoding|null> .processToUnicode -
  414. {
  415. % Currently pdfwrite is only device which can handle GlyphNames2Unicoide to
  416. % generate a ToUnicode CMaps. So don't bother with other devices.
  417. currentdevice .devicename /pdfwrite eq {
  418. PDFDEBUG {
  419. (.processToUnicode beg) =
  420. } if
  421. 2 index /ToUnicode knownoget {
  422. dup type /nametype eq {
  423. % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
  424. ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformaterror
  425. pop
  426. } {
  427. PDFfile fileposition exch
  428. false resolvestream
  429. //ToUnicodeCMapReader begin
  430. cvx exec
  431. end
  432. PDFfile exch setfileposition
  433. 1 index /FontInfo .knownget not {
  434. 1 index /FontInfo 5 dict dup 4 1 roll put
  435. } if
  436. dup /GlyphNames2Unicode .knownget not {
  437. currentglobal exch dup gcheck setglobal
  438. dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
  439. 3 2 roll setglobal
  440. } if % font-res font-dict encoding|null font-info g2u
  441. exch pop exch % font-res font-dict g2u encoding|null
  442. userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
  443. .convert_ToUnicode-into-g2u % font-res font-dict
  444. null % font-res font-dict null
  445. } ifelse
  446. } if
  447. PDFDEBUG {
  448. (.processToUnicode end) =
  449. } if
  450. } if
  451. pop pop pop
  452. } bind def
  453. % ---------------- Descriptors ---------------- %
  454. % Partial descriptors for the 14 built-in fonts. Note that
  455. % from PDF 1.1 to PDF 1.2, the meaning of the Flag 6 in the FontDescriptor
  456. % object has undergone a subtle change in its meaning which has serious
  457. % consequences for searching with Acrobat:
  458. % In PDF 1.1, the flag meant: Font has StandardEncoding
  459. % In PDF 1.2, the flag means: Font has (subset of) StandardRomanCharacterSet
  460. /standardfontdescriptors mark
  461. /Courier mark /Flags 16#23 .dicttomark
  462. /Courier-Oblique 1 index
  463. /Courier-Bold 1 index
  464. /Courier-BoldOblique 1 index
  465. /Helvetica mark /Flags 16#20 .dicttomark
  466. /Helvetica-Oblique 1 index
  467. /Helvetica-Bold 1 index
  468. /Helvetica-BoldOblique 1 index
  469. /Times-Roman mark /Flags 16#22 .dicttomark
  470. /Times-Bold 1 index
  471. /Times-Italic mark /Flags 16#62 .dicttomark
  472. /Times-BoldItalic 1 index
  473. /Symbol mark /Flags 16#4 .dicttomark
  474. /ZapfDingbats 1 index
  475. .dicttomark readonly def
  476. % ---------------- Utilities ---------------- %
  477. /.pdforigfontcache_g 20 dict def
  478. currentglobal false setglobal
  479. systemdict /.pdforigfontcache_l 20 dict .forceput
  480. setglobal
  481. % Find an original font, using cache to prevent adjustfont to accumulate changes.
  482. /pdffindcachedfont { % <font_name> pdffindcachedfont <font>
  483. dup //.pdforigfontcache_g exch .knownget {
  484. exch pop
  485. } {
  486. dup .pdforigfontcache_l exch .knownget {
  487. exch pop
  488. } {
  489. dup findfont dup
  490. dup gcheck { //.pdforigfontcache_g } { .pdforigfontcache_l } ifelse
  491. % Stack : font_name font font cache
  492. 4 2 roll .growput
  493. } ifelse
  494. } ifelse
  495. } bind def
  496. % Add original font to cache to prevent adjustfont to accumulate changes.
  497. /pdfaddcachedfont { % <font_name> pdfaddcachedfont <font>
  498. dup findfont dup % name font font
  499. dup gcheck { //.pdforigfontcache_g } {.pdforigfontcache_l} ifelse
  500. 4 2 roll % font d name font
  501. put % font
  502. } bind def
  503. /.remove_font_name_prefix { % <name> .remove_font_name_prefix <name>
  504. dup .namestring (+) search {
  505. true exch
  506. { dup 65 lt exch 90 gt or {
  507. pop false exit
  508. } if
  509. } forall
  510. { pop exch pop cvn
  511. } {
  512. pop pop
  513. } ifelse
  514. } {
  515. pop
  516. } ifelse
  517. } bind def
  518. % Find a font (except for embedded ones), and adjust its encoding if necessary.
  519. /.pdfdfndict mark
  520. /defaultfontname /Helvetica
  521. .dicttomark readonly def
  522. /pdffindfont { % <font-resource> <fontname> pdffindfont <font>
  523. % If the font isn't available, synthesize one based on
  524. % its descriptor.
  525. dup /Font resourcestatus {
  526. pop pop pdffindcachedfont
  527. } {
  528. 1 index /FontDescriptor knownoget {
  529. % Stack: font-res fontname fontdesc
  530. dup /Flags oget
  531. dup 16#40 and -6 bitshift % 1, oblique/italic
  532. 1 index 16#40000 and -17 bitshift add % 2, bold
  533. exch 16#2 and 2 bitshift add % 8, serif
  534. % We should look at the fixed flag, too.
  535. % Stack: font-res fontname fontdesc properties
  536. % Even though /FontName is a required key in FontDescriptor dict
  537. % (As of the PDF 1.4 Reference Manual), In the case of missing
  538. % /FontName key, we substitue /BaseFont for the value of /FontName.
  539. % Yet another case of broken PDF's that Adobe Reader accepts.
  540. 1 index dup /FontName known {
  541. /FontName oget
  542. } {
  543. ( **** FontDescriptor missing required /FontName key. BaseFont name used.\n)
  544. pdfformaterror
  545. pop 2 index % grab the BaseFont from the stack.
  546. } ifelse
  547. .remove_font_name_prefix
  548. exch
  549. % Analyzes font name and extract "Narrow" property
  550. % which is not described by the FontDescriptor Flags.
  551. 0 2 index .fontnameproperties 4 and or
  552. % Rebind the default font name to Helvetica so that
  553. % fonts with no properties are handled correctly.
  554. //.pdfdfndict begin .substitutefontname end
  555. % Stack: font-res fontname fontdesc substname|null
  556. Fontmap 1 index known not {
  557. % No available good substitution, use the standard one.
  558. pop 1 index .substitutefont
  559. } if
  560. dup 3 index ne QUIET not and {
  561. (Substituting font ) print dup =only
  562. ( for ) print 2 index =only (.) = flush
  563. } if
  564. pdffindcachedfont
  565. % Stack: font-res fontname fontdesc font
  566. % If this is a small-caps font, replace the CharString
  567. % entries for a..z.
  568. exch /Flags oget 16#20000 and 0 ne {
  569. true .copyfontdict
  570. dup /CharStrings 2 copy get dup length dict .copydict
  571. % stack: font-res fontname font font /CharStrings CharStringsdict
  572. 5 index /FirstChar get 97 .max
  573. 6 index /LastChar get 122 .min 1 exch {
  574. % Stack: font-res fontname font' font' /CharStrings charstrings code
  575. % Note that this only remaps a-z, not accented characters.
  576. 6 index /Widths oget 1 index 8 index /FirstChar get sub oget
  577. 1 string dup 0 5 -1 roll put
  578. % Stack: font-res font' font' /CharStrings charstrings code
  579. % width (x)
  580. 2 index exch dup cvn exch
  581. dup 0 2 copy get 32 sub put 4 -1 roll {
  582. % Stack: operand (X) width
  583. 0 setcharwidth exch pop
  584. currentfont /FontMatrix get matrix invertmatrix concat
  585. 0.7 dup scale 0 0 moveto show
  586. } /exec cvx 4 packedarray cvx put
  587. } for put
  588. } if
  589. dup /FontName get 2 index ne {
  590. true .copyfontdict
  591. 2 copy exch /FontName exch put
  592. } if
  593. definefont
  594. } {
  595. % No descriptor available, use the default algorithm.
  596. pdffindcachedfont
  597. } ifelse
  598. } ifelse
  599. exch pop
  600. } bdef
  601. % ---------------- Type 1 fonts ---------------- %
  602. /buildType1 % <Type1-font-resource> buildType1 <font>
  603. { dup /BaseFont get pdffindfont
  604. } bdef
  605. % The state dictionary for the embedded Type 1 font reading procedure
  606. % has the following keys and values:
  607. % data - stream (filter)
  608. % buffer, buffer2 - string
  609. % hexify - procedure to convert buffer to hex if needed
  610. % leftstr - string containing (non-negative) integer
  611. % sectionstr - string containing a character 0 .. 3
  612. % stream - (stream) dictionary
  613. % proc - procedure of the form {-dict- type1read}
  614. % pfbhdr - string containing 16#80 if PFB, 0 otherwise
  615. % When the procedure is executing, this dictionary is current.
  616. % leftstr and sectionstr are strings so that we can change their values
  617. % reliably in case the font executes a restore!
  618. % We also have to do something special about embedded fonts that
  619. % execute definefont more than once -- that is the function of topFontDict.
  620. % Read an embedded Type 1 font.
  621. /readfontfilter { % <proc> readfontfilter <filter>
  622. 0 () /SubFileDecode filter
  623. } bdef
  624. /readtype1dict 5 dict dup begin
  625. /definefont {
  626. dup topFontDict eq topFontDict null eq or {
  627. dup wcheck not { dup length dict copy } if
  628. exch pop savedFontName exch
  629. } if
  630. //systemdict /definefont get exec
  631. } bdef
  632. /eexec {
  633. % Assume the font dictionary is directly below the file on the stack
  634. count 0 gt { /topFontDict 2 index cvlit store } if
  635. //.eexec_param_dict /eexecDecode filter
  636. //systemdict begin readtype1dictcopy begin cvx stopped
  637. currentdict readtype1dictcopy eq { end } if
  638. currentdict //systemdict eq { end } if
  639. { stop } if
  640. } bdef
  641. /undef_proc_warning {
  642. /Repaired true store % flag that we have warnings
  643. UndefProcList exch 2 copy .knownget { 1 add } { 1 } ifelse put
  644. } bdef
  645. /-| { string currentfile exch readstring pop /-| undef_proc_warning } executeonly bdef
  646. /RD { string currentfile exch readstring pop /RD undef_proc_warning } executeonly bdef
  647. /|- { noaccess def /|- undef_proc_warning } executeonly bdef
  648. /ND { noaccess def /ND undef_proc_warning } executeonly bdef
  649. /| { noaccess put /| undef_proc_warning } executeonly bdef
  650. /NP { noaccess put /NP undef_proc_warning } executeonly bdef
  651. end readonly def
  652. /readtype1 { % <font-resource> <stream-dict> readtype1 <font>
  653. % Read the definition, using a procedure-based filter
  654. % that turns binary/hex conversion on and off
  655. % at the right times.
  656. 1 index exch
  657. PDFfile fileposition 3 1 roll
  658. 11 dict begin
  659. /leftstr ( ) 10 string copy def
  660. dup /Length1 oget leftstr cvs pop
  661. /sectionstr <00> 1 string copy def
  662. /pfbhdr <00> 1 string copy def
  663. /stream 1 index def
  664. true resolvestream /data exch def
  665. /buffer 1000 string def % arbitrary
  666. /buffer2 buffer length 2.1 div cvi 1 sub string def
  667. /hexify /buf2hex load def
  668. currentdict end
  669. /type1read cvx 2 array astore cvx dup 0 get /proc 2 index put
  670. readfontfilter
  671. % Some buggy embedded fonts leave extra junk on the stack,
  672. % so we have to make a closure that records the stack depth
  673. % in a fail-safe way. Also restore dictstack depth.
  674. //systemdict begin
  675. % The PDF specification is somewhat muddy about whether
  676. % an embedded font's name is supposed to be the BaseFont
  677. % from the Font object or the FontName from the descriptor.
  678. % Acrobat Distiller requires the former. Save away the
  679. % name so we can substitute it at definefont time.
  680. //readtype1dict dup length 3 add dict copy begin
  681. 1 index /BaseFont oget /savedFontName exch def
  682. /topFontDict null def
  683. /readtype1dictcopy currentdict def
  684. { run } aload pop count 1 sub 2 packedarray cvx exec
  685. % clean up the dictstack
  686. { currentdict /topFontDict known not { end } { end end exit } ifelse } loop
  687. count exch sub { pop } repeat
  688. PDFfile 3 -1 roll setfileposition
  689. /BaseFont oget pdfaddcachedfont
  690. exch pop
  691. } bdef
  692. % Execute the appropriate reading procedure.
  693. /type1read % <dict> type1read <string>
  694. { begin leftstr cvi
  695. { type1read0 type1read1 type1read2 type1read3 } sectionstr 0 get get exec
  696. ( ) leftstr copy cvs pop end
  697. } bdef
  698. % Read the next block of data into the buffer.
  699. /type1readdata % <left> <buffer> type1readdata <substring> <left'>
  700. { 0 2 index 2 index length .min getinterval
  701. % Adobe requires readstring to signal an error if given
  702. % an empty string. Work around this nonsense here.
  703. dup length 0 ne { data exch readstring pop } if
  704. dup length 3 -1 roll exch sub
  705. PDFDEBUG
  706. { dup =only ( read ) print
  707. 1 index length =only (: ) print
  708. 1 index == flush
  709. } if
  710. } bdef
  711. % Read the initial byte to see if we need to skip a 6 byte PFB header
  712. /type1read0 { % <left> type1read0 <string> <left'>
  713. sectionstr 0 1 put % either way we go to the next stage
  714. pfbhdr type1readdata
  715. 1 index 0 get 16#80 eq {
  716. ( **** Warning: Embedded Type1 font in PFB format is not valid PDF.\n)
  717. pdfformaterror
  718. PDFDEBUG { (skipping PFB header) = flush } if
  719. exch pop buffer 0 5 getinterval type1readdata exch
  720. dup 4 get 256 mul 1 index 3 get add 256 mul
  721. 1 index 2 get add 256 mul 1 index 1 get add
  722. PDFDEBUG { (PFB segment length = ) print dup = } if
  723. exch pop % discard the string keeping the PFB segment length
  724. 2 copy ne {
  725. ( **** Warning: Type 1 PFB segment length and Length 1 value do not match.\n)
  726. pdfformaterror
  727. exch % keep the PFB length instead
  728. } if
  729. pop
  730. buffer type1readdata % go ahead and read a block
  731. }
  732. if % if not PFB, return pfbhdr string (first char of file, usually %).
  733. } bdef
  734. % Read the next block of the initial text portion.
  735. /type1read1 { % <left> type1read1 <string> <left'>
  736. PDFDEBUG { (read1 ) print } if
  737. dup 0 eq {
  738. pop sectionstr 0 2 put
  739. stream /Length2 oget
  740. % Determine whether to hexify data for eexec.
  741. dup 8 lt {
  742. type1read2 % Hexify.
  743. } {
  744. PDFDEBUG { (read2 ) print } if
  745. pfbhdr 0 get 16#80 eq {
  746. % eat 6 more bytes of PFB junk before proceeding
  747. PDFDEBUG { (skipping PFB header in segment 2) = flush } if
  748. buffer 0 6 getinterval type1readdata exch
  749. dup 5 get 256 mul 1 index 4 get add 256 mul
  750. 1 index 3 get add 256 mul 1 index 2 get add
  751. PDFDEBUG { (PFB segment length = ) print dup = } if
  752. exch pop % discard the string keeping the PFB segment length
  753. 2 copy ne {
  754. ( **** Warning: Type 1 PFB segment length and Length 2 value do not match.\n)
  755. pdfformaterror
  756. exch % keep the PFB length instead
  757. } if
  758. pop
  759. } if
  760. buffer2 type1readdata exch
  761. % The check doesn't have to be 100% accurate:
  762. % hexifying is always OK.
  763. dup 0 8 getinterval 0 exch { or } forall
  764. 128 ge {
  765. /hexify { } store
  766. /buffer2 buffer def % We don't need an intermediate buffer.
  767. } if hexify exch
  768. } ifelse
  769. } {
  770. buffer type1readdata
  771. } ifelse
  772. } bdef
  773. % Convert a string from binary to hex for eexec.
  774. % Free variables: buffer.
  775. /buf2hex { % <string> buf2hex <hexstring>
  776. buffer /ASCIIHexEncode filter dup 3 -1 roll writestring closefile
  777. buffer (>) search pop exch pop exch pop
  778. } bdef
  779. % Read the next block of the encrypted portion.
  780. /type1trailer
  781. (0000000000000000000000000000000000000000000000000000000000000000\n\
  782. 0000000000000000000000000000000000000000000000000000000000000000\n\
  783. 0000000000000000000000000000000000000000000000000000000000000000\n\
  784. 0000000000000000000000000000000000000000000000000000000000000000\n\
  785. 0000000000000000000000000000000000000000000000000000000000000000\n\
  786. 0000000000000000000000000000000000000000000000000000000000000000\n\
  787. 0000000000000000000000000000000000000000000000000000000000000000\n\
  788. 0000000000000000000000000000000000000000000000000000000000000000\n\
  789. cleartomark\n)
  790. readonly def
  791. /type1read2 { % <left> type1read2 <string> <left'>
  792. PDFDEBUG { (read2 ) print } if
  793. dup 0 eq
  794. { pop sectionstr 0 3 put
  795. stream /Length3 oget
  796. dup 0 eq
  797. { PDFDEBUG { (trailer ) print } if
  798. type1trailer exch
  799. }
  800. {
  801. pfbhdr 0 get 16#80 eq {
  802. % eat 6 more bytes of PFB junk before proceeding
  803. PDFDEBUG { (skipping PFB header in segment 3) = flush } if
  804. buffer 0 6 getinterval type1readdata exch
  805. dup 5 get 256 mul 1 index 4 get add 256 mul
  806. 1 index 3 get add 256 mul 1 index 2 get add
  807. PDFDEBUG { (PFB segment length = ) print dup = } if
  808. exch pop % discard the string keeping the PFB segment length
  809. 2 copy ne {
  810. ( **** Warning: Type 1 PFB segment length and Length 3 value do not match.\n)
  811. pdfformaterror
  812. exch % keep the PFB length instead
  813. } if
  814. pop
  815. } if
  816. type1read3
  817. }
  818. ifelse
  819. }
  820. { buffer2 type1readdata exch hexify exch
  821. }
  822. ifelse
  823. } bdef
  824. % Read the next block of the final text portion.
  825. % When finished, this procedure returns an empty string.
  826. /type1read3 % <left> type1read3 <string> <left'>
  827. { PDFDEBUG { (read3 ) print } if
  828. buffer type1readdata
  829. } bdef
  830. % ---------------- Type 3 fonts ---------------- %
  831. /buildType3 { % <Type3-font-resource> buildType3 <font>
  832. 8 dict begin
  833. /FontType 3 def
  834. % If the font does not contain a Resources entry, then we use
  835. % the resources from our current context. Page 391 of the PDF
  836. % 1.6 spec says that the Resources dict is optional and if not
  837. % present then we should use the Resources for the page.
  838. % However we have a test file (687989) which uses a Type3 font
  839. % inside a form XObject and the desired Resources are in the
  840. % XObject dict and not in the Page dict. So we are going to
  841. % the parent object to find resources instead of only going to
  842. % the page dict when a font does not specify its required
  843. % resources.
  844. /Resources 1 index /Resources knownoget {
  845. oforce
  846. } {
  847. LocalResources
  848. } ifelse def
  849. /FontBBox 1 index /FontBBox get cvx def
  850. /FontMatrix 1 index /FontMatrix oget def
  851. /CharProcs 1 index /CharProcs oget def
  852. 1 index /Widths knownoget {
  853. /Widths exch def
  854. /FirstChar 1 index /FirstChar oget def
  855. /LastChar 1 index /LastChar oget def
  856. } if
  857. /FontName 1 index /Name .knownget not {
  858. PDFfile fileposition 16 10 string cvrs cvn
  859. } if def
  860. /Encoding .notdefEncoding 2 index getencoding def
  861. % We have to define BuildChar rather than BuildGlyph:
  862. % there is no PDF equivalent of glyphshow, and we need
  863. % the character code to access the Widths.
  864. /BuildChar {
  865. % Stack: font charcode
  866. 1 index begin 3 dict begin
  867. /Font 3 -1 roll def /CharCode 1 index def
  868. % Make unknown characters map to /.notdef
  869. Encoding exch get dup CharProcs exch known
  870. { CharProcs exch oget }
  871. { pop CharProcs /.notdef oget }
  872. ifelse
  873. PDFfile fileposition exch
  874. false resolvestream
  875. % Stack: filepos stream
  876. % Don't let setgcolor set the color inside the BuildGlyph
  877. % procedure, because this causes an /undefined error.
  878. q null /FillColor gput null /StrokeColor gput
  879. Font /Resources get exch pdfopdict .pdfruncontext
  880. Q
  881. PDFfile exch setfileposition
  882. end end
  883. } bdef
  884. dup currentdict Encoding .processToUnicode
  885. FontName currentdict end definefont exch pop
  886. } bdef
  887. /.adjustcharwidth { % <wx> <wy> .adjustcharwidth <wx'> <wy'>
  888. /Widths where {
  889. begin
  890. CharCode FirstChar ge CharCode LastChar le and {
  891. exch pop Widths CharCode FirstChar sub get exch
  892. } if end
  893. } if
  894. } bdef
  895. % ---------------- TrueType fonts ---------------- %
  896. /TTfonts mark
  897. /Arial /Helvetica
  898. /Arial,Italic /Helvetica-Oblique
  899. /Arial,Bold /Helvetica-Bold
  900. /Arial,BoldItalic /Helvetica-BoldOblique
  901. /CourierNew /Courier
  902. /CourierNew,Bold /Courier-Bold
  903. /TimesNewRoman /Times-Roman
  904. /TimesNewRoman,Italic /Times-Italic
  905. /TimesNewRoman,Bold /Times-Bold
  906. /TimesNewRoman,BoldItalic /Times-BoldItalic
  907. .dicttomark readonly def
  908. /buildTrueType { % <TrueType-font-resource> buildTrueType <font>
  909. dup /BaseFont oget
  910. /Repaired true store % flag that we had warnings
  911. TTFWarnList 1 index true put % Add fontname to the list
  912. dup TTfonts exch .knownget {
  913. QUIET not {
  914. (Substituting font ) print dup =only
  915. ( for ) print 1 index =only (.) = flush
  916. } if
  917. exch 3 1 roll pdffindfont
  918. true .copyfontdict
  919. 2 copy exch /FontName exch put
  920. definefont
  921. } {
  922. pdffindfont
  923. } ifelse
  924. } bdef
  925. % Read an embedded TrueType font.
  926. /readtruetype { % <font-resource> <stream-dict> readtruetype <font>
  927. % This is much simpler than readtype1, because we don't
  928. % have to deal with the tripartite .PFB format.
  929. 1 index exch
  930. PDFfile fileposition 3 1 roll
  931. true resolvestream readfontfilter
  932. % Stack: filepos fontres stream
  933. 1 index /Subtype get /CIDFontType2 eq {
  934. .loadttcidfont
  935. % Stack: filepos fontres cidfont
  936. } {
  937. % filepos fontres stream
  938. 1 index /FontDescriptor oget % filepos fontres stream fd
  939. /Flags get 4 and 0 ne % filepos fontres stream is_symbolic
  940. dup {
  941. 2 index null exch getencoding % filepos fontres stream is_symbolic Encoding
  942. dup 4 index exch % filepos fontres stream is_symbolic Encoding fontres Encoding
  943. /prebuilt_encoding exch put % filepos fontres stream is_symbolic Encoding
  944. } {
  945. null
  946. } ifelse
  947. .loadpdfttfont
  948. } ifelse
  949. exch pop
  950. PDFfile 3 -1 roll setfileposition
  951. % Ignore both the Encoding and the Widths.
  952. exch pop
  953. } bdef
  954. % ---------------- Type 0 fonts ---------------- %
  955. % Predefine the known CMaps, but only create them on demand.
  956. /knownCMaps mark
  957. /Identity-H { /Identity-H 0 makeIdentityCMap }
  958. /Identity-V { /Identity-V 1 makeIdentityCMap }
  959. .dicttomark def
  960. /makeIdentityCMap { % <cmapname> <wmode> .makeIdentityCMap -
  961. .currentglobal true .setglobal 3 1 roll
  962. /CIDInit /ProcSet findresource begin
  963. 12 dict begin
  964. begincmap
  965. /WMode exch def
  966. /CMapName exch def
  967. /CIDSystemInfo 3 dict dup begin
  968. /Registry (Adobe) def
  969. /Ordering (Identity) def
  970. /Supplement 0 def
  971. end def
  972. %/CMapName (see above)
  973. /CMapVersion 1 def
  974. /CMapType 1 def
  975. %WMode (see above)
  976. % The PDF documentation says that these CMaps map CIDs
  977. % "1 to 65,536". This is a misprint for 0 to 65,535.
  978. 1 begincodespacerange
  979. % <0001> <00ff> <0100> <ffff>
  980. <0000> <ffff>
  981. endcodespacerange
  982. 1 begincidrange
  983. % <0001> <00ff> 1 <0100> <ffff> 256
  984. <0000> <ffff> 0
  985. endcidrange
  986. endcmap
  987. CMapName currentdict /CMap defineresource
  988. knownCMaps CMapName 2 index put
  989. end % CMap
  990. end % CIDInit ProcSet
  991. exch .setglobal
  992. } bdef
  993. /buildType0 { % <Type0-font-resource> buildType0 <font>
  994. dup /BaseFont get % FontName
  995. 1 index /Encoding oget
  996. dup type /nametype eq {
  997. dup /CMap resourcestatus {
  998. pop pop /CMap findresource
  999. } {
  1000. knownCMaps 1 index .knownget
  1001. { exch pop exec } { /undefined signalerror } ifelse
  1002. } ifelse
  1003. } {
  1004. PDFfile fileposition exch
  1005. dup /CMapName get exch true resolvestream cvx exec
  1006. /CMap findresource
  1007. exch PDFfile exch setfileposition
  1008. } ifelse % CMap
  1009. [
  1010. 3 index /DescendantFonts oget { exec resourcefont } forall
  1011. ] % subfonts
  1012. composefont % composefont must insert FontInfo dictionary - see gs_cmap.ps .
  1013. % Stack: fontres font
  1014. 2 copy null .processToUnicode
  1015. 1 index /FontMatrix knownoget {
  1016. dup aload pop true {0 0 1 0 0 1} {3 -1 roll eq and} forall {
  1017. 1 index exch makefont exch /FontName get exch definefont
  1018. } {
  1019. pop
  1020. } ifelse
  1021. } if exch pop
  1022. } bdef
  1023. % ---------------- CIDFontType0/2 fonts ---------------- %
  1024. % Insert metrics into a CIDFont, by saving the PDF W, W2, DW, and DW2
  1025. % arrays and using a (currently very inefficient) CDevProc.
  1026. % For detail, refer "PDF Reference" 2nd ed., p314 "5.6.3 CIDFonts".
  1027. % It notes default DW is 0, but Acrobat Reader uses 1000 as default.
  1028. % If DW is 0, currentpoint does not move by default in rendering text
  1029. % horizontally, the result is unreadable. You can check it by Acrobat.
  1030. /.pdfDefaultDW 1000 def
  1031. /.pdfDefaultDW2 [ 880 -1000 ] def
  1032. /addCIDmetrics { % <CIDFont-resource> <CIDFont> addCIDmetrics <fontdict>
  1033. dup length 5 add dict .copydict
  1034. dup /FID undef
  1035. dup /UniqueID undef
  1036. dup /XUID undef
  1037. % Insert the widths into the font.
  1038. % Stack: pdfresource newfont
  1039. 1 index /DW .knownget {
  1040. 1 index /DW 3 -1 roll put
  1041. } {
  1042. dup /DW .pdfDefaultDW put
  1043. } ifelse
  1044. 1 index /W .knownget {
  1045. dup 2 index /W 3 -1 roll put
  1046. .pdfMakeInternalW 1 index /.internalW 3 -1 roll put
  1047. } if
  1048. 1 index /DW2 .knownget {
  1049. 1 index /DW2 3 -1 roll put
  1050. } {
  1051. dup /DW2 .pdfDefaultDW2 put
  1052. } ifelse
  1053. 1 index /W2 .knownget {
  1054. dup 2 index /W2 3 -1 roll put
  1055. .pdfMakeInternalW2 1 index /.internalW2 3 -1 roll put
  1056. } if
  1057. dup /CDevProc 1 index /CIDWProc load /exec load 3 packedarray cvx put
  1058. exch pop
  1059. } bdef
  1060. /.pdfMakeInternalMTXArray { % <mtx_array> <item_size> .pdfConvertInternalW <mtx_array'>
  1061. % convert /W or /W2 to internal expression
  1062. %
  1063. % mtx_array: original /W or /W2 array
  1064. % item_size: number of metrics values per CID
  1065. %
  1066. % for detail of the metrics list format in PDF,
  1067. % refer PDF Ref. p.317 "Glyph Metrics in CIDFonts".
  1068. %
  1069. % format of single entry in internal expression
  1070. %
  1071. % [
  1072. % [cid_begin cid_end]
  1073. % value_is_varied (bool)
  1074. % [ [values for cid_begin...]
  1075. % [values for cid_begin + 1]
  1076. % ... ]
  1077. % ]
  1078. %
  1079. 7 dict
  1080. begin
  1081. /itemSize exch def
  1082. /M exch def % original /W or /W2
  1083. /Msize M length def
  1084. /Mi { M i get } def % W[i]
  1085. /Mi1 { M i 1 add get } def % W[i + 1]
  1086. /putMTXEntry <<
  1087. /arraytype {
  1088. [
  1089. [Mi Mi Mi1 length itemSize idiv add 1 sub]
  1090. true
  1091. [
  1092. 0 itemSize Mi1 length 1 sub {
  1093. [ exch 1 1 index itemSize add 1 sub { Mi1 exch get } for ]
  1094. } for
  1095. ]
  1096. ]
  1097. /i i 2 add def
  1098. }
  1099. /integertype {
  1100. [
  1101. [Mi Mi1]
  1102. false
  1103. [[ i 2 add 1 i 1 add itemSize add { M exch get } for ]]
  1104. ]
  1105. /i i 3 add def
  1106. }
  1107. >> def
  1108. /i 0 def
  1109. [ { putMTXEntry Mi1 type get exec i Msize ge { exit } if } loop ]
  1110. end
  1111. } def
  1112. /.pdfMakeInternalW { dup length 0 gt { 1 .pdfMakeInternalMTXArray } if } def
  1113. /.pdfMakeInternalW2 { dup length 0 gt { 3 .pdfMakeInternalMTXArray } if } def
  1114. /.pdfGetMTXByCID { % <internalMTXArray> <cid>
  1115. % .pdfGetMTXByCID
  1116. % { <MTXEntry> true | false }
  1117. % get values for given CID from internal format of /W or /W2
  1118. exch
  1119. {
  1120. {
  1121. dup 0 get {} forall % Stack: <cid> <entry> <cid_0> <cid_1>
  1122. 3 index lt { pop pop false exit } if
  1123. 2 index exch sub dup 0 lt { pop pop false exit } if
  1124. 1 index 1 get not { pop 0 } if
  1125. exch 2 get exch get true exit
  1126. } loop
  1127. { exit } if
  1128. } forall
  1129. dup type /arraytype eq { exch pop true } { pop false } ifelse
  1130. } def
  1131. % Apply the [D]W[2] metrics to a character before displaying.
  1132. /CIDWProc { % <w0x> <w0y> <llx> <lly> <urx> <ury>
  1133. % <w1x> <w1y> <vx> <vy> <cid> <font> CIDWproc
  1134. % <w0x'> ... <vy'>
  1135. begin % push <font> to currentdict
  1136. % <w1x> <w1y> <vx> <vy> won't be used and replaced, discard now
  1137. 5 1 roll pop pop pop pop
  1138. {
  1139. currentdict /DW .knownget not { % no DW
  1140. .pdfDefaultDW exit % replace <w0x> by defaultDW
  1141. } if
  1142. currentdict /.internalW .knownget not { % no W
  1143. exit % use already-stacked DW
  1144. } if
  1145. dup length 0 eq { % W is null array
  1146. pop % discard unusable W
  1147. exit % use already-stacked DW
  1148. } if
  1149. % W is finite array, try to get W_cid
  1150. 2 index .pdfGetMTXByCID { % got W, discard DW
  1151. exch pop {} forall
  1152. exit
  1153. } if
  1154. exit
  1155. } loop
  1156. FontType 11 eq {
  1157. 1000 div % <w0x'> (normalized W)
  1158. } if
  1159. 0 % <w0y'>
  1160. % Stack: <w0x> <w0y> <llx> <lly> <urx> <ury> <cid> <w0x'> <w0y'>
  1161. 9 -2 roll pop pop % discard <w0x> <w0y>
  1162. 7 2 roll % put <w0x'> <w0y'>
  1163. % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <cid>
  1164. 0 % <w1x'>
  1165. exch % put <w1x'>
  1166. % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> <cid>
  1167. {
  1168. currentdict /DW2 .knownget not { % no DW2, use defaultDW2
  1169. .pdfDefaultDW2 exit
  1170. } if
  1171. currentdict /.internalW2 .knownget not { % has DW2, no W2
  1172. exit % use already-stacked DW2
  1173. } if
  1174. dup length 0 eq { % W2 is null array
  1175. pop % discard unusable W2
  1176. exit % use already-stacked DW2
  1177. } if
  1178. 2 index .pdfGetMTXByCID { % got W2_cid, discard DW2
  1179. exch pop
  1180. exit
  1181. } if
  1182. % could not get W2_cid
  1183. exit
  1184. } loop
  1185. exch pop % discard <cid>
  1186. % Stack: <w0x'> <w0y'> <llx> <lly> <urx> <ury> <w1x'> { [<vy'> <w1y'>] | [<w1y'> <vx'> <vy'>] }
  1187. dup length 2 eq { % this is DW2
  1188. FontType 11 eq {{1000 div}} {{}} ifelse forall exch
  1189. 8 index 2 div % <vx'> = <w0x'> / 2
  1190. exch
  1191. }{ % assume W2
  1192. FontType 11 eq {{1000 div}} {{}} ifelse forall
  1193. } ifelse
  1194. end % recover currentdict
  1195. } def
  1196. % <string> <match> tailmatch ==> <pre> true
  1197. % ==> <string> false
  1198. /tailmatch {
  1199. 2 copy length 1 index length .min
  1200. dup 2 index length exch sub exch getinterval
  1201. 1 index eq {
  1202. length 1 index length exch sub
  1203. 0 exch getinterval true
  1204. } {
  1205. pop false
  1206. } ifelse
  1207. } bind def
  1208. /makeboldfont {
  1209. 16 dict begin
  1210. /strokewidth exch def
  1211. /basecidfont exch def
  1212. /FontMatrix [ 1 0 0 1 0 0 ] def
  1213. /CIDFontName /.boldfont def
  1214. /CIDFontType 1 def
  1215. /basefont-H /.basefont-H /Identity-H [ basecidfont ] composefont def
  1216. /basefont-V /.basefont-V /Identity-V [ basecidfont ] composefont def
  1217. /CIDSystemInfo dup basecidfont exch get def
  1218. /FontBBox [ basecidfont /FontBBox get cvx exec
  1219. 4 2 roll basecidfont /FontMatrix get transform
  1220. 4 2 roll basecidfont /FontMatrix get transform
  1221. ] def
  1222. /tmpstr 2 string def
  1223. /BuildGlyph {
  1224. gsave
  1225. exch begin
  1226. dup 256 idiv tmpstr exch 0 exch put
  1227. 256 mod tmpstr exch 1 exch put
  1228. rootfont /WMode known { rootfont /WMode get 1 eq } { false } ifelse
  1229. { basefont-V } { basefont-H } ifelse setfont
  1230. strokewidth setlinewidth
  1231. 1 setlinejoin
  1232. newpath
  1233. 0 0 moveto tmpstr false charpath stroke
  1234. 0 0 moveto tmpstr show
  1235. currentpoint setcharwidth
  1236. end
  1237. grestore
  1238. } bind def
  1239. currentdict
  1240. end
  1241. dup /CIDFontName get exch /CIDFont defineresource
  1242. } bind def
  1243. % <CIDFont-resource> <CIDFontName> findCIDFont <CIDFont-resource> <font>
  1244. % CIDFont-resource is not modified.
  1245. /findCIDFont {
  1246. {
  1247. dup /CIDFont resourcestatus {
  1248. pop pop /CIDFont findresource
  1249. exit
  1250. } if
  1251. .remove_font_name_prefix
  1252. dup dup length string cvs
  1253. (,Bold) tailmatch {
  1254. exch pop
  1255. cvn findCIDFont 0.03 makeboldfont
  1256. exit
  1257. } if
  1258. (,Italic) tailmatch {
  1259. exch pop
  1260. cvn findCIDFont
  1261. [ 1 0 0.3 1 0 0 ] makefont
  1262. exit
  1263. } if
  1264. (,BoldItalic) tailmatch {
  1265. exch pop
  1266. cvn findCIDFont 0.03 makeboldfont
  1267. [ 1 0 0.3 1 0 0 ] makefont
  1268. exit
  1269. } if
  1270. pop
  1271. 1 index /CIDSystemInfo get begin Registry (-) Ordering end
  1272. concatstrings concatstrings
  1273. cvn
  1274. QUIET not {
  1275. (Substituting CID font resource) print dup ==only
  1276. ( for ) print 1 index ==only (.\n) print
  1277. } if
  1278. exch pop
  1279. /CIDFont findresource
  1280. exit
  1281. } loop
  1282. } bdef
  1283. /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
  1284. dup /BaseFont get findCIDFont exch pop
  1285. } bdef
  1286. /buildCIDType2 { % <CIDFontType2-font-resource> buildCIDType2 <font>
  1287. dup /BaseFont get findCIDFont exch pop
  1288. } bdef
  1289. /processCIDToGIDMap { % <fontres> <cidfont> processCIDToGIDMap <fontres> <cidfont>
  1290. 1 index /CIDToGIDMap knownoget {
  1291. PDFfile fileposition 4 1 roll
  1292. dup /Identity eq {
  1293. pop
  1294. } {
  1295. true resolvestream
  1296. % Stack: filepos fontres font mapstream
  1297. % Can't know the length of the decompressed stream, so allocate a big buffer...
  1298. dup 65534 string readstring {
  1299. % Length exceeded max string size, use an array of two strings
  1300. 1 index 65534 string readstring pop % maybe a null string - not important.
  1301. 2 array astore
  1302. % Stack: filepos fontres font mapstream array
  1303. dup 1 get length 65534 add
  1304. } {
  1305. dup length
  1306. } ifelse
  1307. 2 idiv
  1308. % Stack: filepos fontres font mapstream array/string CIDCount
  1309. 3 index exch /CIDCount exch put
  1310. exch closefile exch
  1311. dup /CIDMap 4 -1 roll put
  1312. } ifelse
  1313. 3 2 roll PDFfile exch setfileposition
  1314. } if
  1315. } bdef
  1316. % Adjust a CIDFontType0 DW[2] in the font resource.
  1317. /adjustCIDType0 { % <font-resource> <font> adjustfont <font'>
  1318. addCIDmetrics
  1319. dup /CIDFontName get exch /CIDFont defineresource
  1320. } bind def
  1321. % Adjust a CIDFontType2 DW[2] and CIDToGIDMap in the font resource.
  1322. /adjustCIDType2 { % <font-resource> <font> adjustfont <font'>
  1323. addCIDmetrics
  1324. processCIDToGIDMap
  1325. dup /CIDFontName get exch /CIDFont defineresource
  1326. } bind def
  1327. % ---------------- Other embedded fonts ---------------- %
  1328. /fontloadprocs mark
  1329. /Type1C /readType1C cvx
  1330. /CIDFontType0C /readCIDFontType0C cvx
  1331. .dicttomark readonly def
  1332. % Read an embedded compressed font.
  1333. /readType1C { % <font-resource> <stream-dict> readType1C <font>
  1334. 1 index exch
  1335. PDFfile fileposition 3 1 roll
  1336. dup true resolvestream dup readfontfilter
  1337. % Stack: pos resource streamdict stream filter
  1338. 3 index /FontDescriptor oget /FontName oget
  1339. 1 index FRD
  1340. closefile closefile pop
  1341. PDFfile 3 -1 roll setfileposition
  1342. /FontDescriptor oget /FontName oget pdfaddcachedfont
  1343. exch pop
  1344. } bdef
  1345. % Read an embedded CFF CIDFont.
  1346. /readCIDFontType0C { % <font-resource> <stream-dict> readCIDFontType0C <font>
  1347. PDFfile fileposition 3 1 roll
  1348. dup true resolvestream dup readfontfilter
  1349. % Stack: pos resource streamdict stream filter
  1350. 3 index /FontDescriptor oget /FontName oget
  1351. 1 index FRD
  1352. closefile closefile pop
  1353. PDFfile 3 -1 roll setfileposition
  1354. % Some broken Adobe software produces PDF files in which
  1355. % the FontName of the CFF font and the FontName in the
  1356. % FontDescriptor don't match the BaseFont in the font.
  1357. % Use the FontName, rather than the BaseFont, here.
  1358. dup /FontDescriptor oget /FontName oget /CIDFont findresource
  1359. addCIDmetrics dup /CIDFontName get exch /CIDFont defineresource
  1360. } bdef
  1361. % ---------------- Font lookup ---------------- %
  1362. /fonttypeprocs mark % <font-resource> -proc- <font>
  1363. /Type0 //buildType0
  1364. /Type1 //buildType1
  1365. /MMType1 //buildType1
  1366. /Type3 //buildType3
  1367. /TrueType //buildTrueType
  1368. /CIDFontType0 //buildCIDType0
  1369. /CIDFontType2 //buildCIDType2
  1370. .dicttomark readonly def
  1371. /adjustfonttypes mark
  1372. /Type1 //adjustfont
  1373. /MMType1 //adjustfont
  1374. /TrueType //adjustfont
  1375. /CIDFontType0 //adjustCIDType0
  1376. /CIDFontType2 //adjustCIDType2
  1377. .dicttomark readonly def
  1378. /resourcefont % <font-resource> resourcefont <font>
  1379. { dup /PSFont .knownget
  1380. { /FID knownoget { type /fonttype eq } { //false } ifelse }
  1381. { //false }
  1382. ifelse
  1383. { /PSFont get }
  1384. { dup dup /FontDescriptor knownoget { % Stack: font-res font-res font-desc
  1385. dup /FontObject .knownget {
  1386. 3 1 roll pop pop
  1387. } {
  1388. dup /FontFile knownoget
  1389. { dup /Length oget 0 eq
  1390. { pop pop dup /Subtype get fonttypeprocs exch get exec }
  1391. { exch pop readtype1 }
  1392. ifelse
  1393. }
  1394. {
  1395. dup /FontFile2 knownoget
  1396. { exch pop readtruetype }
  1397. { /FontFile3 knownoget
  1398. { dup /Subtype get fontloadprocs exch get exec }
  1399. { dup /Subtype get fonttypeprocs exch get exec }
  1400. ifelse
  1401. }
  1402. ifelse
  1403. }
  1404. ifelse
  1405. 1 index /FontDescriptor oget
  1406. 1 index /FontObject exch put % Save pointer to the font
  1407. }
  1408. ifelse
  1409. }
  1410. { dup /Subtype get fonttypeprocs exch dup () cvn eq {
  1411. ( **** Warning: Font missing required Subtype, /Type1 assumed.\n)
  1412. pdfformaterror
  1413. pop /Type1
  1414. } if get exec
  1415. }
  1416. ifelse
  1417. % Stack: font-res font
  1418. 1 index 3 1 roll
  1419. 1 index /Subtype get
  1420. //adjustfonttypes exch .knownget { exec } { exch pop } ifelse
  1421. dup 3 1 roll /PSFont exch put
  1422. }
  1423. ifelse
  1424. dup checkGlyphNames2Unicode
  1425. } bdef
  1426. drawopdict begin
  1427. /d0 {
  1428. .adjustcharwidth setcharwidth
  1429. } bdef
  1430. /d1 {
  1431. 4 index 0 ne {
  1432. % invalid wy parameter for d1 in Type3 font (must be 0)
  1433. % Even though the PDF 1.4 specification states that this must be 0,
  1434. % Distiller sometimes creates Type3 fonts with non-zero wy. We set
  1435. % it to 0 since this is apparently what Acrobat Reader 4 and 5 do,
  1436. % but if the specification is ever changed to allow non-zero wy, this
  1437. % will not work.
  1438. 5 -1 roll pop 0 5 1 roll % set wy to 0
  1439. } if
  1440. 2 copy % ... llx lly urx ury | urx ury
  1441. 0 ne exch 0 ne % ... llx lly urx ury | ury!=0 urx!=0
  1442. 3 index 6 index eq and % ... llx lly urx ury | ury!=0 (urx!=0 && llx==urx)
  1443. exch 2 index 5 index eq and or { % ... llx lly urx ury | (urx!=0 && llx==urx) || (ury!=0 && lly==ury)
  1444. % The bounding box is empty and likely incorrect. Don't cache.
  1445. pop pop pop pop .adjustcharwidth setcharwidth
  1446. } {
  1447. 6 -2 roll .adjustcharwidth 6 2 roll setcachedevice
  1448. } ifelse
  1449. } bdef
  1450. /Tf {
  1451. 1 index Page /Font rget not { 1 index /invalidfont signalerror } if
  1452. resourcefont exch Tf pop
  1453. } bdef
  1454. end
  1455. end % pdfdict
  1456. end % GS_PDF_ProcSet
  1457. .setglobal