📄 gs_setpd.ps
字号:
% Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved.
%
% This file is part of Aladdin Ghostscript.
%
% Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
% or distributor accepts any responsibility for the consequences of using it,
% or for whether it serves any particular purpose or works at all, unless he
% or she says so in writing. Refer to the Aladdin Ghostscript Free Public
% License (the "License") for full details.
%
% Every copy of Aladdin Ghostscript must include a copy of the License,
% normally in a plain ASCII text file named PUBLIC. The License grants you
% the right to copy, modify and redistribute Aladdin Ghostscript, but only
% under certain conditions described in the License. Among other things, the
% License requires that the copyright notice and this notice be preserved on
% all copies.
% The current implementation of setpagedevice has the following limitations:
% - It doesn't attempt to "interact with the user" for Policy = 2.
languagelevel 1 .setlanguagelevel
level2dict begin
% ---------------- Redefinitions ---------------- %
% Redefine .beginpage and .endpage so that they call BeginPage and
% EndPage respectively if appropriate.
/.beginpage
{ .currentshowpagecount
{ .currentpagedevice pop /BeginPage .knownget { exec } { pop } ifelse }
if
} bind odef
/.endpage
{ .currentshowpagecount
{ exch .currentpagedevice pop /EndPage .knownget
{ exec }
{ exch pop 2 ne }
ifelse
}
{ 2 ne
}
ifelse
} bind odef
% Define interpreter callouts for handling gstate-saving operators,
% to make sure that they create a page device dictionary for use by
% the corresponding gstate-restoring operator.
% We'd really like to avoid the cost of doing this, but we don't see how.
% The names %gsavepagedevice, %savepagedevice, %gstatepagedevice,
% %copygstatepagedevice, and %currentgstatepagedevice are known to the
% interpreter.
(%gsavepagedevice) cvn
{ currentpagedevice pop gsave
} bind def
(%savepagedevice) cvn
{ currentpagedevice pop save
} bind def
(%gstatepagedevice) cvn
{ currentpagedevice pop gstate
} bind def
(%copygstatepagedevice) cvn
{ currentpagedevice pop copy
} bind def
(%currentgstatepagedevice) cvn
{ currentpagedevice pop currentgstate
} bind def
% Define interpreter callouts for handling gstate-restoring operators
% when the current page device needs to be changed.
% The names %grestorepagedevice, %grestoreallpagedevice,
% %restorepagedevice, and %setgstatepagedevice are known to the interpreter.
/.installpagedevice
{ % Since setpagedevice doesn't create new device objects,
% we must (carefully) reinstall the old parameters in
% the same device.
.currentpagedevice pop null currentdevice null .trysetparams
dup type /booleantype eq
{ pop pop }
{ % This should never happen!
DEBUG { (Error in .trysetparams!\n) print pstack flush } if
cleartomark pop pop pop
/.installpagedevice cvx /rangecheck signalerror
}
ifelse pop pop
erasepage initgraphics .beginpage
} bind def
/.uninstallpagedevice
{ 2 .endpage { .currentnumcopies false .outputpage } if
nulldevice
} bind def
(%grestorepagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice
} bind def
(%grestoreallpagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice grestoreall
} bind def
(%restorepagedevice) cvn
{ .uninstallpagedevice grestore .installpagedevice restore
} bind def
(%setgstatepagedevice) cvn
{ .uninstallpagedevice setgstate .installpagedevice
} bind def
% Redefine .currentnumcopies so it consults the NumCopies device parameter.
/.numcopiesdict mark
/NumCopies dup
.dicttomark readonly def
/.currentnumcopies
{ currentdevice //.numcopiesdict .getdeviceparams
dup type /integertype eq
{ exch pop exch pop }
{ cleartomark #copies }
ifelse
} bind odef
% ---------------- Auxiliary definitions ---------------- %
% Define the required attributes of all page devices, and their default values.
% We don't include attributes such as .MediaSize, which all devices
% are guaranteed to supply on their own.
/.defaultpolicies mark
/PolicyNotFound 1
/PageSize 0
/PolicyReport {pop} bind
.dicttomark readonly def
/.requiredattrs mark
/PageOffset [0 0] readonly
% We define InputAttributes and OutputAttributes with a single
% dummy media type that handles pages of any size.
% Devices that care will override this.
/InputAttributes mark 0
mark /PageSize [0 dup 16#7ffff dup] .dicttomark readonly
.dicttomark readonly
(%MediaSource) 0
/OutputAttributes mark 0
mark .dicttomark readonly
.dicttomark readonly
(%MediaDestination) 0
/Install {.callinstall} bind
/BeginPage {.callbeginpage} bind
/EndPage {.callendpage} bind
/Policies .defaultpolicies
.dicttomark readonly def
% Define currentpagedevice so it creates the dictionary on demand if needed,
% adding all the required entries defined just above.
% We have to deal specially with entries that the driver may change
% on its own.
/.dynamicppkeys mark
/.MediaSize dup % because it changes when PageSize is set
/PageCount dup
.dicttomark readonly def
/.makecurrentpagedevice % - .makecurrentpagedevice <dict>
{ currentdevice null .getdeviceparams
% In case of duplicate keys, .dicttomark takes the entry
% lower on the stack, so we can just append the defaults here.
.requiredattrs { } forall .dicttomark
dup .setpagedevice
} bind def
/currentpagedevice
{ .currentpagedevice
{ dup length 0 eq
{ pop .makecurrentpagedevice
}
{ % If any of the dynamic keys have changed,
% we must update the page device dictionary.
currentdevice //.dynamicppkeys .getdeviceparams .dicttomark
{ % Stack: current key value
2 index 2 index .knownget { 1 index ne } { true } ifelse
{ 2 index wcheck not
{ % This is the first entry being updated.
% Copy the dictionary to make it writable.
3 -1 roll dup length dict .copydict
3 1 roll
}
if
2 index 3 1 roll put
}
{ pop pop
}
ifelse
}
forall
% We would like to do a .setpagedevice so we don't keep
% re-creating the dictionary. Unfortunately, the effect
% of this is that if any dynamic key changes (PageCount
% in particular), we will do the equivalent of a
% setpagedevice at the next restore or grestore.
% Therefore, we make the dictionary read-only, but
% we don't store it away. I.e., NOT:
% dup wcheck { .setpagedevice .currentpagedevice pop } if
readonly
}
ifelse
}
if
} bind odef
% The implementation of setpagedevice is quite complex. Currently,
% everything but the media matching algorithm is implemented here.
% By default, we only present the requested changes to the device,
% but there are some parameters that require special merging action.
% Define those parameters here, with the procedures that do the merging.
% The procedures are called as follows:
% <merged> <key> <new_value> -proc- <merged> <key> <new_value'>
/.mergespecial mark
/InputAttributes
{ dup null eq
{ pop null
}
{ 3 copy pop .knownget
{ dup null eq
{ pop dup length dict }
{ dup length 2 index length add dict .copydict }
ifelse
}
{ dup length dict
}
ifelse .copydict readonly
}
ifelse
} bind
/OutputAttributes 1 index
/Policies
{ 3 copy pop .knownget
{ dup length 2 index length add dict .copydict }
{ dup length dict }
ifelse copy readonly
} bind
.dicttomark readonly def
% Define the keys used in input attribute matching.
/.inputattrkeys [
/PageSize /MediaColor /MediaWeight /MediaType /InsertSheet
] readonly def
% Define other keys used in media selection.
/.inputselectionkeys [
/MediaPosition /Orientation
] readonly def
% Define the keys used in output attribute matching.
/.outputattrkeys [
/OutputType
] readonly def
% Define all the parameters that should always be copied to the merged
% dictionary.
/.copiedkeys [
/OutputDevice
.mergespecial { pop } forall
.inputattrkeys aload pop
.inputselectionkeys aload pop
.outputattrkeys aload pop
] readonly def
% Define the parameters that should not be presented to the device.
% The procedures are called as follows:
% <merged> <key> <value> -proc-
% The procedure leaves all its operands on the stack and returns
% true iff the key/value pair should be presented to .putdeviceparams.
/.presentspecial mark
.dynamicppkeys { pop false } forall
% We must ignore an explicit request for .MediaSize,
% because media matching always handles this.
/.MediaSize false
/Name false
/OutputDevice false
/PageOffset false
/PageSize false % obsolete alias for .MediaSize
/InputAttributes false
.inputattrkeys
{ dup /PageSize eq
{ pop }
{ { 2 index /InputAttributes .knownget { null eq } { true } ifelse } }
ifelse
}
forall
.inputselectionkeys { false } forall
/OutputAttributes false
.outputattrkeys
{ { 2 index /OutputAttributes .knownget { null eq } { true } ifelse } }
forall
/Install false
/BeginPage false
/EndPage false
/Policies false
% Our extensions:
/HWColorMap
{ % HACK: don't transmit the color map, because
% window systems can change the color map on their own
% incrementally. Someday we'll have a better
% solution for this....
false
}
/ViewerPreProcess false
.dicttomark readonly def
% Define access to device defaults.
/.defaultdeviceparams
{ finddevice null .getdeviceparams
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -