1
0

pdf_draw.ps 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  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_draw.ps,v 1.98 2005/10/05 14:37:59 ray Exp $
  16. % pdf_draw.ps
  17. % PDF drawing operations (graphics, text, and images).
  18. /.setlanguagelevel where { pop 2 .setlanguagelevel } if
  19. .currentglobal true .setglobal
  20. /pdfdict where { pop } { /pdfdict 100 dict def } ifelse
  21. GS_PDF_ProcSet begin
  22. pdfdict begin
  23. % For simplicity, we use a single interpretation dictionary for all
  24. % PDF graphics operations, even though this is too liberal.
  25. /drawopdict 100 dict def
  26. % ================================ Graphics ================================ %
  27. % ---------------- Functions ---------------- %
  28. % Note that resolvefunction converts a PDF Function to a PostScript Function;
  29. % resolve*fnproc converts a PDF function to a PostScript procedure.
  30. % We need to process all required and optional parameters to resolve any
  31. % use of indirect references.
  32. /fnrdict mark
  33. 0 { .resolvefn0 }
  34. 2 { .resolvefn2 }
  35. 3 { .resolvefn3 }
  36. 4 { .resolvefn4 }
  37. .dicttomark readonly def
  38. /.resolvefn0 {
  39. dup length 1 add dict .copydict % make room for DataSource
  40. % now resolve any indirect references
  41. dup /Size 2 copy knownoget { put } { pop pop } ifelse
  42. dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse
  43. dup /Order 2 copy knownoget { put } { pop pop } ifelse
  44. dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  45. dup /Decode 2 copy knownoget { put } { pop pop } ifelse
  46. % Don't lose our place in PDFfile.
  47. PDFfile fileposition exch
  48. dup true resolvestream
  49. % The stream isn't positionable, so read all the data now.
  50. % Stack: filepos fndict stream
  51. 1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  52. 2 index /Size get { mul } forall
  53. 7 add 8 idiv string
  54. 1 index exch readstring pop exch closefile
  55. % Stack: filepos fndict data
  56. exch dup /DataSource 4 -1 roll put
  57. exch PDFfile exch setfileposition
  58. } bdef
  59. /.resolvefn2 {
  60. dup length dict .copydict
  61. dup /C0 2 copy knownoget { put } { pop pop } ifelse
  62. dup /C1 2 copy knownoget { put } { pop pop } ifelse
  63. dup /N 2 copy knownoget { put } { pop pop } ifelse
  64. } bdef
  65. /.resolvefn3 {
  66. dup length dict .copydict
  67. dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  68. dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  69. dup /Functions 2 copy oget mark exch dup {
  70. oforce .resolvefn
  71. } forall
  72. counttomark -1 roll astore exch pop put
  73. } bdef
  74. /.resolvefn4 {
  75. PDFfile fileposition exch % filepos fndict
  76. dup true resolvestream % filepos fndict stream
  77. exch dup length dict copy % filepos stream fndict2
  78. dup /Function undef % filepos stream fndict2
  79. exch dup token not {
  80. () /rangecheck cvx signalerror
  81. } if
  82. exch token {
  83. /rangecheck cvx signalerror
  84. } if
  85. % Use .bind to avoid idiom recognition.
  86. .bind
  87. 1 index /Function 3 -1 roll put
  88. exch PDFfile exch setfileposition
  89. } bdef
  90. /.resolvefn { % <fndict> .resolvefn <fndict'>
  91. dup length dict .copydict
  92. dup /Domain 2 copy knownoget { put } { pop pop } ifelse
  93. dup /Range 2 copy knownoget { put } { pop pop } ifelse
  94. dup /FunctionType oget //fnrdict exch get exec
  95. } bdef
  96. /resolvefunction { % <fndict> resolvefunction <function>
  97. .resolvefn
  98. PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Function: ) print dup === flush } if } if
  99. } bdef
  100. /resolvefnproc { % <fndict> resolvefnproc <proc>
  101. resolvefunction .buildfunction
  102. } bdef
  103. /resolveidfnproc { % <fndict> resolveidfnproc <proc>
  104. dup /Identity eq { pop { } } { resolvefnproc } ifelse
  105. } bdef
  106. /resolvedefaultfnproc { % <fndict> <default> resolved'fnproc <proc>
  107. 1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
  108. } bdef
  109. % ---------------- Shadings ---------------- %
  110. /shrdict mark
  111. /ColorSpace {
  112. resolvecolorspace
  113. }
  114. /Function {
  115. dup type /dicttype eq {
  116. resolvefunction
  117. } {
  118. [ exch { oforce resolvefunction } forall ]
  119. } ifelse
  120. }
  121. .dicttomark readonly def
  122. /resolveshading { % <shadingstream> resolveshading <shading>
  123. PDFfile fileposition exch
  124. mark exch {
  125. oforce //shrdict 2 index .knownget { exec } if
  126. } forall .dicttomark
  127. dup /ShadingType get 4 ge {
  128. dup dup true resolvestream
  129. % Make a reusable stream so that the shading doesn't
  130. % reposition PDFfile at unexpected times.
  131. /ReusableStreamDecode filter /DataSource exch put
  132. } if exch PDFfile exch setfileposition
  133. } bdef
  134. /resolvesh { % <shname> resolveshading <shading>
  135. Page /Shading rget {
  136. resolveshading
  137. } {
  138. null
  139. }ifelse
  140. } bdef
  141. % ---------------- Halftones ---------------- %
  142. /spotfunctions mark
  143. /Round {
  144. abs exch abs 2 copy add 1 le {
  145. dup mul exch dup mul add 1 exch sub
  146. } {
  147. 1 sub dup mul exch 1 sub dup mul add 1 sub
  148. } ifelse
  149. }
  150. /Diamond {
  151. abs exch abs 2 copy add .75 le {
  152. dup mul exch dup mul add 1 exch sub
  153. } {
  154. 2 copy add 1.23 le {
  155. .85 mul add 1 exch sub
  156. } {
  157. 1 sub dup mul exch 1 sub dup mul add 1 sub
  158. } ifelse
  159. } ifelse
  160. }
  161. /Ellipse {
  162. abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
  163. pop dup mul exch .75 div dup mul add 4 div 1 exch sub
  164. } {
  165. dup 1 gt {
  166. pop 1 exch sub dup mul exch 1 exch sub
  167. .75 div dup mul add 4 div 1 sub
  168. } {
  169. .5 exch sub exch pop exch pop
  170. } ifelse
  171. } ifelse
  172. }
  173. /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub }
  174. /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub }
  175. /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub }
  176. /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub }
  177. /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub }
  178. /Line { exch pop abs neg }
  179. /LineX { pop }
  180. /LineY { exch pop }
  181. /Square { abs exch abs 2 copy lt { exch } if pop neg }
  182. /Cross { abs exch abs 2 copy gt { exch } if pop neg }
  183. /Rhomboid { abs exch abs 0.9 mul add 2 div }
  184. /DoubleDot { 2 {360 mul sin 2 div exch } repeat add }
  185. /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg }
  186. /SimpleDot { dup mul exch dup mul add 1 exch sub }
  187. /InvertedSimpleDot { dup mul exch dup mul add 1 sub }
  188. /CosineDot { 180 mul cos exch 180 mul cos add 2 div }
  189. /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add }
  190. /InvertedDouble {
  191. exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  192. }
  193. .dicttomark readonly def
  194. /htrdict mark
  195. 1 { .resolveht1 }
  196. 5 { .resolveht5 }
  197. % We don't support types 6, 10, or 16 yet.
  198. .dicttomark readonly def
  199. /.resolveht1 {
  200. mark exch {
  201. oforce
  202. 1 index /SpotFunction eq {
  203. dup type /nametype eq
  204. { //spotfunctions exch get } { resolvefnproc }
  205. ifelse
  206. } {
  207. 1 index /TransferFunction eq {
  208. resolveidfnproc
  209. } if
  210. } ifelse
  211. } forall .dicttomark
  212. } bdef
  213. /.resolveht5 {
  214. mark exch {
  215. oforce dup type /dicttype eq { resolvehalftone } if
  216. } forall .dicttomark
  217. } bdef
  218. /resolvehalftone { % <dict> resolvehalftone <halftone>
  219. dup /HalftoneType get
  220. dup //htrdict exch .knownget {
  221. exch pop exec
  222. } {
  223. (\n\n **** Unsupported HalftoneType ) pdfformaterror
  224. =string cvs pdfformaterror (. ***\n\n) pdfformaterror
  225. /resolvehalftone cvx /unregistered signalerror
  226. } ifelse
  227. } bdef
  228. % ---------------- Graphics state management ---------------- %
  229. /cmmatrix matrix def
  230. drawopdict begin
  231. % Graphics state stack
  232. /q { q } def
  233. /Q { Q } def
  234. % Graphics state setting
  235. /cm { { //false upath } stopped {
  236. pop % discard 'false' (upath failed, probably no currentpoint).
  237. //cmmatrix astore concat
  238. } {
  239. % update the CTM, then uappend.
  240. 7 1 roll //cmmatrix astore concat
  241. newpath { mark exch uappend } stopped
  242. cleartomark
  243. } ifelse
  244. } def
  245. /i { 1 .min setflat } def
  246. /J /setlinecap load def
  247. /d /setdash load def
  248. /j /setlinejoin load def
  249. /w /setlinewidth load def
  250. /M { 1 .max setmiterlimit } bdef
  251. /gs { gs } def
  252. end
  253. % Each entry in this dictionary is
  254. % <gsres> <value> -proc- <gsres>
  255. /gsbg {
  256. /BGDefault load resolvedefaultfnproc setblackgeneration
  257. } bdef
  258. /gsucr {
  259. /UCRDefault load resolvedefaultfnproc setundercolorremoval
  260. } bdef
  261. /gstr {
  262. dup type /arraytype eq {
  263. { oforce /TRDefault load resolvedefaultfnproc } forall
  264. setcolortransfer
  265. } {
  266. /TRDefault load resolvedefaultfnproc settransfer
  267. } ifelse
  268. } bdef
  269. /gsparamdict mark
  270. /SA { setstrokeadjust }
  271. /OP { 1 index /op known not { dup op } if OP }
  272. % The PDF 1.3 specification says that the name /Default is only
  273. % recognized for {BG,UCR,TR}2. However, PDF 1.3 files produced
  274. % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
  275. % with the older keys, so we have to implement this.
  276. /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  277. /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  278. /TR { 1 index /TR2 known { pop } { gstr } ifelse }
  279. /HT {
  280. dup /Default eq {
  281. pop .setdefaulthalftone
  282. } {
  283. %****** DOESN'T IMPLEMENT THE STREAM CASE YET ******
  284. resolvehalftone sethalftone
  285. } ifelse
  286. % the transfer function may dependent on the halftone, so make sure
  287. % it is set if included in the graphic state (otherwise this is
  288. % subject to order of a dictionary forall, which is unpredictable)
  289. dup /TR2 .knownget {
  290. dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse
  291. } {
  292. dup /TR .knownget {
  293. /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse
  294. } if
  295. } ifelse
  296. }
  297. /HTP {
  298. % HTP may be present even if this isn't a DPS interpreter.
  299. /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  300. }
  301. % PDF 1.3
  302. /Font { aload pop Tf }
  303. /LW { setlinewidth }
  304. /LC { setlinecap }
  305. /LJ { setlinejoin }
  306. /ML { 1 .max setmiterlimit }
  307. /D { aload pop setdash }
  308. /RI { ri }
  309. /op { op }
  310. /OPM { OPM }
  311. /BG2 { gsbg }
  312. /UCR2 { gsucr }
  313. /TR2 { gstr }
  314. /FL { 1 .min setflat }
  315. /SM {
  316. % SM may be present even if this is only a Level 2 interpreter.
  317. /setsmoothness where { pop setsmoothness } { pop } ifelse
  318. }
  319. % PDF 1.4
  320. % All of these require the "transparency" feature in the interpreter.
  321. /ca { ca }
  322. /CA { CA }
  323. /SMask { gssmask }
  324. /AIS { AIS }
  325. /BM { BM }
  326. /TK { TK }
  327. .dicttomark readonly def
  328. /gs { % <gsres> gs -
  329. Page /ExtGState rget {
  330. % We keep the dictionary on the stack during the forall so that
  331. % keys that interact with each other have access to it.
  332. dup {
  333. oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
  334. } forall pop
  335. } if
  336. } bdef
  337. % ------ Transparency support ------ %
  338. /gssmask {
  339. dup /None eq PDFusingtransparency not or {
  340. pop null
  341. } {
  342. % Preprocess the SMask value into a parameter dictionary for
  343. % .begintransparencymaskgroup, with added /BBox and /Draw keys.
  344. mark exch % Stack: mark smaskdict
  345. dup /S oget /Subtype exch 3 2 roll
  346. % Stack: mark ... smaskdict
  347. dup /BC knownoget {
  348. dup /Background exch 4 2 roll
  349. gsave
  350. 1 index /G oget /Group oget /CS knownoget {
  351. csresolve dup setgcolorspace csput
  352. } if
  353. aload pop setcolor [ currentgray ]
  354. grestore
  355. /GrayBackground exch 3 2 roll
  356. } if
  357. dup /TR knownoget {
  358. resolveidfnproc /TransferFunction exch 3 2 roll
  359. } if
  360. dup /G oget dup /BBox oget /BBox exch 4 2 roll
  361. /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
  362. pop .dicttomark
  363. } ifelse SMask
  364. } bdef
  365. % This procedure is called to actually render the soft mask.
  366. /.execmaskgroup { % <masknum> <paramdict> <formdict> .execmaskgroup -
  367. % Save our place in PDFfile, and do a gsave to avoid resetting
  368. % the color space.
  369. currentcolorspace 4 1 roll
  370. PDFfile fileposition 4 1 roll
  371. % We have to select the group's color space so that the
  372. % background color will be interpreted correctly.
  373. dup /Group oget /CS knownoget { csresolve dup setgcolorspace csput } if
  374. exch dup /BBox get aload pop .begintransparencymaskgroup {
  375. dup /Resources knownoget { oforce } { 0 dict } ifelse
  376. exch false resolvestream
  377. .execgroup .endtransparencymask
  378. } stopped {
  379. .discardtransparencymask stop
  380. } if
  381. PDFfile exch setfileposition
  382. setcolorspace
  383. } bdef
  384. % Paint a Form+Group XObject, either for a transparency mask or for a Do.
  385. /.execgroup { % <resdict> <stream> .execgroup -
  386. gsave //nodict begin
  387. null SMask
  388. 1 .setopacityalpha 1 .setshapealpha
  389. 0 .inittransparencymask 1 .inittransparencymask
  390. /Compatible .setblendmode
  391. % Execute the body of the Form, similar to DoForm.
  392. pdfopdict .pdfruncontext
  393. end grestore
  394. } bdef
  395. /.beginformgroup { % groupdict bbox .beginformgroup -
  396. exch mark exch % bbox mark groupdict
  397. dup /CS knownoget { csresolve setgcolorspace } if
  398. dup /I knownoget { /Isolated exch 3 2 roll } if
  399. dup /K knownoget { /Knockout exch 3 2 roll } if
  400. pop .dicttomark
  401. % Stack: bbox paramdict
  402. exch aload pop
  403. .begintransparencygroup
  404. } bdef
  405. % .paintgroupform implements the Form PaintProc in the case where the
  406. % Form XObject dictionary includes a Group key. See .paintform below.
  407. /.paintgroupform { % <resdict> <stream> <formdict> .paintgroupform -
  408. dup /Group oget exch /BBox oget
  409. % Stack: resdict stream groupdict bbox
  410. .beginformgroup {
  411. .execgroup
  412. } stopped {
  413. .discardtransparencygroup stop
  414. } if .endtransparencygroup
  415. } bdef
  416. % Make an ImageType 103 (soft-masked) image.
  417. /makesoftmaskimage { % <datasource> <imagemask> <SMask> makesoftmaskimage
  418. % <datasource> <imagemask>, updates currentdict =
  419. % imagedict
  420. % See the ImageType 3 case of makemaskimage below.
  421. % SMask is a stream, another Image XObject.
  422. % Stack: datasource imagemask(false) smaskstreamdict
  423. PDFfile fileposition exch
  424. dup /Matte knownoget { /Matte exch def } if
  425. dup length dict makeimagedict pop
  426. % In order to prevent the two data sources from being
  427. % aliased, we need to make at least one a reusable stream.
  428. % We pick the mask, since it's smaller (in case we need to
  429. % read all its data now).
  430. % Stack: datasource imagemask(false) savedpos
  431. % maskdict is currentdict
  432. /DataSource DataSource mark
  433. /Intent 1
  434. /AsyncRead true
  435. .dicttomark .reusablestreamdecode def
  436. PDFfile exch setfileposition
  437. currentdict end currentdict end
  438. 5 dict begin
  439. /ImageType 103 def
  440. /DataDict exch def
  441. dup /InterleaveType 3 put
  442. DataDict /Matte knownoget {
  443. /Matte exch def
  444. } if
  445. AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  446. /ColorSpace DataDict /ColorSpace get def
  447. } bdef
  448. % ---------------- Color setting ---------------- %
  449. /01_1 [0 1] readonly def
  450. /01_3 [0 1 0 1 0 1] readonly def
  451. /01_4 [0 1 0 1 0 1 0 1] readonly def
  452. % The keys here are resolved (PostScript, not PDF) color space names.
  453. /csncompdict mark
  454. /DeviceGray { pop 1 }
  455. /DeviceRGB { pop 3 }
  456. /DeviceCMYK { pop 4 }
  457. /CIEBasedA { pop 1 }
  458. /CIEBasedABC { pop 3 }
  459. /ICCBased { 1 oget /N oget }
  460. /Separation { pop 1 }
  461. /DeviceN { 1 oget length }
  462. .dicttomark readonly def
  463. /csrdict mark
  464. /DeviceGray { }
  465. /DeviceRGB { }
  466. /DeviceCMYK { }
  467. /CalGray {
  468. 1 oget 6 dict begin
  469. dup /Gamma knownoget {
  470. /exp load 2 packedarray cvx /DecodeA exch def
  471. } if
  472. dup /BlackPoint knownoget { /BlackPoint exch def } if
  473. dup /WhitePoint knownoget {
  474. dup /WhitePoint exch def
  475. dup /MatrixA exch def
  476. /RangeLMN [ 3 2 roll { 0 exch } forall ] def
  477. } if
  478. /PDFColorSpace exch def [ /CIEBasedA currentdict end ]
  479. }
  480. /CalRGB {
  481. 1 oget 6 dict begin
  482. dup /Gamma knownoget {
  483. [ exch { /exp load 2 packedarray cvx } forall
  484. ] /DecodeABC exch def
  485. } if
  486. dup /Matrix knownoget { /MatrixABC exch def } if
  487. dup /BlackPoint knownoget { /BlackPoint exch def } if
  488. dup /WhitePoint knownoget { /WhitePoint exch def } if
  489. /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  490. }
  491. /CalCMYK {
  492. pop /DeviceCMYK % not defined by Adobe
  493. }
  494. /Lab {
  495. 1 oget 6 dict begin
  496. dup /Range knownoget not { [-100 100 -100 100] } if
  497. [0 100 null null null null] dup 2 4 -1 roll putinterval
  498. /RangeABC exch def
  499. /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind] def
  500. /MatrixABC [1 1 1 1 0 0 0 0 -1] def
  501. dup /BlackPoint knownoget { /BlackPoint exch def } if
  502. dup /WhitePoint knownoget { /WhitePoint exch def } {
  503. ( **** Warning: Lab colorspace is missing WhitePoint.\n)
  504. pdfformaterror
  505. /WhitePoint [0.9505 1 1.089] def
  506. } ifelse
  507. % scaling function g() for DecodeLMN construction
  508. { dup 6 29 div ge {dup dup mul mul} {4 29 div sub 108 841 div mul} ifelse }
  509. /DecodeLMN [
  510. % Store white point implicitly inside procedures.
  511. [ 3 index aload pop WhitePoint 0 get /mul .systemvar ] cvx bind
  512. [ 4 index aload pop WhitePoint 1 get /mul .systemvar ] cvx bind
  513. [ 5 index aload pop WhitePoint 2 get /mul .systemvar ] cvx bind
  514. ] def pop
  515. /PDFColorSpace exch def [ /CIEBasedABC currentdict end ]
  516. }
  517. /ICCBased {
  518. dup 1 get type /dicttype ne { % don't resolve more than once
  519. PDFfile fileposition exch
  520. dup dup 1 oget
  521. mark exch { oforce } forall .dicttomark
  522. dup dup true resolvestream
  523. /ReusableStreamDecode filter /DataSource exch put
  524. 1 exch put
  525. exch PDFfile exch setfileposition
  526. % Resolve alternate color space
  527. dup 1 get % Get colorspace dictionary
  528. dup /Alternate .knownget % Check for alternate color space
  529. { oforce resolvecolorspace /Alternate exch put } % resolve and replace
  530. { pop } % remove colorspace dictionary
  531. ifelse
  532. } if
  533. } bind
  534. /Separation {
  535. aload pop exch oforce resolvecolorspace
  536. % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01
  537. % can use /Identity name here instead of a function.
  538. exch oforce resolveidfnproc
  539. 4 array astore
  540. }
  541. /DeviceN {
  542. 0 4 getinterval % ignore attributes
  543. aload pop 3 -1 roll oforce % resolve names array
  544. [ exch { oforce } forall ] % resolve each of the names
  545. 3 -1 roll oforce resolvecolorspace
  546. 3 -1 roll oforce resolvefnproc
  547. 4 array astore
  548. }
  549. /Indexed {
  550. aload pop 3 -1 roll oforce resolvecolorspace
  551. % Stack: /Indexed hival lookup basespace
  552. % If the underlying space is a Lab space, we must scale
  553. % the output of the lookup table as part of DecodeABC.
  554. dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
  555. dup 1 get /DecodeLMN known {
  556. 1 get dup length dict copy
  557. begin /DecodeABC [ 0 2 4 {
  558. RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
  559. RangeABC 3 index get /add load
  560. DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
  561. } for ] def
  562. /RangeABC //01_3 def
  563. currentdict end /CIEBasedABC exch 2 array astore
  564. } if
  565. } if
  566. 3 1 roll
  567. oforce dup type /stringtype ne {
  568. % The color lookup table is a stream.
  569. % Get its contents. Don't lose our place in PDFfile.
  570. % Stack: /Indexed basespace hival lookup
  571. PDFfile fileposition 5 1 roll true resolvestream
  572. % Stack: filepos /Indexed basespace hival lookupstream
  573. 1 index 1 add
  574. % Stack: filepos /Indexed basespace hival lookupstream len
  575. 3 index
  576. dup dup type /arraytype eq { 0 get } if
  577. //csncompdict exch get exec mul
  578. string readstring pop
  579. % Stack: filepos /Indexed basespace hival table
  580. 5 -1 roll PDFfile exch setfileposition
  581. }
  582. if 4 array astore
  583. % Replace the PDFColorSpace with the Indexed space if needed.
  584. dup 1 get
  585. dup type /arraytype eq {
  586. dup length 2 ge {
  587. dup 1 get type /dicttype eq {
  588. dup 1 get /PDFColorSpace known {
  589. dup 1 get /PDFColorSpace 3 index put
  590. } if
  591. } if
  592. } if
  593. } if pop
  594. }
  595. /Pattern {
  596. dup type /nametype ne {
  597. dup length 1 gt {
  598. 1 oget resolvecolorspace
  599. /Pattern exch 2 array astore
  600. } if
  601. } if
  602. }
  603. .dicttomark readonly def
  604. /cssubst { % <csname> cssubst <cspace'> true
  605. % <csname> cssubst false
  606. dup resolvecolorspace
  607. dup 1 index ne { exch pop true } { pop pop false } ifelse
  608. } bdef
  609. /csnames mark
  610. /DeviceGray dup /DeviceRGB dup /DeviceCMYK dup /Pattern dup
  611. .dicttomark readonly def
  612. /csresolve { % <csresourcename> csresolve <cspace>
  613. dup type /nametype ne {
  614. (\n **** Warning: CS/cs (setcolorspace) operand not a name: ) pdfformaterror
  615. dup stderrfile dup 3 -1 roll write==only flushfile
  616. ( ****\n) pdfformaterror
  617. dup type /arraytype eq { % Adobe InDesign + PDF Library has array
  618. resolvecolorspace
  619. } if
  620. } {
  621. dup Page /ColorSpace rget {
  622. exch pop resolvecolorspace
  623. } {
  624. //csnames 1 index known not { /undefined cvx signalerror } if
  625. } ifelse
  626. } ifelse
  627. } bdef
  628. /resolvecolorspace { % <cspace> resolvecolorspace <cspace'>
  629. dup dup type /arraytype eq { 0 get } if
  630. //csrdict exch .knownget
  631. {
  632. exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
  633. } {
  634. dup type /nametype eq { csresolve } { csset exch pop } ifelse
  635. } ifelse
  636. } bdef
  637. /scresolve { % <c0> ... scresolve <multi>
  638. % We can't really make sc[n] and SC[N] work, because
  639. % the color space information isn't available at
  640. % conversion time; so we hack it by assuming that
  641. % all the operands on the stack are used, and that
  642. % if the top operand is a name, it's a Pattern resource.
  643. dup type /nametype eq
  644. { Page /Pattern rget { resolvepattern } { null } ifelse }
  645. if
  646. dup type /dicttype eq {
  647. % Check the PaintType, if any (shading patterns don't
  648. % have one).
  649. dup /PaintType knownoget { 2 eq } { false } ifelse
  650. } {
  651. .pdfcount 1 gt
  652. } ifelse
  653. } bdef
  654. /.pdfpaintproc { % <patdict> <resdict> .pdfpaintproc -
  655. PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Begin PaintProc) print dup === flush } if } if
  656. % For uncolored patterns, we have to unbind the current
  657. % color and color space before running the PaintProc.
  658. % There's no harm in doing this for colored patterns,
  659. % so for simplicity, we always do it.
  660. PDFfile fileposition 3 1 roll
  661. q
  662. null sc1 null SC1
  663. % save old value of pdfemptycount on opstack, set to new value
  664. pdfemptycount /pdfemptycount count 3 sub def 3 1 roll
  665. exch false resolvestream pdfopdict .pdfruncontext
  666. % restore pdfemptycount
  667. /pdfemptycount exch def
  668. Q
  669. PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%End PaintProc) print dup === flush } if } if
  670. PDFfile exch setfileposition
  671. } bdef
  672. /resolvepattern { % <patternstreamdict> resolvepattern <patterndict>
  673. % Don't do the resolvestream now: just capture the data
  674. % from the file if necessary.
  675. dup length dict copy
  676. dup /FilePosition .knownget {
  677. 1 index /File get dup fileposition 3 1 roll
  678. % Stack: dict savepos pos file
  679. dup 3 -1 roll setfileposition
  680. dup 3 index /Length oget
  681. dup 65535 le {
  682. string readstring pop
  683. } {
  684. () /SubFileDecode filter /ReusableStreamDecode filter
  685. } ifelse
  686. % Stack: dict savepos file string
  687. 3 1 roll exch setfileposition
  688. 1 index /File 3 -1 roll put
  689. dup /FilePosition undef
  690. } if
  691. dup /Shading knownoget {
  692. resolveshading 1 index /Shading 3 -1 roll put
  693. } if
  694. dup /PaintProc [
  695. % Bind the resource dictionary into the PaintProc.
  696. 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  697. /.pdfpaintproc cvx
  698. ] cvx put
  699. PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { true } ifelse { (%Pattern: ) print dup === flush } if } if
  700. } bdef
  701. drawopdict begin
  702. /g { /DeviceGray cssubst { cs sc1 } { g } ifelse } bdef
  703. /rg { /DeviceRGB cssubst { cs sc* } { rg } ifelse } bdef
  704. /k { k } bdef
  705. /cs { csresolve cs } bdef
  706. /sc { scresolve { sc* } { sc1 } ifelse } bdef
  707. /scn /sc load def
  708. /G { /DeviceGray cssubst { CS SC1 } { G } ifelse } bdef
  709. /RG { /DeviceRGB cssubst { CS SC* } { RG } ifelse } bdef
  710. /K { K } bdef
  711. /CS { csresolve CS } bdef
  712. /ri { ri } bdef
  713. /SC { scresolve { SC* } { SC1 } ifelse } bdef
  714. /SCN /SC load def
  715. end
  716. % ---------------- Paths ---------------- %
  717. drawopdict begin
  718. % Path construction
  719. /m /moveto load def
  720. /l /lineto load def
  721. /c /curveto load def
  722. /v { currentpoint 6 2 roll curveto } def
  723. /y { 2 copy curveto } def
  724. /re {
  725. 4 2 roll moveto exch dup 0 rlineto 0 3 -1 roll rlineto neg 0 rlineto
  726. closepath
  727. } def
  728. /h /closepath load def
  729. % Path painting and clipping
  730. /n { n } def
  731. /S { S } def
  732. /s { s } def
  733. /f { f } def
  734. /f* { f* } def
  735. /B { B } def
  736. /b { b } def
  737. /B* { B* } def
  738. /b* { b* } def
  739. /W { W } def
  740. /W* { W* } def
  741. /sh { setfillstate resolvesh shfill } def
  742. end
  743. % ---------------- XObjects ---------------- %
  744. /xobjectprocs mark % <dict> -proc- -
  745. /Image { DoImage }
  746. /Form { DoForm }
  747. /PS { DoPS }
  748. .dicttomark readonly def
  749. % Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
  750. % color space names.
  751. /defaultdecodedict mark
  752. /DeviceGray { pop //01_1 } bind
  753. /DeviceRGB { pop //01_3 } bind
  754. /DeviceCMYK { pop //01_4 } bind
  755. /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind
  756. /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
  757. /ICCBased {
  758. 1 oget dup /Range knownoget {
  759. exch pop
  760. }{
  761. /N get [ exch {0 1} repeat ] readonly
  762. } ifelse
  763. } bind
  764. /Separation { pop //01_1 } bind
  765. /DeviceN {
  766. 1 oget length [ exch {0 1} repeat ] readonly
  767. } bind
  768. /Indexed {
  769. pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  770. } bind
  771. .dicttomark readonly def
  772. /checkaltimage { % <resdict> checkaltimage <resdict[']>
  773. Printed {
  774. dup /Alternates knownoget {
  775. {
  776. dup /DefaultForPrinting knownoget {
  777. {
  778. /Image oget exch pop exit
  779. } {
  780. pop
  781. } ifelse
  782. } {
  783. pop
  784. } ifelse
  785. } forall
  786. } if
  787. } if
  788. } bdef
  789. /makeimagedict { % <resdict> <newdict> makeimagedict <imagemask>
  790. % On return, newdict' is currentdict
  791. begin
  792. /Width 2 copy oget def
  793. /Height 2 copy oget def
  794. % Handle missing BitsPerComponent later.
  795. /BitsPerComponent 2 copy knownoget { def } { pop } ifelse
  796. /Interpolate 2 copy knownoget { def } { pop } ifelse
  797. makeimagekeys
  798. } bdef
  799. /makeimagekeys { % <resdict> makeimagekeys <imagemask>
  800. % newdict is currentdict
  801. % Assumes Width, Height, BPC, Interpolate already copied.
  802. /ImageType 1 def
  803. /ImageMatrix Width 0 0
  804. % Handle 0-height images specially.
  805. Height dup 0 eq { pop 1 } if neg 0 1 index neg
  806. 6 array astore def
  807. dup /ImageMask knownoget dup { and } if {
  808. % Image mask
  809. % Decode is required for the PostScript image operators.
  810. % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
  811. /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
  812. % BitsPerComponent is optional for masks.
  813. /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
  814. true
  815. } {
  816. % Opaque image
  817. dup /ColorSpace oget resolvecolorspace /ColorSpace exch def
  818. % Decode is required for the PostScript image operators.
  819. /Decode 2 copy knownoget not {
  820. ColorSpace //defaultdecodedict
  821. ColorSpace dup type /arraytype eq { 0 get } if get exec
  822. } if def
  823. false
  824. } ifelse
  825. % Even though we're going to read data,
  826. % pass false to resolvestream so that
  827. % it doesn't try to use Length (which may not be present).
  828. exch false resolvestream /DataSource exch def
  829. } bdef
  830. /DoImage {
  831. checkaltimage dup length 6 add dict
  832. 1 index /SMask knownoget { 1 index exch /SMask exch put } if
  833. 1 index /Mask knownoget { 1 index exch /Mask exch put } if
  834. makeimagedict doimagesmask
  835. } bdef
  836. /makemaskimage { % <datasource> <imagemask> <Mask> makemaskimage
  837. % <datasource> <imagemask>, updates currentdict =
  838. % imagedict
  839. dup type /arraytype eq {
  840. /ImageType 4 def
  841. % Check that every element of the Mask is an integer.
  842. //false 1 index {
  843. type /integertype ne or
  844. } forall {
  845. (\n **** Warning: Some elements of Mask array are not integers.\n)
  846. pdfformaterror
  847. [ exch { 0.5 add cvi } forall ] % following AR4, 5, 6 implementation
  848. } if
  849. % Check elements of array are within 0::(2**BitsPerComponent)-1
  850. % This is a PostScript error, but AR ignores Mask in that case
  851. 2 BitsPerComponent exp cvi 1 sub //false 2 index {
  852. % stack: max_value result_bool value
  853. dup 0 lt exch 3 index gt or or
  854. } forall exch pop {
  855. (\n **** Warning: Some elements of Mask array are out of range.\n)
  856. pdfformaterror
  857. pop /ImageType 1 def % revert to non-masked image
  858. } {
  859. /MaskColor exch def
  860. } ifelse
  861. } {
  862. % Mask is a stream, another Image XObject.
  863. % Stack: datasource imagemask(false) maskstreamdict
  864. PDFfile fileposition exch
  865. dup length dict makeimagedict pop
  866. % In order to prevent the two data sources from being
  867. % aliased, we need to make at least one a reusable stream.
  868. % We pick the mask, since it's smaller (in case we need to
  869. % read all its data now).
  870. % Stack: datasource imagemask(false) savedpos
  871. % maskdict is currentdict
  872. /DataSource DataSource mark
  873. /Intent 1
  874. /AsyncRead true
  875. .dicttomark .reusablestreamdecode def
  876. PDFfile exch setfileposition
  877. currentdict end currentdict end
  878. 5 dict begin
  879. /ImageType 3 def
  880. /InterleaveType 3 def
  881. /DataDict exch def
  882. /MaskDict exch def
  883. /ColorSpace DataDict /ColorSpace get def
  884. } ifelse
  885. } bdef
  886. /doimagesmask { % <imagemask> doimagesmask -
  887. PDFusingtransparency { currentdict /SMask knownoget } { false } ifelse {
  888. .begintransparencymaskimage
  889. PDFfile fileposition exch
  890. gsave //nodict begin
  891. null /SoftMask gput
  892. 1 .setopacityalpha 1 .setshapealpha
  893. 0 .inittransparencymask 1 .inittransparencymask
  894. /Compatible .setblendmode
  895. DoImage
  896. end grestore
  897. PDFfile exch setfileposition
  898. 0 .endtransparencymask
  899. << /Subtype /Group /Isolated true >> 0 0 1 1 .begintransparencygroup
  900. doimage
  901. .endtransparencygroup
  902. } {
  903. doimage
  904. } ifelse
  905. } bdef
  906. /doimage { % <imagemask> doimage -
  907. % imagedict is currentdict, gets popped from dstack
  908. DataSource exch
  909. PDFusingtransparency {
  910. currentdict /SMask knownoget
  911. } {
  912. false
  913. } ifelse {
  914. makesoftmaskimage
  915. } {
  916. currentdict /Mask knownoget {
  917. makemaskimage
  918. } if
  919. } ifelse
  920. % Stack: datasource imagemask
  921. % image and imagemask can be redefined in gs_init.ps to tweak interpolation
  922. % after device-specific files are run. Don't bind them here.
  923. { currentdict end setfillstate /imagemask }
  924. { ColorSpace setgcolorspace currentdict end setfillblend /image }
  925. ifelse
  926. .systemvar stopped {
  927. pop
  928. $error /errorname get dup /ioerror eq {
  929. pop (\n **** Warning: File has insufficient data for an image.\n)
  930. pdfformaterror
  931. } {
  932. (\n **** Warning: File encountered ')
  933. exch 40 string cvs concatstrings
  934. (' error while processing an image.\n) concatstrings
  935. pdfformaterror
  936. } ifelse
  937. } if
  938. % Close the input stream, unless it is PDFfile or
  939. % PDFsource.
  940. dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
  941. } bdef
  942. /.paintform { % <formdict> <resdict> <stream> .paintform -
  943. 3 -1 roll dup /Group known PDFusingtransparency and {
  944. .paintgroupform
  945. } {
  946. pop pdfopdict .pdfruncontext
  947. } ifelse
  948. } bdef
  949. /DoForm {
  950. % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
  951. % and /Matrix keys optional. Cope with the missing keys.
  952. begin <<
  953. currentdict /FormType known not { /FormType 1 } if
  954. currentdict /Matrix known not { /Matrix { 1 0 0 1 0 0 } cvlit } if
  955. currentdict end { oforce } forall
  956. >>
  957. dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  958. 3 index false /resolvestream cvx
  959. /.paintform cvx
  960. ] cvx /PaintProc exch put
  961. % Adjust pdfemptycount since we have an extra dictionary on the stack
  962. pdfemptycount exch
  963. /pdfemptycount where pop count 2 sub /pdfemptycount exch put
  964. q execform Q % gsave / grestore around the Form
  965. % Restore pdfemptycount
  966. /pdfemptycount where pop exch /pdfemptycount exch put
  967. } bdef
  968. /_dops_save 1 array def
  969. /DoPS {
  970. DOPS
  971. {
  972. //_dops_save 0 save put
  973. true resolvestream cvx exec
  974. //_dops_save 0 get restore
  975. }
  976. { pop }
  977. ifelse
  978. } bdef
  979. currentdict /_dops_save undef
  980. drawopdict begin
  981. /Do {
  982. setfillblend
  983. PDFfile fileposition exch
  984. dup Page /XObject rget {
  985. exch pop dup /Subtype get xobjectprocs exch get
  986. % Don't leave extra objects on the stack while executing
  987. % the definition of the form.
  988. 3 -1 roll 2 .execn
  989. } {
  990. % This should cause an error, but Acrobat Reader can
  991. % continue, so we do too.
  992. ( **** Undefined XObject resource: )
  993. exch =string cvs concatstrings (\n) concatstrings
  994. pdfformaterror
  995. } ifelse
  996. PDFfile exch setfileposition
  997. } bdef
  998. end
  999. % ---------------- In-line images ---------------- %
  1000. % Undo the abbreviations in an in-line image dictionary.
  1001. % Note that we must look inside array values.
  1002. % /I is context-dependent.
  1003. /unabbrevkeydict mark
  1004. /BPC /BitsPerComponent /CS /ColorSpace /D /Decode /DP /DecodeParms
  1005. /F /Filter /H /Height /I /Interpolate /IM /ImageMask /W /Width
  1006. .dicttomark readonly def
  1007. /unabbrevvaluedict mark
  1008. /AHx /ASCIIHexDecode /A85 /ASCII85Decode /CC /CalCMYK
  1009. /CCF /CCITTFaxDecode /CG /CalGray /CR /CalRGB
  1010. /DCT /DCTDecode /CMYK /DeviceCMYK /Fl /FlateDecode
  1011. /G /DeviceGray /RGB /DeviceRGB
  1012. /I /Indexed /LZW /LZWDecode /RL /RunLengthDecode
  1013. .dicttomark readonly def
  1014. /unabbrevtypedict mark
  1015. /nametype {
  1016. //unabbrevvaluedict 1 index .knownget { exch pop } if
  1017. }
  1018. /arraytype {
  1019. dup 0 1 2 index length 1 sub {
  1020. 2 copy get unabbrevvalue put dup
  1021. } for pop
  1022. }
  1023. .dicttomark readonly def
  1024. /unabbrevvalue { % <obj> unabbrevvalue <obj'>
  1025. oforce //unabbrevtypedict 1 index type .knownget { exec } if
  1026. } bdef
  1027. drawopdict begin
  1028. /BI { mark } bdef
  1029. /ID {
  1030. counttomark 2 idiv dup 7 add dict begin {
  1031. exch //unabbrevkeydict 1 index .knownget { exch pop } if
  1032. exch unabbrevvalue def
  1033. } repeat pop
  1034. /IDFlag true def % flag for stream processing.
  1035. /File PDFsource def
  1036. currentdict makeimagekeys doimage
  1037. % The Adobe documentation says that the data following ID
  1038. % consists of "lines", and some PDF files (specifically, some files
  1039. % produced by PCL2PDF from Visual Software) contain garbage bytes
  1040. % between the last byte of valid data and an EOL.
  1041. % Some files (PDFOUT v3.8d by GenText) have EI immediately following
  1042. % the stream. Some have no EOL and garbage bytes.
  1043. % Therefore, we skip all bytes before EI or EOL
  1044. 0
  1045. { PDFsource read not { //true exit } if
  1046. dup 10 eq 1 index 13 eq or
  1047. { pop PDFsource token pop /EI ne exit
  1048. }
  1049. if
  1050. exch 69 eq 1 index 73 eq and { //false exit } if % 'EI'
  1051. }
  1052. loop
  1053. exch pop
  1054. { /ID cvx /syntaxerror signalerror
  1055. }
  1056. if
  1057. } bdef
  1058. end
  1059. % ================================ Text ================================ %
  1060. drawopdict begin
  1061. % Text control
  1062. /BT { BT } def
  1063. /ET { ET } def
  1064. /Tc { Tc } def
  1065. /TL { TL } def
  1066. /Tr { Tr } def
  1067. /Ts { Ts } def
  1068. /Tw { Tw } def
  1069. /Tz { Tz } def
  1070. % Text positioning
  1071. /Td { Td } def
  1072. /TD { TD } def
  1073. /Tm { Tm } def
  1074. /T* { T* } def
  1075. % Text painting
  1076. /Tj { Tj } def
  1077. /' { ' } def
  1078. /" { " } def
  1079. /TJ { TJ } def
  1080. end
  1081. % ============================== Annotations ============================== %
  1082. % Get and normalize an annotation's rectangle.
  1083. /annotrect { % <annot> annotrect <x> <y> <w> <h>
  1084. /Rect get aload pop
  1085. exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  1086. exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
  1087. } bdef
  1088. % Set an annotation color.
  1089. /annotsetcolor { % <annot> annotsetcolor -
  1090. /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
  1091. } bdef
  1092. % Draw the border. Currently, we ignore requests for beveling, and we
  1093. % don't round the corners of rectangles.
  1094. /strokeborder { % <annot> <width> <dash> strokeborder -
  1095. 1 index 0 ne { % do not draw if border width is 0
  1096. gsave
  1097. 2 index annotsetcolor
  1098. 0 setdash dup setlinewidth
  1099. exch annotrect
  1100. 2 { 4 index sub 4 1 roll } repeat
  1101. 2 { 4 index 0.5 mul add 4 1 roll } repeat
  1102. rectstroke pop
  1103. grestore
  1104. } {
  1105. pop pop pop
  1106. } ifelse
  1107. } bdef
  1108. % Draw an annotation border.
  1109. /drawborder { % <annot> drawborder -
  1110. gsave
  1111. dup /BS knownoget {
  1112. dup /W knownoget not { 1 } if
  1113. [] 2 index /S knownoget {
  1114. /D eq { 2 index /D knownoget not { [3] } if exch pop } if
  1115. } if 3 -1 roll pop strokeborder
  1116. } {
  1117. dup /Border knownoget {
  1118. dup 2 get
  1119. exch dup length 3 gt { 3 get } { pop [] } ifelse
  1120. strokeborder
  1121. } {
  1122. 1 [] strokeborder
  1123. } ifelse
  1124. } ifelse
  1125. grestore
  1126. } bdef
  1127. %
  1128. % The PDF annotation F (flags) integer is bit encoded.
  1129. % Bit 1 (LSB) Invisible: 1 --> Do not display if no handler.
  1130. % Note: We have no handlers but we ignore this bit.
  1131. % Bit 2 Hidden: 1 --> Do not display. We will not display if this bit is set.
  1132. % Bit 3 Print: 1 --> Display if printing. We will display if this bit set
  1133. % (and not hidden) and Printed is true
  1134. % Bit 4 NoZoom: 1 --> Do not zoom annotation even if image is zoomed.
  1135. % Bit 5 NoRotate: 1 --> Do not rotate annotation even if image is rotated.
  1136. % Bit 6 NoView: 0 --> Display if this is a 'viewer'. We will display
  1137. % if this bit is not set (and not hidden) and Printed is false
  1138. % Bit 7 Read Only - 1 --> No interaction. We ignore this bit
  1139. %
  1140. /annotvisible { % <annot> annotvisible <visible>
  1141. /F knownoget not { 0 } if % Get flag value
  1142. dup 2 and 0 eq % Check hidden flag
  1143. exch dup 4 and 0 ne Printed and % Check print flag
  1144. exch 32 and 0 eq Printed not and % Check noview flag
  1145. or % Combine print and view
  1146. and % Combine with 'hidden' flag test
  1147. } bdef
  1148. /drawwidget { % <scalefactor> <annot> drawwidget -
  1149. dup /AP knownoget {
  1150. false
  1151. [/N /R /D] {
  1152. % stack: scale annot appearance false key
  1153. dup 3 index exch known {
  1154. exch pop true exit
  1155. } if
  1156. pop
  1157. } forall
  1158. % stack: scale annot appearance key true
  1159. % stack: scale annot appearance false
  1160. dup {
  1161. pop
  1162. oget
  1163. % Acrobat Distiller produces files in which this Form
  1164. % XObject lacks Type and Subtype keys. This is illegal,
  1165. % but Acrobat Reader accepts it. The only way we can
  1166. % tell whether this is a Form or a set of sub-appearances
  1167. % is by testing for the stream Length key.
  1168. dup /Length known {
  1169. % If this is a form then simply use it
  1170. true
  1171. } {
  1172. 1 index /AS knownoget not {
  1173. % If we do not have AS then use any appearance
  1174. { exch pop oforce exit } forall true
  1175. } {
  1176. % Stack: annot Ndict AS
  1177. % Get the specified appearance. If no appearance, then
  1178. % display nothing - set stack = false.
  1179. knownoget
  1180. } ifelse
  1181. } ifelse
  1182. } {
  1183. exch pop % discard useless AP dictionary
  1184. } ifelse
  1185. % Stack: scale annot appearance true
  1186. % Stack: scale annot false
  1187. {
  1188. % Draw appearance
  1189. % Initialize graphic following "7.4.4 Appearance Streams"
  1190. q graphicsbeginpage textbeginpage
  1191. 1 index annotrect pop pop translate
  1192. 2 index dup scale % Apply scale factor
  1193. DoForm Q
  1194. } if
  1195. } if pop pop
  1196. } bdef
  1197. % For stamp object we have to determine the size of the output rectangle
  1198. % and the size of the BBox for the stamp image. From these we calculate
  1199. % a scale factor for drawing the stamp.
  1200. /calcstampscale { % <annot> calcstampscale scale
  1201. dup /Rect known {
  1202. dup annotrect 4 -2 roll pop pop % get width height size in user space
  1203. 3 -1 roll /AP knownoget {
  1204. /N knownoget {
  1205. dup /Matrix knownoget {
  1206. % transform /Annot /Rect xwidth to Form space
  1207. 4 -2 roll 3 -1 roll dtransform 3 -1 roll
  1208. } if
  1209. /BBox knownoget {
  1210. exch pop % discard y height
  1211. aload pop pop exch pop sub % BBox width
  1212. dup 0 eq {
  1213. ( **** Warning: /BBox has zero width which is not allowed.\n)
  1214. pdfformaterror
  1215. pop pop 1 1 % 0 width -- revert to unity scaling
  1216. } if
  1217. div % scale x widths
  1218. dup 0 lt { neg } if % get magnitude
  1219. } {
  1220. pop pop 1 % default to unity scaling
  1221. } ifelse % if we have /BBox
  1222. } {
  1223. pop pop 1
  1224. } ifelse % if we have /N
  1225. } {
  1226. pop pop 1
  1227. } ifelse % if we have /AP
  1228. } {
  1229. ( **** Warning: /Annot dict is missing required /Rect entry.\n)
  1230. pdfformaterror
  1231. pop 1
  1232. } ifelse
  1233. } bdef
  1234. /drawlink { % <annot> drawlink -
  1235. dup drawborder dup calcstampscale exch drawwidget
  1236. } bdef
  1237. % Draw an annotation.
  1238. /drawannottypes mark
  1239. /Link { drawlink } bind
  1240. .dicttomark readonly def
  1241. /drawannot { % <annot> drawannot -
  1242. dup annotvisible {
  1243. gsave
  1244. dup dup /Subtype get //drawannottypes exch .knownget {
  1245. exec
  1246. } {
  1247. dup calcstampscale exch drawwidget % Use drawwidget for everything else
  1248. } ifelse % type known
  1249. grestore
  1250. } if pop % annotvisible
  1251. } bdef
  1252. currentdict /drawannottypes undef
  1253. end % pdfdict
  1254. end % GS_PDF_ProcSet
  1255. .setglobal