Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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