pdf_draw.ps 33 KB

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