~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to Resource/Init/gs_setpd.ps

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: gs_setpd.ps 9350 2009-01-13 18:38:37Z ray $
 
17
% The current implementation of setpagedevice has the following limitations:
 
18
%       - It doesn't attempt to "interact with the user" for Policy = 2.
 
19
 
 
20
languagelevel 1 .setlanguagelevel
 
21
level2dict begin
 
22
 
 
23
% ---------------- Redefinitions ---------------- %
 
24
 
 
25
% Redefine .beginpage and .endpage so that they call BeginPage and
 
26
% EndPage respectively if appropriate.
 
27
 
 
28
% We have to guard against the BeginPage procedure not popping its operand.
 
29
% This is really stupid, but the Genoa CET does it.
 
30
/.beginpage {           % - .beginpage -
 
31
  .currentshowpagecount {
 
32
    .currentpagedevice pop
 
33
    dup //null ne { /BeginPage .knownget } { pop //false } ifelse {
 
34
                % Stack: ... pagecount proc
 
35
       count 2 .execn
 
36
                % Stack: ... ..???.. oldcount
 
37
       count 1 add exch sub { pop } repeat
 
38
    } {
 
39
      pop
 
40
    } ifelse
 
41
  } if
 
42
} bind odef
 
43
 
 
44
% Guard similarly against EndPage not popping its operand.
 
45
/.endpage {             % <reason> .endpage <print_bool>
 
46
  .currentshowpagecount {
 
47
    1 index .currentpagedevice pop
 
48
    dup //null ne { /EndPage .knownget } { pop //false } ifelse {
 
49
                % Stack: ... reason pagecount reason proc
 
50
      count 2 .execn
 
51
                % Stack: ... ..???.. print oldcount
 
52
      count 2 add exch sub { exch pop } repeat
 
53
    } {
 
54
      pop pop 2 ne
 
55
    } ifelse
 
56
  } {
 
57
    2 ne
 
58
  } ifelse
 
59
} bind odef
 
60
 
 
61
% Define interpreter callouts for handling gstate-saving operators,
 
62
% to make sure that they create a page device dictionary for use by
 
63
% the corresponding gstate-restoring operator.
 
64
% We'd really like to avoid the cost of doing this, but we don't see how.
 
65
% The names %gsavepagedevice, %savepagedevice, %gstatepagedevice,
 
66
% %copygstatepagedevice, and %currentgstatepagedevice are known to the
 
67
% interpreter.
 
68
 
 
69
(%gsavepagedevice) cvn
 
70
 { currentpagedevice pop gsave
 
71
 } bind def
 
72
 
 
73
(%savepagedevice) cvn
 
74
 { currentpagedevice pop save
 
75
 } bind def
 
76
 
 
77
(%gstatepagedevice) cvn
 
78
 { currentpagedevice pop gstate
 
79
 } bind def
 
80
 
 
81
(%copygstatepagedevice) cvn
 
82
 { currentpagedevice pop copy
 
83
 } bind def
 
84
 
 
85
(%currentgstatepagedevice) cvn
 
86
 { currentpagedevice pop currentgstate
 
87
 } bind def
 
88
 
 
89
% Define interpreter callouts for handling gstate-restoring operators
 
90
% when the current page device needs to be changed.
 
91
% The names %grestorepagedevice, %grestoreallpagedevice,
 
92
% %restorepagedevice, %restore1pagedevice, and %setgstatepagedevice
 
93
% are known to the interpreter.
 
94
 
 
95
/.installpagedevice
 
96
 {      % Since setpagedevice doesn't create new device objects,
 
97
        % we must (carefully) reinstall the old parameters in
 
98
        % the same device.
 
99
   .currentpagedevice pop //null currentdevice //null .trysetparams
 
100
   dup type /booleantype eq
 
101
    { pop pop }
 
102
    {           % This should never happen!
 
103
      SETPDDEBUG { (Error in .trysetparams!) = pstack flush } if
 
104
      cleartomark pop pop pop
 
105
      /.installpagedevice cvx /rangecheck signalerror
 
106
    }
 
107
   ifelse pop pop
 
108
        % A careful reading of the Red Book reveals that an erasepage
 
109
        % should occur, but *not* an initgraphics.
 
110
   erasepage .beginpage
 
111
 } bind def
 
112
 
 
113
/.uninstallpagedevice
 
114
 { 2 .endpage { .currentnumcopies //false .outputpage } if
 
115
   nulldevice
 
116
 } bind def
 
117
 
 
118
(%grestorepagedevice) cvn
 
119
 { .uninstallpagedevice grestore .installpagedevice
 
120
 } bind def
 
121
 
 
122
(%grestoreallpagedevice) cvn
 
123
 { .uninstallpagedevice grestore .installpagedevice grestoreall
 
124
 } bind def
 
125
 
 
126
(%restore1pagedevice) cvn
 
127
 { .uninstallpagedevice grestore .installpagedevice restore
 
128
 } bind def
 
129
 
 
130
(%restorepagedevice) cvn
 
131
 { .uninstallpagedevice restore .installpagedevice
 
132
 } bind def
 
133
 
 
134
(%setgstatepagedevice) cvn
 
135
 { .uninstallpagedevice setgstate .installpagedevice
 
136
 } bind def
 
137
 
 
138
% Redefine .currentnumcopies so it consults the NumCopies device parameter.
 
139
/.numcopiesdict mark
 
140
  /NumCopies dup
 
141
.dicttomark readonly def
 
142
 
 
143
/.currentnumcopies
 
144
 { currentdevice //.numcopiesdict .getdeviceparams
 
145
   dup type /integertype eq
 
146
    { exch pop exch pop }
 
147
    { cleartomark #copies }
 
148
   ifelse
 
149
 } bind odef
 
150
 
 
151
% Redefine .currentpagedevice and .setpagedevice so they convert between
 
152
% null and a fixed empty directionary.
 
153
/.nullpagedevice 0 dict readonly def
 
154
/.currentpagedevice {
 
155
  //.currentpagedevice exch dup //null eq { pop //.nullpagedevice } if exch
 
156
} bind odef
 
157
/.setpagedevice {
 
158
  dup //.nullpagedevice eq { pop //null } if //.setpagedevice
 
159
} bind odef
 
160
 
 
161
% ---------------- Auxiliary definitions ---------------- %
 
162
 
 
163
% Define the required attributes of all page devices, and their default values.
 
164
% We don't include attributes such as .MediaSize, which all devices
 
165
% are guaranteed to supply on their own.
 
166
/.defaultpolicies mark
 
167
  % M. Sweet, Easy Software Products
 
168
  %
 
169
  % Due to the fact that it is not possible to properly implement
 
170
  % the selection policies from a Ghostscript driver, we have changed
 
171
  % the default policy to "7" (impose) to avoid numerous problems with
 
172
  % printing within CUPS...
 
173
  %
 
174
  NOMEDIAATTRS {
 
175
    /PolicyNotFound 7
 
176
    /PageSize 7
 
177
  } {
 
178
    /PolicyNotFound 1
 
179
    /PageSize 0
 
180
  } ifelse
 
181
  /PolicyReport {
 
182
    dup /.LockSafetyParams known {
 
183
        % Only possible error is invalidaccess
 
184
      /setpagedevice .systemvar /invalidaccess signalerror
 
185
    }
 
186
    if
 
187
    pop
 
188
  } bind
 
189
.dicttomark readonly def
 
190
% Note that the values of .requiredattrs are executed, not just fetched.
 
191
/.requiredattrs mark
 
192
  /PageDeviceName //null
 
193
  /PageOffset [0 0] readonly
 
194
% We populate InputAttributes with all of the known page sizes 
 
195
% followed by a dummy media type that handles pages of any size.
 
196
% This will create some duplicates, but that only slightly slows
 
197
% down the media selection (loop is in zmedia2.c).
 
198
%
 
199
% Some PostScript creators assume that slot 0 is the default media
 
200
% size and some can't handle a non-standard 4-element array which
 
201
% is a 'range' type page size (always put last).
 
202
%
 
203
% Real Devices that can only handle specific page sizes will override this.
 
204
  /InputAttributes {
 
205
    mark
 
206
    % First put the device's default page size in slot 0
 
207
    % This satifies those that have devices built with a4 as the default
 
208
    0 mark /PageSize currentdevice /PageSize gsgetdeviceprop .dicttomark
 
209
    statusdict /.pagetypenames get {
 
210
      counttomark 1 sub 2 idiv exch mark exch /PageSize exch
 
211
      % stack: mark --dict-- --dict-- ... key mark /PageSize pagetypename
 
212
      % see note above about pagetype executable array contents.
 
213
      load dup 0 get exch 1 get 2 array astore .dicttomark
 
214
    } forall
 
215
    % If NORANGEPAGESIZE is defined, (-dNORANGEPAGESIZE), then don't add
 
216
    % the 'match any' PageSize entry
 
217
    systemdict /NORANGEPAGESIZE known not {
 
218
      % Add one last entry which is the 4 element range array (non-standard)
 
219
      counttomark 2 idiv 
 
220
        % PageSize with either dimension 0 will be detected in
 
221
        % match_page_size, so we can allow it here
 
222
      mark /PageSize [0 dup 16#7ffff dup] .dicttomark
 
223
    } if
 
224
    .dicttomark
 
225
  }
 
226
  (%MediaSource) 0
 
227
  /OutputAttributes {
 
228
    mark 0 mark .dicttomark readonly .dicttomark
 
229
  }
 
230
  (%MediaDestination) 0
 
231
  /Install {{.callinstall}} bind
 
232
  /BeginPage {{.callbeginpage}} bind
 
233
  /EndPage {{.callendpage}} bind
 
234
  /Policies .defaultpolicies
 
235
  /ImagingBBox //null           % default value
 
236
  /UseCIEColor /.getuseciecolor load
 
237
.dicttomark readonly def
 
238
 
 
239
% Define currentpagedevice so it creates the dictionary on demand if needed,
 
240
% adding all the required entries defined just above.
 
241
% We have to deal specially with entries that the driver may change
 
242
% on its own.
 
243
/.dynamicppkeys mark
 
244
  /.MediaSize dup               % because it changes when PageSize is set
 
245
%  /LeadingEdge dup
 
246
  /PageCount dup
 
247
  /Colors dup
 
248
  /BitsPerPixel dup
 
249
  /ColorValues dup
 
250
.dicttomark readonly def
 
251
/.makecurrentpagedevice {       % - .makecurrentpagedevice <dict>
 
252
  currentdevice //null .getdeviceparams
 
253
        % Make the dictionary large enough to add defaulted entries.
 
254
  counttomark 2 idiv .requiredattrs length add dict
 
255
  counttomark 2 idiv { dup 4 2 roll put } repeat exch pop
 
256
        % Add any missing required attributes.
 
257
        % Make a writable and (if possible) local copy of any default
 
258
        % dictionaries, to work around a bug in the output of WordPerfect,
 
259
        % which assumes that these dictionaries are writable and local.
 
260
  .currentglobal exch dup gcheck .setglobal
 
261
  .requiredattrs {
 
262
    2 index 2 index known {
 
263
      1 index /Policies eq {
 
264
        % Merge policies from the device driver with defaults
 
265
        2 index             % <<>> /key value <<>>
 
266
        3 2 roll get        % <<>> value <<policies>>
 
267
        exch {                
 
268
          2 index 2 index known { 
 
269
            pop pop
 
270
          } { 
 
271
            2 index 3 1 roll put
 
272
          } ifelse
 
273
        } forall
 
274
        pop
 
275
      } {
 
276
        pop pop
 
277
      } ifelse
 
278
    } {
 
279
      exec 2 index 3 1 roll put
 
280
    } ifelse
 
281
  } forall exch .setglobal
 
282
  dup .setpagedevice
 
283
} bind def
 
284
/currentpagedevice {
 
285
  .currentpagedevice {
 
286
    dup length 0 eq {
 
287
      pop .makecurrentpagedevice
 
288
    } {
 
289
                % If any of the dynamic keys have changed,
 
290
                % we must update the page device dictionary.
 
291
      currentdevice //.dynamicppkeys .getdeviceparams .dicttomark {
 
292
                % Stack: current key value
 
293
            2 index 2 index .knownget { 1 index ne } { //true } ifelse
 
294
             { 2 index wcheck not
 
295
                {       % This is the first entry being updated.
 
296
                        % Copy the dictionary to make it writable.
 
297
                  3 -1 roll
 
298
                  currentglobal 1 index dup gcheck currentglobal and setglobal
 
299
                  length dict
 
300
                  exch setglobal
 
301
                  .copydict
 
302
                  3 1 roll
 
303
                }
 
304
               if
 
305
               2 index 3 1 roll put
 
306
             }
 
307
             { pop pop
 
308
             }
 
309
            ifelse
 
310
      } forall
 
311
      % If the device is the distiller device, update distillerparams that
 
312
      % may have been changed by setdistillerparams
 
313
      currentdevice .devicename /pdfwrite eq {
 
314
        currentdistillerparams {
 
315
              % Stack: current key value
 
316
          2 index 2 index .knownget { 1 index ne } { //true } ifelse
 
317
          { 2 index 3 1 roll put } { pop pop } ifelse
 
318
        } forall
 
319
      } if
 
320
                % If the dictionary was global and is now local, copy
 
321
                % any global subsidiary dictionaries to local VM.  This
 
322
                % too is to work around the Word Perfect bug (see above).
 
323
      dup gcheck not {
 
324
        dup {
 
325
          dup type /dicttype eq { dup gcheck } { //false } ifelse {
 
326
                % Copy-on-write, see above.
 
327
            2 index wcheck not {
 
328
              3 -1 roll dup length dict .copydict
 
329
              3 1 roll
 
330
            } if
 
331
            .copytree 2 index 3 1 roll put
 
332
          } {
 
333
            pop pop
 
334
          } ifelse
 
335
        } forall
 
336
      } if
 
337
                % We would like to do a .setpagedevice so we don't keep
 
338
                % re-creating the dictionary.  Unfortunately, the effect
 
339
                % of this is that if any dynamic key changes (PageCount
 
340
                % in particular), we will do the equivalent of a
 
341
                % setpagedevice at the next restore or grestore.
 
342
                % Therefore, we make the dictionary read-only, but
 
343
                % we don't store it away.  I.e., NOT:
 
344
                % dup wcheck { .setpagedevice .currentpagedevice pop } if
 
345
      readonly
 
346
    } ifelse
 
347
  } if
 
348
} bind odef
 
349
 
 
350
% Copy a dictionary recursively.
 
351
/.copytree {    % <dict> .copytree <dict'>
 
352
  dup length dict exch {
 
353
    dup type /dicttype eq { .copytree } if 2 index 3 1 roll put
 
354
  } forall
 
355
} bind def
 
356
 
 
357
% The implementation of setpagedevice is quite complex.  Currently,
 
358
% everything but the media matching algorithm is implemented here.
 
359
 
 
360
% By default, we only present the requested changes to the device,
 
361
% but there are some parameters that require special merging action.
 
362
% Define those parameters here, with the procedures that do the merging.
 
363
% The procedures are called as follows:
 
364
%       <merged> <key> <new_value> -proc- <merged> <key> <new_value'>
 
365
/.mergespecial mark
 
366
  /InputAttributes
 
367
   { dup //null eq
 
368
      { pop //null
 
369
      }
 
370
      { 3 copy pop .knownget
 
371
         { dup //null eq
 
372
            { pop dup length dict }
 
373
            { dup length 2 index length add dict .copydict }
 
374
           ifelse
 
375
         }
 
376
         { dup length dict
 
377
         }
 
378
        ifelse .copydict readonly
 
379
      }
 
380
     ifelse
 
381
   } bind
 
382
  /OutputAttributes 1 index
 
383
  /Policies
 
384
    { 3 copy pop .knownget
 
385
       { dup length 2 index length add dict .copydict }
 
386
       { dup length dict }
 
387
      ifelse copy readonly
 
388
    } bind
 
389
.dicttomark readonly def
 
390
 
 
391
% M. Sweet, Easy Software Products:
 
392
%
 
393
% Define NOMEDIAATTRS to turn off the default (but unimplementable) media
 
394
% selection policies for setpagedevice.  This is used by CUPS to support
 
395
% the standard Adobe media attributes.
 
396
NOMEDIAATTRS {
 
397
  % Define only PageSize for input attribute matching.
 
398
  /.inputattrkeys [
 
399
    /PageSize
 
400
  ] readonly def
 
401
  % Define no other keys used in media selection.
 
402
  /.inputselectionkeys [
 
403
    /noInputSelectionsKeys
 
404
  ] readonly def
 
405
 
 
406
  % Define no keys used in output attribute matching.
 
407
  /.outputattrkeys [
 
408
    /noOutputAttrKeys
 
409
  ] readonly def
 
410
} {
 
411
  % Define the keys used in input attribute matching.
 
412
  /.inputattrkeys [
 
413
    /PageSize /MediaColor /MediaWeight /MediaType /InsertSheet /ManualFeed
 
414
          % The following are documented in Adobe's supplement for v2017.
 
415
    /LeadingEdge /MediaClass
 
416
  ] readonly def
 
417
  % Define other keys used in media selection.
 
418
  /.inputselectionkeys [
 
419
    /MediaPosition /Orientation
 
420
  ] readonly def
 
421
 
 
422
  % Define the keys used in output attribute matching.
 
423
  /.outputattrkeys [
 
424
    /OutputType
 
425
  ] readonly def
 
426
} ifelse
 
427
 
 
428
% Define all the parameters that should always be copied to the merged
 
429
% dictionary.
 
430
/.copiedkeys [
 
431
  /OutputDevice
 
432
  .mergespecial { pop } forall
 
433
  .inputattrkeys aload pop
 
434
  .inputselectionkeys aload pop
 
435
  .outputattrkeys aload pop
 
436
] readonly def
 
437
 
 
438
% Define the parameters that should not be presented to the device.
 
439
% The procedures are called as follows:
 
440
%       <merged> <key> <value> -proc-
 
441
% The procedure leaves all its operands on the stack and returns
 
442
% true iff the key/value pair should be presented to .putdeviceparams.
 
443
/.presentspecial mark
 
444
  .dynamicppkeys
 
445
      { pop dup /LeadingEdge ne { //false } { pop } ifelse }
 
446
  forall
 
447
                        % We must ignore an explicit request for .MediaSize,
 
448
                        % because media matching always handles this.
 
449
  /.MediaSize //false
 
450
  /Name //false
 
451
  /OutputDevice //false
 
452
  /PageDeviceName //false
 
453
  /PageOffset //false
 
454
  /PageSize //false             % obsolete alias for .MediaSize
 
455
  /InputAttributes //false
 
456
  .inputattrkeys
 
457
       { dup dup /PageSize eq exch /LeadingEdge eq or
 
458
       { pop }
 
459
       { { 2 index /InputAttributes .knownget { //null eq } { //true } ifelse } }
 
460
      ifelse
 
461
    }
 
462
  forall
 
463
  .inputselectionkeys { //false } forall
 
464
  /OutputAttributes //false
 
465
  .outputattrkeys
 
466
    { { 2 index /OutputAttributes .knownget { //null eq } { //true } ifelse } }
 
467
  forall
 
468
  /Install //false
 
469
  /BeginPage //false
 
470
  /EndPage //false
 
471
  /Policies //false
 
472
        % Our extensions:
 
473
  /HWColorMap
 
474
    {                   % HACK: don't transmit the color map, because
 
475
                        % window systems can change the color map on their own
 
476
                        % incrementally.  Someday we'll have a better
 
477
                        % solution for this....
 
478
      //false
 
479
    }
 
480
  /ViewerPreProcess //false
 
481
  /ImagingBBox //false  % This prevents the ImagingBBox value in the setpagedevice
 
482
                        % from affecting the device's ImagingBBox parameter, but
 
483
                        % does retain a 'shadow' copy at the PostScript level.
 
484
                        % This is done for Adobe compatibility since Adobe does
 
485
                        % render marks outside the ImagingBBox (and QuarkXpress
 
486
                        % relies on it).
 
487
.dicttomark readonly def
 
488
 
 
489
% Define access to device defaults.
 
490
/.defaultdeviceparams
 
491
 { finddevice //null .getdeviceparams
 
492
 } bind def
 
493
 
 
494
% Select media (input or output).  The hard work is done in an operator:
 
495
%       <pagedict> <attrdict> <policydict> <keys> .matchmedia <key> true
 
496
%       <pagedict> <attrdict> <policydict> <keys> .matchmedia false
 
497
%       <pagedict> null <policydict> <keys> .matchmedia null true
 
498
/.selectmedia           % <orig> <request> <merged> <failed>     <-- retained
 
499
                        %   <attrdict> <policydict> <attrkeys> <mediakey>
 
500
                        %   .selectmedia
 
501
 { 5 index 5 -2 roll 4 index .matchmedia
 
502
                % Stack: orig request merged failed attrkeys mediakey
 
503
                %   (key true | false)
 
504
    { 4 index 3 1 roll put pop
 
505
    }
 
506
    {   % Adobe's implementations have a "big hairy heuristic"
 
507
        % to choose the set of keys to report as having failed the match.
 
508
        % For the moment, we report any keys that are in the request
 
509
        % and don't have the same value as in the original dictionary.
 
510
      5 index 1 index .knownget
 
511
       { 4 index 3 1 roll put }
 
512
       { 3 index exch .undef }
 
513
      ifelse
 
514
       {        % Stack: <orig> <request> <merged> <failed> <attrkey>
 
515
         3 index 1 index .knownget
 
516
          { 5 index 2 index .knownget { ne } { pop //true } ifelse }
 
517
          { //true }
 
518
         ifelse         % Stack: ... <failed> <attrkey> <report>
 
519
          { 2 copy /rangecheck put }
 
520
         if pop
 
521
       }
 
522
      forall
 
523
    }
 
524
   ifelse
 
525
 } bind def
 
526
 
 
527
% Apply Policies to any unprocessed failed requests.
 
528
% As we process each request entry, we replace the error name
 
529
% in the <failed> dictionary with the policy value,
 
530
% and we replace the key in the <merged> dictionary with its prior value
 
531
% (or remove it if it had no prior value).
 
532
/.policyprocs mark
 
533
% These procedures are called with the following on the stack:
 
534
%   <orig> <merged> <failed> <Policies> <key> <policy>
 
535
% They are expected to consume the top 2 operands.
 
536
% NOTE: we currently treat all values other than 0, 1, or 7 (for PageSize)
 
537
% the same as 0, i.e., we signal an error.
 
538
%
 
539
% M. Sweet, Easy Software Products:
 
540
%
 
541
% Define NOMEDIAATTRS to turn off the default (but unimplementable) media
 
542
% selection policies for setpagedevice.  This is used by CUPS to support
 
543
% the standard Adobe media attributes.
 
544
  0 {           % Set errorinfo and signal a configurationerror.
 
545
      NOMEDIAATTRS {
 
546
        % NOMEDIAATTRS means that the default policy is 7...
 
547
        pop 2 index exch 7 put
 
548
      } {
 
549
        pop dup 4 index exch get 2 array astore
 
550
        $error /errorinfo 3 -1 roll put
 
551
        cleartomark
 
552
        /setpagedevice .systemvar /configurationerror signalerror
 
553
      } ifelse
 
554
  } bind
 
555
  1 {           % Roll back the failed request to its previous status.
 
556
SETPDDEBUG { (Rolling back.) = pstack flush } if
 
557
        3 index 2 index 3 -1 roll .forceput
 
558
        4 index 1 index .knownget
 
559
         { 4 index 3 1 roll .forceput }
 
560
         { 3 index exch .undef }
 
561
        ifelse
 
562
  } .bind
 
563
  7 {           % For PageSize only, just impose the request.
 
564
        1 index /PageSize eq
 
565
         { pop pop 1 index /PageSize 7 put }
 
566
         { .policyprocs 0 get exec }
 
567
        ifelse
 
568
  } bind
 
569
.dicttomark readonly def
 
570
/.applypolicies         % <orig> <merged> <failed> .applypolicies
 
571
                        %   <orig> <merged'> <failed'>
 
572
 { 1 index /Policies get 1 index
 
573
    { type /integertype eq
 
574
       { pop            % already processed
 
575
       }
 
576
       { 2 copy .knownget not { 1 index /PolicyNotFound get } if
 
577
                        % Stack: <orig> <merged> <failed> <Policies> <key>
 
578
                        %   <policy>
 
579
         .policyprocs 1 index .knownget not { .policyprocs 0 get } if exec
 
580
       }
 
581
      ifelse
 
582
    }
 
583
   forall pop
 
584
 } bind def
 
585
 
 
586
% Prepare to present parameters to the device, by spreading them onto the
 
587
% operand stack and removing any that shouldn't be presented.
 
588
/.prepareparams         % <params> .prepareparams -mark- <key1> <value1> ...
 
589
 { mark exch dup
 
590
    {                   % Stack: -mark- key1 value1 ... merged key value
 
591
      .presentspecial 2 index .knownget
 
592
       { exec { 3 -1 roll } { pop pop } ifelse }
 
593
       { 3 -1 roll }
 
594
      ifelse
 
595
    }
 
596
   forall pop
 
597
 } bind def
 
598
 
 
599
% Put device parameters without resetting currentpagedevice.
 
600
% (.putdeviceparams clears the current page device.)
 
601
/.putdeviceparamsonly   % <device> <Policies|null> <require_all> -mark-
 
602
                        %   <key1> <value1> ... .putdeviceparamsonly
 
603
                        % On success: <device> <eraseflag>
 
604
                        % On failure: <device> <Policies|null> <req_all> -mark-
 
605
                        %   <key1> <error1> ...
 
606
 { .currentpagedevice
 
607
    { counttomark 4 add 1 roll .putdeviceparams
 
608
      dup type /booleantype eq { 3 } { counttomark 5 add } ifelse -1 roll
 
609
      .setpagedevice
 
610
    }
 
611
    { pop .putdeviceparams
 
612
    }
 
613
   ifelse
 
614
 } bind def
 
615
 
 
616
% Try setting the device parameters from the merged request.
 
617
/.trysetparams          % <merged> <(ignored)> <device> <Policies>
 
618
                        %   .trysetparams
 
619
 { //true 4 index .prepareparams
 
620
                        % Add the computed .MediaSize.
 
621
                        % Stack: merged (ignored) device Policies -true-
 
622
                        %   -mark- key1 value1 ...
 
623
   counttomark 5 add index .computemediasize
 
624
   exch pop exch pop /.MediaSize exch
 
625
SETPDDEBUG { (Putting.) = pstack flush } if
 
626
   .putdeviceparamsonly
 
627
SETPDDEBUG { (Result of putting.) = pstack flush } if
 
628
 } bind def
 
629
 
 
630
% Compute the media size and initial matrix from a merged request (after
 
631
% media selection).
 
632
/.computemediasize      % <request> .computemediasize
 
633
                        %   <request> <matrix> <[width height]>
 
634
 { dup /PageSize get                                    % requested page size
 
635
   1 index /InputAttributes get
 
636
     2 index (%MediaSource) get get /PageSize get       % media size
 
637
                                                        % (may be a range)
 
638
   2 index /Policies get
 
639
     dup /PageSize .knownget
 
640
      { exch pop } { /PolicyNotFound get } ifelse       % PageSize policy,
 
641
                                                        % affects scaling
 
642
   3 index /Orientation .knownget not { //null } if
 
643
   4 index /RollFedMedia .knownget not { //false } if
 
644
   matrix .matchpagesize not {
 
645
                % This is a "can't happen" condition!
 
646
     /setpagedevice .systemvar /rangecheck signalerror
 
647
   } if
 
648
   2 array astore
 
649
 } bind def
 
650
 
 
651
% ---------------- setpagedevice itself ---------------- %
 
652
 
 
653
/setpagedevice
 
654
 {              % We mustn't pop the argument until the very end,
 
655
                % so that the pseudo-operator machinery can restore the stack
 
656
                % if an error occurs.
 
657
   mark 1 index currentpagedevice
 
658
 
 
659
                % Check whether we are changing OutputDevice;
 
660
                % also handle the case where the current device
 
661
                % is not a page device.
 
662
                % Stack: mark <request> <current>
 
663
SETPDDEBUG { (Checking.) = pstack flush } if
 
664
 
 
665
   dup /OutputDevice .knownget
 
666
    {           % Current device is a page device.
 
667
      2 index /OutputDevice .knownget
 
668
       {        % A specific OutputDevice was requested.
 
669
         2 copy eq
 
670
          { pop pop //null }
 
671
          { exch pop }
 
672
         ifelse
 
673
       }
 
674
       { pop //null
 
675
       }
 
676
      ifelse
 
677
    }
 
678
    {           % Current device is not a page device.
 
679
                % Use the default device.
 
680
      1 index /OutputDevice .knownget not { .defaultdevicename } if
 
681
    }
 
682
   ifelse
 
683
   dup //null eq
 
684
    { pop
 
685
    }
 
686
    { exch pop .defaultdeviceparams
 
687
                % In case of duplicate keys, .dicttomark takes the entry
 
688
                % lower on the stack, so we can just append the defaults here.
 
689
      .requiredattrs { exec } forall .dicttomark
 
690
    }
 
691
   ifelse
 
692
 
 
693
                % Check whether a viewer wants to intervene.
 
694
                % We must check both the request (which takes precedence)
 
695
                % and the current dictionary.
 
696
                % Stack: mark <request> <orig>
 
697
   exch dup /ViewerPreProcess .knownget
 
698
    { exec }
 
699
    { 1 index /ViewerPreProcess .knownget { exec } if }
 
700
   ifelse exch
 
701
 
 
702
                % Construct a merged request from the actual request plus
 
703
                % any keys that should always be propagated.
 
704
                % Stack: mark <request> <orig>
 
705
SETPDDEBUG { (Merging.) = pstack flush } if
 
706
 
 
707
   exch 1 index length 1 index length add dict
 
708
   .copiedkeys
 
709
    {           % Stack: <orig> <request> <merged> <key>
 
710
      3 index 1 index .knownget { 3 copy put pop } if pop
 
711
    }
 
712
   forall
 
713
                % Stack: <orig> <request> <merged>
 
714
   dup 2 index
 
715
    {           % stack: <orig> <request> <merged> <merged> <rkey> <rvalue>
 
716
      .mergespecial 2 index .knownget { exec } if
 
717
      put dup
 
718
    }
 
719
   forall pop
 
720
                % Hack: if FIXEDRESOLUTION is true, discard any attempt to
 
721
                % change HWResolution.
 
722
   FIXEDRESOLUTION { dup /HWResolution .undef } if
 
723
                % Hack: if FIXEDMEDIA is true, discard any attempt to change
 
724
                % PageSize or HWSize.
 
725
   FIXEDMEDIA
 
726
    { dup /PageSize 4 index /PageSize get put
 
727
      dup /HWSize 4 index /HWSize get put
 
728
    } if
 
729
                % Hack: to work around some files that take a PageSize
 
730
                % from InputAttributes and impose it, discard any attempt
 
731
                % to set PageSize to a 4-element value.
 
732
                % Stack: mark <orig> <request> <merged>
 
733
    dup /PageSize .knownget {
 
734
      length 2 ne {
 
735
        dup /PageSize 4 index /PageSize get put
 
736
      } if
 
737
    } if
 
738
 
 
739
                % Select input and output media.
 
740
                % Stack: mark <orig> <request> <merged>
 
741
SETPDDEBUG { (Selecting.) = pstack flush } if
 
742
 
 
743
   0 dict       % <failed>
 
744
   1 index /InputAttributes .knownget
 
745
    { 2 index /Policies get
 
746
      .inputattrkeys (%MediaSource) cvn .selectmedia
 
747
    } if
 
748
   1 index /OutputAttributes .knownget
 
749
    { 2 index /Policies get
 
750
      .outputattrkeys (%MediaDestination) cvn .selectmedia
 
751
     } if
 
752
   3 -1 roll 4 1 roll           % temporarily swap orig & request
 
753
   .applypolicies
 
754
   3 -1 roll 4 1 roll           % swap back
 
755
 
 
756
                % Construct the new device, and attempt to set its attributes.
 
757
                % Stack: mark <orig> <request> <merged> <failed>
 
758
SETPDDEBUG { (Constructing.) = pstack flush } if
 
759
 
 
760
   currentdevice .devicename 2 index /OutputDevice get eq
 
761
    { currentdevice }
 
762
    { 1 index /OutputDevice get finddevice }
 
763
   ifelse
 
764
                %**************** We should copy the device here,
 
765
                %**************** but since we can't close the old device,
 
766
                %**************** we don't.  This is WRONG.
 
767
        %****************copydevice
 
768
   2 index /Policies get
 
769
   .trysetparams
 
770
   dup type /booleantype ne
 
771
    {           % The request failed.
 
772
                % Stack: ... <orig> <request> <merged> <failed> <device>
 
773
                %   <Policies> true mark <name> <errorname> ...
 
774
SETPDDEBUG { (Recovering.) = pstack flush } if
 
775
      counttomark 4 add index
 
776
      counttomark 2 idiv { dup 4 -2 roll put } repeat
 
777
      pop pop pop
 
778
                % Stack: mark ... <orig> <request> <merged> <failed> <device>
 
779
                %   <Policies>
 
780
      6 2 roll 3 -1 roll 4 1 roll
 
781
      .applypolicies
 
782
      3 -1 roll 4 1 roll 6 -2 roll
 
783
      .trysetparams             % shouldn't fail!
 
784
      dup type /booleantype ne
 
785
       { 2 { counttomark 1 add 1 roll cleartomark } repeat
 
786
         /setpagedevice .systemvar exch signalerror
 
787
       }
 
788
      if
 
789
    }
 
790
   if
 
791
 
 
792
                % The attempt succeeded.  Install the new device.
 
793
                % Stack: mark ... <merged> <failed> <device> <eraseflag>
 
794
SETPDDEBUG { (Installing.) = pstack flush } if
 
795
 
 
796
   pop 2 .endpage
 
797
    { 1 //true .outputpage
 
798
      (>>setpagedevice, press <return> to continue<<\n) .confirm
 
799
    }
 
800
   if
 
801
                % .setdevice clears the current page device!
 
802
   .currentpagedevice pop exch
 
803
   .setdevice pop
 
804
   .setpagedevice
 
805
 
 
806
                % Implement UseCIEColor directly if this is a LL3 system.
 
807
                % The color substitution feature is now implemented in
 
808
                % the interpreter, and this is used as an optimization.
 
809
                %
 
810
                % NB: This shoud be the only use of the .setuseciecolor
 
811
                %     operator anywhere.
 
812
                %
 
813
                % If UseCIEColor is transitioned to false, set some
 
814
                % color space other than /DeviceGray, to insure that
 
815
                % initgraphics will actually perform a setcolorspace
 
816
                % operation (there is an optimization in setcolorspace
 
817
                % that does nothing if the operand and current color
 
818
                % spaces are the same, and UseCIEColor is false).
 
819
 
 
820
    /.setuseciecolor where
 
821
      {
 
822
        pop 1 index /UseCIEColor .knownget
 
823
          {
 
824
            dup .setuseciecolor not
 
825
              { /DeviceRGB setcolorspace }
 
826
            if
 
827
          }
 
828
        if
 
829
      }
 
830
    if
 
831
 
 
832
                % Merge the request into the current page device,
 
833
                % unless we're changing the OutputDevice.
 
834
                % Stack: mark ... <merged> <failed>
 
835
   exch currentpagedevice dup length 2 index length add dict
 
836
                % Stack: mark ... <failed> <merged> <current> <newdict>
 
837
   2 index /OutputDevice .knownget {
 
838
     2 index /OutputDevice .knownget not { //null } if eq
 
839
   } {
 
840
     //true
 
841
   } ifelse {
 
842
                % Same OutputDevice, merge the dictionaries.
 
843
     .copydict
 
844
   } {
 
845
                % Different OutputDevice, discard the old dictionary.
 
846
     exch pop
 
847
   } ifelse .copydict
 
848
                % Initialize the default matrix, taking media matching
 
849
                % into account.
 
850
   .computemediasize pop initmatrix concat
 
851
   dup /PageOffset .knownget
 
852
    {           % Translate by the given number of 1/72" units in device X/Y.
 
853
      dup 0 get exch 1 get
 
854
      2 index /HWResolution get dup 1 get exch 0 get
 
855
      4 -1 roll mul 72 div   3 1 roll mul 72 div
 
856
      idtransform translate
 
857
    }
 
858
   if
 
859
                % We must install the new page device dictionary
 
860
                % before calling the Install procedure.
 
861
  dup .setpagedevice
 
862
  .setdefaulthalftone   % Set the default screen before calling Install.
 
863
  dup /Install .knownget {
 
864
    { .execinstall } stopped {
 
865
      pop % Install procedure failed. One element will have been left on the stack.
 
866
      % stack: mark <orig> <request> <failed> <merged>
 
867
      1 index /Install $error /errorname get put        % Put it in the "failed" dict
 
868
      % .applypolicies needs stack: <orig> <merged> <failed>
 
869
      exch 4 2 roll exch 4 2 roll .applypolicies exch 4 2 roll exch 4 2 roll
 
870
      % Now execute the old Install -- failures after this are not handled
 
871
      dup /Install .knownget { { .execinstall } stopped { pop } if } if
 
872
      .postinstall stop
 
873
    } {
 
874
      .postinstall
 
875
    } ifelse
 
876
  } {
 
877
    .postinstall
 
878
  } ifelse
 
879
} odef
 
880
 
 
881
% We break out the code after calling the Install procedure into a
 
882
% separate procedure, since it is executed even if Install causes an error.
 
883
% By making .execinstall a separate operator procedure, we get the stacks
 
884
% mostly restored if it fails, except for one element (the operand).
 
885
% Thus if it fails, there will be one element left on the op stack.
 
886
 
 
887
/.execinstall {         % <proc> .execinstall -
 
888
  dup   % element left on the stack if the exec fails.
 
889
 
 
890
        % Because the interpreter optimizes tail calls, we can't just let
 
891
        % the body of this procedure be 'exec', because that would lose
 
892
        % the stack protection that is the whole reason for having the
 
893
        % procedure in the first place. The 'pop' for the dummy element 
 
894
        % on the op stack suffices.
 
895
  exec
 
896
  pop   % See above.
 
897
} odef
 
898
 
 
899
/.postinstall {         % mark ... <failed> <merged> .postinstall -
 
900
   matrix currentmatrix .setdefaultmatrix
 
901
                % Erase and initialize the page.
 
902
   initgraphics
 
903
   currentoverprint //false setoverprint 1 setcolor
 
904
   .fillpage
 
905
   0 setcolor setoverprint
 
906
   .beginpage
 
907
 
 
908
                % Clean up, calling PolicyReport if needed.
 
909
                % Stack: mark ... <failed> <merged>
 
910
SETPDDEBUG { (Finishing.) = pstack flush } if
 
911
 
 
912
   exch dup length 0 ne
 
913
    { 1 index /Policies get /PolicyReport get
 
914
      counttomark 1 add 2 roll cleartomark
 
915
      exec
 
916
    }
 
917
    { cleartomark
 
918
    }
 
919
   ifelse pop
 
920
 
 
921
} odef
 
922
 
 
923
end                             % level2dict
 
924
.setlanguagelevel