]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/gs_ll3.ps
Import cups.org releases
[thirdparty/cups.git] / pstoraster / gs_ll3.ps
1 % Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved.
2 %
3 % This file is part of GNU Ghostscript.
4 %
5 % GNU Ghostscript is distributed in the hope that it will be useful, but
6 % WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 % to anyone for the consequences of using it or for whether it serves any
8 % particular purpose or works at all, unless he says so in writing. Refer
9 % to the GNU General Public License for full details.
10 %
11 % Everyone is granted permission to copy, modify and redistribute GNU
12 % Ghostscript, but only under the conditions described in the GNU General
13 % Public License. A copy of this license is supposed to have been given
14 % to you along with GNU Ghostscript so you can know your rights and
15 % responsibilities. It should be in a file named COPYING. Among other
16 % things, the copyright notice and this notice must be preserved on all
17 % copies.
18 %
19 % Aladdin Enterprises supports the work of the GNU Project, but is not
20 % affiliated with the Free Software Foundation or the GNU Project. GNU
21 % Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 % GNU software to build or run it.
23
24 % $Id: gs_ll3.ps 956 2000-03-08 23:15:43Z mike $
25 % Initialization file for PostScript LanguageLevel 3 functions.
26 % Essentially all of these are stubs right now.
27 % This file must be loaded after gs_lev2.ps and gs_res.ps.
28 % These definitions go into ll3dict or various ProcSets.
29 % NOTE: the interpreter creates ll3dict.
30
31 ll3dict begin
32
33 % We need LanguageLevel 2 or higher in order to have setuserparams and
34 % defineresource.
35 languagelevel dup 2 max .setlanguagelevel
36
37 % ------ Idiom recognition ------ %
38
39 /IdiomRecognition false .definepsuserparam
40
41 % Modify `bind' to apply idiom recognition afterwards.
42 /.bindscratch 128 string def
43 % Do the right thing if NOBIND or DELAYBIND is in effect.
44 % Note also that since this definition of `bind' may get bound in,
45 % it has to function properly even at lower language levels,
46 % where IdiomRecognition may not be defined.
47 /bind load /.bind load ne
48 /bind { % <proc> bind <proc'>
49 //.bind currentuserparams /IdiomRecognition
50 .knownget not { false } if {
51 (*) {
52 /IdiomSet findresource
53 false exch {
54 % Stack: proc false dummykey [template substitute]
55 exch pop dup 1 get exch 0 get
56 % Stack: proc false substitute template
57 3 index .eqproc {
58 2 index gcheck 1 index gcheck not and {
59 pop
60 } {
61 3 -1 roll pop exch not exit
62 } ifelse
63 } {
64 pop
65 } ifelse
66 } forall { exit } if
67 } //.bindscratch /IdiomSet resourceforall
68 } if
69 } odef
70 { /.bind /bind load def
71 /bind { } def
72 } if
73 currentdict /.bindscratch .undef
74
75 % ------ HalftoneTypes 6, 10, 16 ------ %
76
77 % This code depends on one new operator:
78 %
79 % <dict> <Width> <Height> <Thresholds> <bits> <shift> .setstriphalftone -
80 %
81 % <dict> is the dictionary that will be returned by .currenthalftone.
82 % The operator only looks at the TransferFunction entry.
83 % Width, Height: as for HalftoneType 3.
84 % Thresholds: a BigStringEncode filter holding the thresholds,
85 % Width x Height x BitsPerSample / 8 bytes.
86 % shift: the amount of X shift per Y repetition of the halftone,
87 % 0 <= Shift < Width.
88 % bits: bits per sample, 8 or 16.
89 %
90 % Eventually the code below will have to get hooked up to sethalftone
91 % and currenthalftone....
92
93 /.copybytes { % <source> <dest> <count> .copybytes -
94 { 1 index read not { /sethalftone load /rangecheck signalerror exit } if
95 1 index exch write
96 } repeat pop pop
97 } bind def
98
99 /.copythresholds { % <dict> <Width> <Height> <bits> .copythresholds -
100 dup 8 idiv 3 index mul 2 index mul
101 dup /BigStringEncode filter 3 1 roll
102 % Stack: dict width height dest bits nbytes
103 5 index /Thresholds get 3 index 3 -1 roll .copybytes
104 1 index closefile
105 0 .setstriphalftone
106 } bind def
107
108 /.sethalftone6 { % <dict> .sethalftone6 -
109 % Keys: Width, Height, Thresholds, T'Function
110 dup /Width get 1 index /Height get
111 8 .copythresholds
112 } odef
113
114 /.copythresholds2 { % <dict> <Width> <Height> <Width2> <Height2>
115 % <bits> .copythresholds2 -
116 % The block height B is gcd(Height, Height2).
117 3 index 2 index {
118 2 copy lt { exch } if dup 1 eq { pop exit } if exch 1 index mod
119 } loop
120 % The raster R is (Width * Height + Width2 * Height2) / B * bits/8.
121 5 index 5 index mul 4 index 4 index mul add 1 index idiv
122 2 index 8 idiv mul
123 % Currently I don't know how to compute the stride.
124 % ****** COMPUTE THE STRIDE SOMEHOW ******
125 % Push additional arguments onto the stack.
126 1 index 1 index mul /BigStringEncode filter 4 1 roll
127 9 index /Thresholds get
128 % Stack: dict width height width2 height2 bits
129 % dest B R stride source
130 % For the first rectangle, the number of blocks is Height / B;
131 % the offset is 0.
132 5 copy 14 index 5 1 roll
133 14 index 5 index idiv 4 1 roll
134 0 exch .copyshifted
135 % For the second rectangle, the number of blocks is Height2 / B;
136 % the offset is Width.
137 5 copy 12 index 5 1 roll
138 12 index 4 index idiv 4 1 roll
139 16 index exch .copyshifted
140 % Stack: dict width height width2 height2 bits
141 % dest B R stride source
142 % We want: dict R/(bits/8) B dest bits stride
143 pop exch 4 index 8 idiv idiv 4 1 roll
144 % R/(bits/8) dest B stride
145 exch 3 1 roll 5 -1 roll exch
146 9 -4 roll 4 { pop } repeat
147 .setstriphalftone
148 } bind def
149
150 % Copy a shifted rectangular threshold array into a BigStringEncode filter.
151 % Note that the width and shift are in bytes, not samples.
152 /.copyshifted { % <dest> <width> <B> <N> <R> <stride> <offset>
153 % <source> .copyshifted -
154 % Copy N blocks of <width> x B bytes from <source>.
155 % Row Y (0 <= Y < B) in group G (0 <= G < N) must get copied to byte position
156 % Y * R + (G * stride + offset) mod R
157 % in the destination.
158 1 index % Stack: ... rowstart
159 6 index { % iterate over rows within a block
160 5 index { % iterate over blocks
161 8 index 1 index setfileposition
162 1 index 9 index 9 index .copybytes
163 4 index add % + raster
164 } repeat % end block
165 3 index add 4 index mod % + stride, mod raster
166 } repeat % end row in block
167 9 { pop } repeat
168 } bind def
169
170 /.sethalftone10 { % <dict> .sethalftone10 -
171 % Keys: XSquare, YSquare, Thresholds, T'Function
172 % ****** DOESN'T HANDLE STRING SOURCE ******
173 dup /XSquare get dup 2 index /YSquare get dup
174 8 .copythresholds2
175 } odef
176
177 /.sethalftone16 { % <dict> .sethalftone16 -
178 % Keys: Width, Height, Width2, Height2,
179 % Thresholds, T'Function
180 dup /Width get 1 index /Height get
181 2 index /Width2 .knownget { % 2-rectangle case
182 3 index /Height2 get
183 16 .copythresholds2
184 } { % 1-rectangle case
185 16 .copythresholds
186 } ifelse
187 } odef
188
189 {6 10 16} { dup /HalftoneType defineresource pop } forall
190
191 % ------ ImageTypes 3 and 4 (masked images) ------ %
192
193 .imagetypes
194 dup 3 /.image3 load put
195 4 /.image4 load put
196
197 % ------ Functions ------ %
198
199 % Define the FunctionType resource category.
200 /Generic /Category findresource dup maxlength 3 add dict .copydict begin
201 /InstanceType /integertype def
202 /FunctionType currentdict end /Category defineresource pop
203
204 {0 2 3} { dup /FunctionType defineresource pop } forall
205
206 % ------ Smooth shading ------ %
207
208 % Define the ShadingType resource category.
209 /Generic /Category findresource dup maxlength 3 add dict .copydict begin
210 /InstanceType /integertype def
211 /ShadingType currentdict end /Category defineresource pop
212
213 systemdict /.shadingtypes mark % not ll3dict
214 1 /.buildshading1 load
215 2 /.buildshading2 load
216 3 /.buildshading3 load
217 4 /.buildshading4 load
218 5 /.buildshading5 load
219 6 /.buildshading6 load
220 7 /.buildshading7 load
221 .dicttomark put
222
223 /.buildshading { % <shadingdict> .buildshading <shading>
224 % The .buildshading operators use the current color space
225 % for ColorSpace.
226 dup /ShadingType get //.shadingtypes exch get
227 1 index /ColorSpace get gsave { setcolorspace exec } stopped
228 grestore { stop } if
229 } bind def
230 /.buildpattern2 { % <template> <matrix> .buildpattern2
231 % <template> <pattern>
232 1 index /Shading get .buildshading .buildshadingpattern
233 } bind def
234
235 .patterntypes
236 2 /.buildpattern2 load put
237
238 /shfill { % <shadingdict> shfill -
239 % Currently, .shfill requires that the color space
240 % in the pattern be the current color space.
241 dup .buildshading
242 1 index /ColorSpace get
243 gsave { setcolorspace .shfill } stopped grestore { stop } if
244 pop
245 } odef
246
247 % Establish an arbitrary initial smoothness value.
248 1 64 div setsmoothness
249
250 % ------ Trapping ------ %
251
252 % The PostScript-level trapping parameters are maintained in userdict,
253 % and explicitly reinstalled upon restore.
254
255 /Trapping mark
256
257 /settrapparams dup { % <paramdict> settrapparams -
258 /.trapparams .uservar dup length dict .copydict
259 dup 2 index {
260 % Stack: paramdict olddict olddict key value
261 2 index 2 index known { put dup } { pop pop } ifelse
262 } forall pop
263 dup .settrapparams % Let the operator check parameter validity.
264 .userdict /.trapparams 3 -1 roll put pop
265 } bind .makeoperator
266
267 /.copyparams { % <obj> .copyparams <obj'>
268 dup type /dicttype eq {
269 dup length dict .copydict
270 dup {
271 .copyparams 3 copy put pop pop
272 } forall
273 } {
274 dup type /arraytype eq {
275 [ exch { .copyparams } forall ]
276 } if
277 } ifelse
278 } odef
279
280 /currenttrapparams dup { % - currenttrapparams <paramdict>
281 /.trapparams .uservar .copyparams
282 } bind .makeoperator
283
284 /settrapzone dup { % - settrapzone -
285 % ****** DUMMY ******
286 newpath
287 } bind .makeoperator
288
289 % Define initial (dummy) trapping parameters.
290 % These values are mostly complete guesses.
291 userdict /.trapparams mark
292 /BlackColorLimit 1.0
293 /BlackDensityLimit 1.0
294 /BlackWidth 1.0
295 /ColorantZoneDetails 0 dict
296 /Enabled true
297 /HalftoneName null
298 /ImageInternalTrapping false
299 /ImageResolution 1
300 /ImageToObjectTrapping true
301 /ImageTrapPlacement /Center
302 /SlidingTrapLimit 1.0
303 /StepLimit 1.0
304 /TrapColorScaling 0.0
305 /TrapSetName null
306 /TrapWidth 1.0
307 .dicttomark readonly put
308
309 .dicttomark /ProcSet defineresource pop
310
311 % ------ Miscellaneous ------ %
312
313 % Define additional user and system parameters.
314 psuserparams begin
315 /HalftoneMode 0 def
316 /MaxSuperScreen 1016 def
317 end
318 pssystemparams begin % read-only, so use .forcedef
319 /MaxDisplayAndSourceList 160000 .forcedef
320 end
321
322 % Define the IdiomSet, InkParams, and TrapParams resource categories.
323 { /IdiomSet /InkParams /TrapParams } {
324 /Generic /Category findresource dup maxlength 3 add dict .copydict begin
325 /InstanceType /dicttype def
326 currentdict end /Category defineresource pop
327 } forall
328
329 % Define the ReusableStreamDecode filter.
330 % ****** DOESN'T WORK FOR CONTENTS >64K ******
331 /.reusablestreamdecode { % <source> <dict> .reusablestreamdecode <file>
332 % <source> .reusablestreamdecode <file>
333 % Collect the filter parameters.
334 dup type /dicttype eq { 2 copy } { dup 0 dict } ifelse
335 dup .rsdparams
336 % Construct the filter pipeline.
337 % The very first filter should use the value of CloseSource
338 % from the RSD dictionary; all the others should have
339 % CloseSource = true.
340 % Stack: source dict filters parms
341 2 index /CloseSource .knownget not { false } if 5 -1 roll
342 % Stack: dict filters parms CloseSource source
343 0 1 5 index length 1 sub {
344 4 index 1 index get
345 % Stack: dict filters parms CloseSource source index filtname
346 4 index null eq {
347 0 dict
348 } {
349 4 index 2 index get dup null eq { pop } if
350 } ifelse
351 3 -1 roll pop filter
352 exch pop true exch % set CloseSource for further filters
353 } for
354 % See if we can create the filter directly.
355 % Stack: dict filters parms CloseSource file
356 null 2 index { .reusablestream } .internalstopped {
357 pop pop
358 % No luck. Read the entire contents of the stream now.
359 10 dict exch {
360 % Stack: dict filters parms CloseSource contdict file
361 dup 1000 string readstring
362 3 index dup length 4 -1 roll put not { break } if
363 } loop pop
364 % Concatenate the contents into one big string.
365 % Stack: dict filters parms CloseSource contdict
366 0 1 index { length exch pop add } forall string
367 exch {
368 % Stack: dict filters parms CloseSource string index substring
369 exch 1000 mul exch 2 index 3 1 roll putinterval
370 } forall
371 % Now create the stream on the string.
372 null 3 -1 roll .reusablestream
373 } if
374 % We created the stream successfully: clean up.
375 4 { exch pop } repeat
376 dup type /dicttype eq { pop } if pop
377 } odef
378 filterdict /ReusableStreamDecode /.reusablestreamdecode load put
379
380 /languagelevel 3 def
381 % When running in LanguageLevel 3 mode, this interpreter is supposed to be
382 % compatible with Adobe version 3010.
383 /version (3010) readonly def
384
385 .setlanguagelevel
386
387 end % ll3dict