1%
2% psi.prolog
3%
4% Copyright (C) 1996-2000 by vhf computer GmbH + vhf interservice GmbH
5% Author:   Georg Fleischmann
6%
7% created:  2000-09-09
8% modified:
9%
10
11%%% this file also contains a section taken from GPL Ghostscript 8.50 "traceimg.ps", see below
12
13% this PostScript code writes a file with the structure below.
14% # # # # l		(x0 y0 x1 y1) line
15% # # # # # # # #c	(x0 y0 x1 y1 x2 y2 x3 y3) curve
16% # w			(width) width
17% # # # # # co		(c m y k a) color
18% n			new list
19% f			list is a filled polygon
20% s			list is a group
21% cl			list is a clip list (clip with old clip list and use it)
22% gs			save current clip list and width to top of stack
23% gr			use last clip list (on top of stack) and width
24% # # # # # # # # # #	(x y a b c d e f text font) text
25%
26% Adapted for Scribus by Franz Schmid 15.05.2004
27% Also removed the hardcoded Output Filename
28% and changed it in a way the -sOutputFile Option of Ghostscript can be used
29% Speeded up the flattening of Text by removing unneeded calculations.
30% Changed the Output slightly to ease parsing
31% m                 moveto
32% l # # # #         (x0 y0 x1 y1) line
33% c # # # # # # # # (x0 y0 x1 y1 x2 y2 x3 y3) curve
34% w #               (width) Linewidth
35% co # # # # #      (c m y k a) color
36% n                 new list
37% f                 list is a filled polygon
38% s                 list is a stroke path
39% cp                close current subpath
40% ci                list is a clip list (clip with old clip list and use it)
41% sp                end of page
42% lj #              linejoin
43% lc #              linecap
44% ld # # #n         linedash count offset d1, d2, dx
45% im #              image <name>
46% pat # #           makepattern params tmpfilename
47% mask				imagemask, followed by b/w image
48% fill-evenodd		set fill rule
49% fill-winding		- " -
50% 15.05.2004 Added the Glyphshow Operator.
51% 17.05.2004 Made clipping working.
52% 20.05.2004 kshow is working now.
53% 22.02.2006 added image and colorimage ops -- av
54% 02.03.2006 added code to divide reported coordinates by (device resolution/72) -- av
55% 23.03.2006 added code to trace PDF commands
56
57% some hacks to get access to PDF operators, needs -sDELAYBIND
58
59currentglobal true setglobal
60GS_PDF_ProcSet begin
61currentdict /setshowstate
62{
63	dup WordSpacing 0 32 TextSpacing 0 6 -1 roll awidthshow
64	//setshowstate exec
65} .forceput
66currentdict /endpage {
67	(sp\n) print
68	//endpage exec
69} .forceput
70currentdict /doimage known not {
71	currentdict /doimage { } .forceput
72} if
73currentdict /doimage {
74	currentdict i_image
75	//doimage exec
76} .forceput
77end
78setglobal
79.bindnow
80
81/cfile TraceFile (w) file def
82/print { cfile exch writestring } bind def
83
84
85/==write  % any ==write -
86{
87	dup type dup /arraytype eq exch /packedarraytype eq or
88	{
89		i_file ([) writestring
90			{ ==write i_file ( ) writestring } forall
91		i_file (]) writestring
92	} {
93	dup type /nametype eq
94	{
95		i_file (/) writestring i_file exch i_str cvs writestring
96	} {
97	dup type /stringtype eq
98	{
99		true 1 index { 32 ge and } forall
100		{
101			i_file (\() writestring i_file exch writestring i_file (\)) writestring
102		}
103		{
104			i_file (<) writestring
105			i_file /ASCIIHexEncode filter dup
106			3 -1 roll
107			writestring closefile % close filter
108			i_file (\n) writestring
109		} ifelse
110	} {
111	dup type /dicttype eq
112	{
113		i_file (<<) writestring
114		{ ==write ( ) =write ==write (\n) =write } forall
115		i_file (>>) writestring
116	} {
117		i_file exch i_str cvs
118		dup dup length 1 sub get (-) 0 get eq { pop (null) } if
119		writestring
120	} ifelse } ifelse } ifelse } ifelse
121} def
122
123/=write  % any =write -
124{
125	dup type dup /arraytype eq exch /packedarraytype eq or
126	{
127			{ =write i_file ( ) writestring } forall
128	} {
129	dup type /nametype eq
130	{
131		i_file exch i_str cvs writestring
132	} {
133	dup type /stringtype eq
134	{
135		i_file exch writestring
136	} {
137	dup type /dicttype eq
138	{
139		i_file (<<) writestring
140		{ =write ( ) =write =write (\n) =write } forall
141		i_file (>>) writestring
142	} {
143		i_file exch i_str cvs writestring
144	} ifelse } ifelse } ifelse } ifelse
145} def
146
147
148% flag to deactivate our substitutions
149/i_shortcut false def
150
151% defines an overloaded function     name proc i_shortcutOverload -
152% equvalent to /name { i_shortcut { //name } { proc } ifelse } bind def
153/i_shortcutOverload
154{
155	[ /i_shortcut /load load [ 5 index load ] cvx 4 index /ifelse load ] cvx
156	exch pop
157	bind def
158} def
159
160% whether we have to flatten the text
161/flattenText 1 def
162
163% is a Clipping there
164/clipCnt 0 def
165
166% remember the current point
167/currentX 0 def
168/currentY 0 def
169
170% 1st point of path to close the path
171/beginX 0 def
172/beginY 0 def
173
174% dummy for converting strings
175/i_str 50 string def
176
177% 0 = mirror at
178/mirror 0 def
179
180% mirror a at 0
181/mir
182{
183	mirror 0 ne
184	{	0 exch sub
185	}if
186} bind def
187
188% scale
189
190currentpagedevice /HWResolution get aload pop
19172 div /i_vscale exch def
19272 div /i_hscale exch def
193
194/m_a 1 def
195/m_b 0 def
196/m_c 0 def
197/m_d 1 def
198/m_x 0 def
199/m_y 0 def
200/matrix_x	% x y
201{
202	% ax + cy + tx
203	m_c mul exch m_a mul add m_x add i_hscale div
204} bind def
205/matrix_y	% x y
206{
207	% bx + dy + ty
208	m_d mul exch m_b mul add m_y add i_vscale div
209} bind def
210
211
212/concatenate   % str1 str2 concatenate str12
213{
214	dup length 2 index length add string
215	dup 3 index length 3 index putinterval
216	dup 0 4 index putinterval
217	exch pop exch pop
218} bind def
219
220% this is like search but returns the last match in string
221/rsearch	% string seek  rsearch  post match pre true // string false
222{
223	2 copy search	% string seek post1 match1 pre1 true
224	{
225		2 index 4 index rsearch		% string seek post1 match1 pre1 post2 match2 pre2 true
226		{
227			6 -1 roll pop			% string seek match1 pre1 post2 match2 pre2
228			% combine (pre1 match1 pre2) into one string
229			5 -1 roll exch concatenate	% string seek pre1 post2 match2 (match1+pre2)
230			4 -1 roll exch concatenate	% string seek post2 match2 (pre1+match1+pre2)
231		} {		% string seek post1 match1 pre1 post1
232			pop
233		} ifelse
234		% string seek post match pre
235		5 -2 roll pop pop
236		true
237	} {		% string seek string
238		pop pop false
239	} ifelse
240} bind def
241
242
243% returns a unique filename for the given extension
244/i_exportfilename   % string i_exportfilename string
245{
246	/ExportFiles where { /ExportFiles get (.) rsearch { exch pop exch pop } if } { (imagefile) } ifelse
247	    (-) concatenate dup /i_basename exch def i_filecount 9 string cvs concatenate
248		{
249			i_filecount 1 add /i_filecount exch store
250			dup 2 index concatenate status not { exit } if
251			pop pop pop pop pop
252			i_basename i_filecount 9 string cvs concatenate
253		} loop
254	exch pop
255} bind def
256
257% Code for reading patters is currently commented out, as it
258% doesn't seem to work correctly.
259% /makepattern { % dict matrix  makepattern patterndict
260% %/makepattern =
261% 	% we will do some real painting here:
262% 	/i_shortcut true store
263% 	% params:
264% 	/i_m exch def
265% 	/i_dict exch def
266% 	% define export filename
267% 	/i_basename (.png) i_exportfilename (.png) concatenate def
268% 	i_dict /BBox get
269% 		dup 0 get /i_x exch def
270% 		dup 1 get /i_y exch def
271% 		dup 2 get i_x sub /i_w exch def
272% 		3 get i_y sub /i_h exch def
273% 	% we want those in devspace:
274% 		i_x i_y i_m itransform matrix currentmatrix transform
275% 			i_vscale div /i_y exch def i_hscale div /i_x exch def
276% 		i_w i_h i_m idtransform matrix currentmatrix dtransform
277% 			i_vscale div /i_h exch def i_hscale div /i_w exch def
278% 		% i_h < 0 ?
279% 		i_h 0 le
280% 		{
281% 			/i_y i_h i_y add def
282% 			/i_h i_h neg def
283% 		} if
284% 		% i_w < 0 ?
285% 		i_w 0 le
286% 		{
287% 			/i_x i_w i_x add def
288% 			/i_w i_w neg def
289% 		} if
290% 	% now we can use the current matrix as pattern matrix, but with (0,0) origin
291% 	i_m ==
292% 	i_x i_y matrix currentmatrix translate /i_m exch def
293% 	i_m ==
294% 	i_dict /BBox [ 0 0 i_w i_h ] put
295% 	(w x h =) = i_w = i_h =
296% 	% paint pattern to png file
297% 	gsave
298% 	currentcolor currentcolorspace
299% 	<<
300% 		/OutputFile i_basename
301% 		/OutputDevice (pngalpha)
302% 		/TextAlphaBits 4
303% 		/GraphicsAlphaBits 4
304% %		/BackgroundColor 16777215
305% %		/BackgroundColor 0
306% 		/PageUsesTransparency true
307% 		/HWResolution [ 72 72 ]
308% 		/ProcessColorModel /DeviceRGB
309% 		/PageSize [i_w i_h]
310% 	/pngalpha finddevice putdeviceprops setdevice
311% 	setcolorspace setcolor
312% %	matrix currentmatrix ==
313% %	0 0 transform exch = =
314% %	1 1 transform exch = =
315% 	i_dict i_w i_h matrix identmatrix scale
316% 			%matrix identmatrix
317% 			//makepattern setpattern
318% 	0 0 i_w i_h rectfill
319% 	showpage
320% 	grestore
321% 	% create pattern with our extensions:
322% 	i_dict dup /ExportFile i_basename put
323% 	dup /Origin [ 0 0 transform ] put
324% 	i_m //makepattern
325% 	/i_shortcut false store
326% %/makepatternE =
327% } i_shortcutOverload
328
329/writecurrentpattern
330{
331	currentcolor
332	(pat ) print
333	dup /Origin get
334	dup 0 get i_hscale div i_str cvs print ( ) print
335	    1 get i_vscale div i_str cvs print ( ) print
336	/ExportFile get print
337	(\n) print
338} bind def
339
340/writecurrentcmykcolor
341{
342	currentcmykcolor	% -> c m y k
343	(co )print
344	3 index i_str cvs print
345	( ) print
346	2 index i_str cvs print
347	( ) print
348	1 index i_str cvs print
349	( ) print
350	i_str cvs print
351	( ) print
352	pop pop pop
353	.currentopacityalpha	% a
354	i_str cvs print
355	(\n) print
356} bind def
357
358
359/writecurrentrgbcolor
360{
361	currentrgbcolor	% -> r g b
362	(corgb )print
363	2 index i_str cvs print
364	( ) print
365	1 index i_str cvs print
366	( ) print
367	i_str cvs print
368	( ) print
369	pop pop
370	.currentopacityalpha	% a
371	i_str cvs print
372	(\n) print
373} bind def
374
375
376/writecurrentcolor
377{
378	currentcolorspace 0 get
379
380	% try to find a base colorspace first
381	dup	/Indexed eq
382	{
383		pop
384		currentcolorspace 1 get
385		dup type /arraytype eq { 0 get } if
386	} if
387
388	dup dup /DeviceN eq exch /Separation eq or
389	{
390		pop
391		currentcolorspace 2 get
392		dup type /arraytype eq { 0 get } if
393	} if
394
395	% now write values
396	dup /CIEBasedABC eq
397	{ % this must be a hack....
398		gsave
399		currentcolor setrgbcolor
400		writecurrentrgbcolor
401		grestore
402	} {
403 	dup /DeviceRGB eq
404	{
405		writecurrentrgbcolor
406	} {
407	dup dup /DeviceCMYK eq exch /DeviceGray eq or
408	{
409		writecurrentcmykcolor
410	} {
411	dup /Pattern eq
412	{
413		writecurrentpattern
414	} {
415		% TODO: other CIE
416		writecurrentrgbcolor % will always be 0
417	}
418	ifelse } ifelse } ifelse } ifelse
419	pop
420} bind def
421
422/writecurrentlinecap
423{
424	(lc ) print
425	currentlinecap i_str cvs print
426	(\n) print
427} bind def
428
429/writecurrentlinejoin
430{
431	(lj ) print
432	currentlinejoin i_str cvs print
433	(\n) print
434} bind def
435
436/writecurrentdash
437{
438	(ld ) print
439	currentdash 1 index length i_str cvs print ( ) print i_str cvs print ( ) print
440	0 1 2 index length 1 sub
441	{
442		1 index exch get
443		storeMatrix
444		dup dup dup m_b abs mul exch m_d abs mul add  exch m_a abs mul add  exch m_c abs mul add  2 div  abs
445		i_hscale div
446		i_str cvs print ( ) print
447	} for
448	pop
449	(\n) print
450} bind def
451
452/writecurrentlinewidth
453{
454	userdict begin
455	currentlinewidth	% w
456	storeMatrix
457
458	% (wb + wd + wa + wc) / 2
459%??
460	dup dup dup m_b abs mul exch m_d abs mul add  exch m_a abs mul add  exch m_c abs mul add  2 div  abs
461	i_hscale div
462	% transform (w,w) and take length
463%av-test:	dup dtransform i_vscale div dup mul exch i_hscale div dup mul add sqrt
464	(w ) print
465	i_str cvs print
466	(\n) print
467	end
468} bind def
469
470/i_move	% x y
471{
472	userdict begin
473	(m\n) print
474	/currentY exch def
475	/currentX exch def
476	/beginX currentX def
477	/beginY currentY def
478	end
479} bind def
480
481/i_line
482{
483	userdict begin
484	/y1 exch def
485	/x1 exch def
486
487	% x x1 ne y y1 ne or
488	currentX x1 sub abs 0.001 gt  currentY y1 sub abs 0.001 gt or
489	{
490		(l ) print
491		currentX currentY matrix_x i_str cvs print
492		( ) print
493		currentX currentY matrix_y i_str cvs print
494		( ) print
495
496		x1 y1 matrix_x i_str cvs print
497		( ) print
498		x1 y1 matrix_y i_str cvs print
499		(\n) print
500		/currentX x1 def
501		/currentY y1 def
502	}if
503	end
504} bind def
505
506/i_curve
507{
508	userdict begin
509	% x1 y1 x2 y2 x3 y3
510	(c ) print
511	currentX currentY matrix_x i_str cvs print
512	( ) print
513	currentX currentY matrix_y i_str cvs print
514	( ) print
515	5 index 5 index matrix_x i_str cvs print
516	( ) print
517	5 index 5 index matrix_y i_str cvs print
518	( ) print
519	3 index 3 index matrix_x i_str cvs print
520	( ) print
521	3 index 3 index matrix_y i_str cvs print
522	( ) print
523
524	/currentY exch def
525	/currentX exch def
526
527	currentX currentY matrix_x i_str cvs print
528	( ) print
529	currentX currentY matrix_y i_str cvs print
530	(\n)print
531	pop pop pop pop
532	end
533} bind def
534
535% modified: 18.10.96
536/i_close
537{
538	beginX beginY i_line
539	(cp\n) print
540} bind def
541
542/storeMatrix
543{
544	userdict begin
545	matrix currentmatrix
546	dup 0 get /m_a exch def
547	dup 1 get /m_b exch def
548	dup 2 get /m_c exch def
549	dup 3 get /m_d exch def
550	dup 4 get /m_x exch def
551	5 get /m_y exch def
552	end
553} bind def
554
555/pathClipAndClose % this is not nice: closes all open paths & flattens the path :-(
556{
557	clipsave
558	clip				% combine clippath and path
559	newpath clippath	% copy (closed) clippath to path
560	cliprestore
561} bind def
562
563
564% find out if the point is within the clipping area
565/i_in_clip					% x y  i_in_clip  bool
566{
567	gsave
568	newpath clippath
569	infill
570	grestore
571} bind def
572
573
574% find out if two points are within the clipping area
575/i_in_clip2					% x1 y1 x2 y2 i_in_clip  bool1 bool2
576{
577	gsave
578	newpath clippath
579	infill					% x1 y1 bool2
580	3 1 roll				% bool2 x1 y1
581	infill					% bool2 bool1
582	exch
583	grestore
584} bind def
585
586
587/i_clip_move
588{
589	/beginY exch store
590	/beginX exch store
591	/currentX beginX store
592	/currentY beginY store
593	% test if within cliparea
594	currentX currentY i_in_clip
595	{
596		currentX currentY /moveto load
597	} if
598} bind def
599
600
601% find intersection with line x1,y1 -> x2,y2 with clip path.
602% x1,y2 is outside the clip area, x2, y2, x3, y3 inside
603
604/i_find_clip_intersect		% x1 y1 x2 y2  i_find_clip_intersect  x3 y3
605{
606	3 index 2 index sub		% x1 y1 x2 y2 dx
607	3 index 2 index sub		% x1 y1 x2 y2 dx dy
608	gsave
609	newpath clippath
610	{
611		2 div exch 2 div exch				% half interval
612		2 copy abs 0.01 lt exch abs 0.01 lt and
613			{ exit } if						% done
614		2 copy 4 index add exch				% x1 y1 x2 y2 dx dy (y2+dy) dx
615		       5 index add exch				% x1 y1 x2 y2 dx dy (x2+dx) (y2+dy)
616%		/Intersect = 7 index = 6 index = 5 index = 4 index = 3 index = 2 index = 1 index = 0 index =
617		2 copy infill
618		{									% replace x2,y2
619			6 -2 roll pop pop
620			4 2 roll
621		} {
622			8 -2 roll pop pop				% replace x1,y1
623			6 2 roll
624		} ifelse
625	} loop
626	grestore
627	6 -2 roll								% return x2,y2
628	4 { pop } repeat
629} bind def
630
631/i_clip_line
632{
633	/endY exch store
634	/endX exch store
635	currentX currentY endX endY i_in_clip2
636	{ % end in
637		{
638			% both in. just draw it. FIXME check if line leaves cliparea
639			endX endY /lineto load
640		} {
641			% current not in
642			% find new current point
643			currentX currentY endX endY i_find_clip_intersect
644			/moveto load
645			endX endY /lineto load
646		} ifelse
647	} { % end not in
648		{   % current in
649			% find new endpoint
650			endX endY currentX currentY i_find_clip_intersect
651			/lineto load
652		} {
653			% both not in
654			% try to find a point within cliparea
655			currentX currentY endX endY i_find_clip_intersect
656			2 copy i_in_clip
657			{
658				% yeah
659				/moveto load
660				% now find point from other end
661				endX endY currentX currentY i_find_clip_intersect
662				/lineto load
663			} {
664				pop pop
665			} ifelse
666		} ifelse
667	} ifelse
668	/currentX endX store
669	/currentY endY store
670} bind def
671
672
673/pathClipForStroke
674{
675	% only lines
676	flattenpath
677	% create a userpath from currentpath
678	userdict begin
679	/beginX 0 def /beginY 0 def
680	/currentX 0 def /currentY 0 def
681	/endX 0 def /endY 0 def
682	systemdict begin							% some EPS redefine moveto & Co :-(
683	[
684			{ i_clip_move }						% remember last move
685			{ i_clip_line }						% clip lines individually
686			{ 6 {pop} repeat /OOPS = }			% won't happen
687			{ beginX beginY i_clip_line }		% close with line
688		pathforall
689	] cvx
690%	dup ==
691	newpath % uappend % userpaths SUCK!
692	end end
693	exec
694} bind def
695
696/rectfill
697{
698	userdict begin
699	(n\n)print			% start polygon
700	writecurrentcolor
701	writecurrentlinewidth
702	writecurrentlinecap
703	writecurrentlinejoin
704	writecurrentdash
705	storeMatrix
706
707	% x y width height
708	dup type /arraytype ne
709	{
710		/hr exch def
711		/wr exch def
712		/yr exch def
713		/xr exch def
714		xr yr i_move
715		xr wr add yr i_line
716		xr wr add yr hr add i_line
717		xr yr hr add i_line
718		xr yr i_line
719	}
720	% numarray
721	% numstring
722	{
723		/ar exch def
724		0 4 ar length 1 sub
725		{
726			/n exch def
727			ar n get /xr exch def
728			ar n 1 add get /yr exch def
729			ar n 2 add get /wr exch def
730			ar n 3 add get /hr exch def
731			xr yr i_move
732			xr wr add yr i_line
733			xr wr add yr hr add i_line
734			xr yr hr add i_line
735			xr yr i_line
736		} for
737	}ifelse
738	(cp\n)print
739	(f\n)print			% close polygon
740	end
741} i_shortcutOverload
742
743/rectstroke
744{
745	userdict begin
746	(n\n)print			% start rect
747	writecurrentcolor
748	writecurrentlinewidth
749	writecurrentlinecap
750	writecurrentlinejoin
751	writecurrentdash
752	storeMatrix
753
754	% x y width height
755	dup type dup /arraytype ne exch /stringtype ne and
756	{
757		/hr exch def
758		/wr exch def
759		/yr exch def
760		/xr exch def
761		xr yr i_move
762		xr wr add yr i_line
763		xr wr add yr hr add i_line
764		xr yr hr add i_line
765		xr yr i_line
766	}
767	% numarray
768	% numstring
769	{
770		/ar exch def
771		0 4 ar length 1 sub
772		{
773			/n exch def
774			ar n get /xr exch def
775			ar n 1 add get /yr exch def
776			ar n 2 add get /wr exch def
777			ar n 3 add get /hr exch def
778			xr yr i_move
779			xr wr add yr i_line
780			xr wr add yr hr add i_line
781			xr yr hr add i_line
782			xr yr i_line
783		} for
784	}ifelse
785	(cp\n)print
786	(s\n)print			% stroke rect
787	end
788} i_shortcutOverload
789
790/stroke
791{
792	(n\n) print
793	writecurrentcolor
794	writecurrentlinewidth
795	writecurrentlinecap
796	writecurrentlinejoin
797	writecurrentdash
798%	clipCnt 1 eq
799%		{ pathClipForStroke } if
800	storeMatrix
801
802	{i_move} {i_line} {i_curve} {i_close} pathforall
803	(s\n)print			% stroke path
804	newpath
805} i_shortcutOverload
806
807/eofill
808{
809	(n\n) print			% start polygon
810	writecurrentcolor	% write color
811	writecurrentlinewidth
812	writecurrentlinecap
813	writecurrentlinejoin
814	writecurrentdash
815%	clipCnt 1 eq
816%		{ pathClipAndClose } if
817	storeMatrix			% take transformation, scaling, rotation from PostScript
818	{i_move} {i_line} {i_curve} {i_close} pathforall
819	(f\n)print			% close polygon
820
821	newpath				% clear stack
822} i_shortcutOverload
823
824/fill
825{
826	(fill-winding\n) print
827	eofill
828	(fill-evenodd\n) print
829} i_shortcutOverload
830
831/clip
832{
833	userdict begin
834	(n\n)print			% start clip polygon
835
836% FIXME: pathClipAndClose first?
837
838	storeMatrix			% take transformation, scaling, rotation from PostScript
839	{i_move} {i_line} {i_curve} {i_close} pathforall
840
841	(ci\n)print			% close clip polygon begin path
842						% we have to close the path!!
843%	clip
844%	/clipCnt 1 def
845	newpath				% clear stack
846	end
847} i_shortcutOverload
848
849/eoclip
850{
851	userdict begin
852	(n\n)print			% start clip polygon
853
854% FIXME: pathClipAndClose first?
855
856	storeMatrix			% take transformation, scaling, rotation from PostScript
857	{i_move} {i_line} {i_curve} {i_close} pathforall
858
859	(ci\n)print			% close clip polygon begin path
860						% we have to close the path!!
861%	clip
862%	/clipCnt 1 def
863	newpath				% clear stack
864	end
865} i_shortcutOverload
866
867% we don't clip
868% because this doesn't work for flattening text (show, charpath) with NeXT PostScript Code
869/rectclip
870{
871	% let Scribus decide what to do with ci; was: pop pop pop pop
872	userdict begin
873	(n\n)print			% start clip polygon
874
875	storeMatrix			% take transformation, scaling, rotation from PostScript
876	dup type dup /arraytype ne exch /stringtype ne and
877	{
878		4 copy
879		/i_h exch def
880		/i_w exch def
881		/i_y exch def
882		/i_x exch def
883		i_x i_y i_move
884		i_x i_w add i_y i_line
885		i_x i_w add i_y i_h add i_line
886		i_x i_y i_h add i_line
887	} {
888		% array or string
889		0 4 dup length 1 sub
890		{
891			1 index 1 index get /i_x exch def
892			1 add
893			1 index 1 index get /i_y exch def
894			1 add
895			1 index 1 index get /i_w exch def
896			1 add
897			1 index 1 index get /i_y exch def
898			i_x i_y i_move
899			i_x i_w add i_y i_line
900			i_x i_w add i_y i_h add i_line
901			i_x i_y i_h add i_line
902		} for
903	} ifelse
904
905	(ci\n)print			% close clip polygon begin path
906						% we have to close the path!!
907%	rectclip
908%	/clipCnt 1 def
909	newpath				% clear stack
910	end
911} i_shortcutOverload
912
913
914% Code for reading images is currently commented out, as it
915% doesn't seem to work correctly.
916%    Copyright (C) 1994 Aladdin Enterprises.  All rights reserved.
917%
918% This software is provided AS-IS with no warranty, either express or
919% implied.
920%
921% This software is distributed under license and may not be copied,
922% modified or distributed except as expressly authorized under the terms
923% of the license contained in the file LICENSE in this distribution.
924%
925% For more information about licensing, please refer to
926% http://www.ghostscript.com/licensing/. For information on
927% commercial licensing, go to http://www.artifex.com/licensing/ or
928% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
929% San Rafael, CA  94903, U.S.A., +1(415)492-9861.
930
931% $Id: import.prolog 13454 2009-05-08 19:04:32Z jghali $
932% traceimg.ps
933% Trace the data supplied to the 'image' operator.
934
935% This code currently handles only the (Level 2) dictionary form of image,
936% with a single data source and 8-bit pixels.
937
938% changed for Scribus image import by Andreas Vox, 2006-2-21
939% added support for colorimage and other image variant
940
941/i_image			% <dict> i_image -
942{
943%dup { == == } forall
944/i_image =
945	begin
946		/i_left Width Height mul Decode length 2 idiv mul BitsPerComponent mul 8 idiv dup /i_size exch store store
947		/i_dict currentdict store
948		/i_nsources 1 store
949		/i_source 0 store
950		/i_datasource currentdict /DataSource get store
951		currentdict /MultipleDataSources known not
952			{ /MultipleDataSources false def } if
953		MultipleDataSources
954		{
955			/i_nsources  DataSource length store
956			/i_datasource DataSource 0 get store
957		} if
958	end
959	storeMatrix
960	i_dict /ImageMatrix get matrix invertmatrix matrix currentmatrix matrix concatmatrix /i_m exch def
961	i_dict /Width get  0 i_m dtransform dup mul exch dup mul add sqrt /i_w exch def
962	0 i_dict /Height get i_m dtransform dup mul exch dup mul add sqrt /i_h exch def
963	0  0 i_m transform  /i_y exch def /i_x exch def
964	i_dict /Width get i_dict /Height get i_m transform
965	/i_hflip -1 def /i_vflip 1 def
966	dup i_y le { /i_y exch def } { pop /i_vflip -1 def } ifelse
967	dup i_x le { /i_x exch def } { pop /i_hflip  1 def } ifelse
968	0 i_dict /Height get i_m dtransform atan
969	/i_angle exch def
970	(.dat) i_exportfilename
971		(im ) print			% im x y w h angle ...
972		i_x i_hscale div i_str cvs print ( ) print
973		i_y i_vscale div i_str cvs print ( ) print
974		i_w i_hscale div i_str cvs print ( ) print
975		i_h i_vscale div i_str cvs print ( ) print
976		i_angle i_str cvs print ( ) print
977		i_dict /Width get  i_str cvs print ( ) print			% ... hpix vpix ...
978		i_dict /Height get i_str cvs print ( ) print
979		currentcolorspace 0 get /DeviceRGB eq
980			{ (tiff24nc ) print }
981		{ currentcolorspace 0 get /DeviceCMYK eq
982			{ (psdcmyk ) print }
983		{ currentcolorspace 0 get /DeviceGray eq
984			{ (tiffgray ) print }
985			{ (tiff32nc ) print }
986		ifelse } ifelse } ifelse
987        dup  (.tif) concatenate print (\n) print flush			% ... dev filename
988		(.dat) concatenate (w) file /i_file exch store			% temp file
989	currentcolorspace ==write ( setcolorspace\n) =write
990	(<<\n) =write
991	i_dict { exch
992		  dup /DataSource eq
993			{ pop pop (/DataSource currentfile\n) =write }
994		  {
995			dup /ImageMatrix eq
996				{ pop pop (/ImageMatrix [) =write
997					i_hflip ==write ( 0 0 ) =write i_vflip ==write
998					( ) =write
999					i_hflip 0 lt { i_dict /Width get } { 0 } ifelse ==write
1000					( ) =write
1001					i_vflip 0 lt { i_dict /Height get} { 0 } ifelse ==write
1002					(]\n) =write }
1003				{ ==write ( ) =write ==write (\n) =write }
1004			ifelse
1005		  } ifelse
1006		} forall
1007	(>>\nimage\n) =write i_file flushfile
1008
1009    { %loop
1010      i_left 0 le
1011      {
1012		i_source 1 add /i_source exch def
1013        i_source i_nsources ge { exit } if
1014        i_dict /DataSource get i_source get /i_datasource exch def
1015		/i_left i_size def
1016      } if
1017      /i_datasource load exec
1018      dup type /filetype eq
1019       { i_buf 0 i_left 32 .min getinterval readstring pop
1020       } if
1021      dup length 0 eq {pop i_zero 0 i_left 32 .min getinterval} if
1022      dup i_file exch writestring
1023      i_left exch length sub /i_left exch def
1024    } loop
1025    i_file flushfile
1026/i_imageE =
1027 } bind def
1028
1029/colorimage
1030{
1031/colorimage =
1032	% width height bits/sample matrix datasource0..n-1 multi ncomp
1033	/tmpN exch def
1034	/tmpMulti exch def
1035	tmpMulti
1036	{
1037		/tmpN load array astore
1038	} if
1039	/tmpN load 6 add dict
1040	dup 7 -1 roll /Width exch put
1041	dup 6 -1 roll /Height exch put
1042	dup 5 -1 roll /BitsPerComponent exch put
1043	dup 4 -1 roll /ImageMatrix exch put
1044	dup 3 -1 roll /DataSource exch put
1045	tmpMulti
1046	{
1047		dup /MultipleDataSources true put
1048	} if
1049	dup /ImageType 1 put
1050	gsave
1051	/tmpN load
1052		dup 1 eq
1053		{
1054			1 index /Decode [0 1] /Decode put
1055            /DeviceGray setcolorspace
1056		} if
1057		dup 3 eq
1058		{
1059			1 index /Decode [0 1 0 1 0 1] put
1060			/DeviceRGB setcolorspace
1061		} if
1062		dup 4 eq
1063		{
1064			1 index /Decode [0 1 0 1 0 1 0 1]  put
1065			/DeviceCMYK setcolorspace
1066		} if
1067	pop
1068	i_image
1069	grestore
1070/colorimageE =
1071} i_shortcutOverload
1072
1073/image {
1074/image =
1075	gsave
1076	dup type /dicttype ne
1077	{
1078		% width height bits/sample matrix datasource
1079		7 dict
1080		dup 7 -1 roll /Width exch put
1081		dup 6 -1 roll /Height exch put
1082		dup 5 -1 roll /BitsPerComponent  exch put
1083		dup 4 -1 roll /ImageMatrix exch put
1084		dup 3 -1 roll /DataSource exch put
1085		dup 1 /ImageType exch put
1086		dup [0 1] /Decode exch put
1087		/DeviceGray setcolorspace
1088	} if
1089	i_image
1090	grestore
1091/imageE =
1092} i_shortcutOverload
1093
1094/imagemask
1095{
1096/imagemask =
1097	writecurrentcolor
1098	(mask\n) print
1099	gsave
1100	dup type /dicttype ne
1101	{
1102		% width height pol matrix datasource
1103		7 dict
1104		dup 7 -1 roll /Width exch put
1105		dup 6 -1 roll /Height exch put
1106		dup 5 -1 roll { [0 1] } { [1 0] } ifelse /Decode exch put
1107		dup 4 -1 roll /ImageMatrix exch put
1108		dup 3 -1 roll /DataSource exch put
1109	} if
1110	dup 1 /ImageType exch put
1111	dup 1 /BitsPerComponent exch put
1112	/DeviceGray setcolorspace
1113	i_image
1114	grestore
1115/imagemaskE =
1116} i_shortcutOverload
1117
1118
1119% declare some global vars
1120
1121/i_left 0 def
1122/i_size 0 def
1123/i_dict null def
1124/i_buf 32 string def
1125/i_nsources 1 def
1126/i_source 0 def
1127/i_datasource { (x) } def
1128/i_file null def
1129/i_filecount 1 def
1130/i_zero 32 string def
1131
1132%%%% End of traceimage code
1133
1134
1135/stateArray 500 array def
1136/stateTop 0 def
1137/gsave
1138{
1139	(gs\n) print
1140	userdict begin
1141%	(gs\n) print
1142	stateArray stateTop gstate currentgstate put
1143	/stateTop stateTop 1 add def
1144	end
1145} i_shortcutOverload
1146
1147/grestore
1148{
1149	(gr\n) print
1150	userdict begin
1151	stateTop 1 lt
1152	{
1153	}
1154	{
1155%		(gr\n) print
1156		stateArray stateTop 1 sub get setgstate
1157		/stateTop stateTop 1 sub def
1158		stateArray stateTop 0 put
1159	}ifelse
1160	end
1161} i_shortcutOverload
1162
1163/stringwidth
1164{
1165	/i_shortcut true store
1166	stringwidth
1167	/i_shortcut false store
1168} i_shortcutOverload
1169
1170% a bind def of the show operator doesn't work,
1171% so this is our way to get a charpath entry for flattening text
1172/root_charpath
1173{
1174	charpath
1175} bind def
1176
1177/i_kerningI
1178{
1179	exch 1 getinterval stringwidth
1180} bind def
1181
1182% find kerning value
1183/i_kerningII		% index string   i_kerning   dx dy
1184{
1185	% stringwidth( [n..n+1] ) - stringwidth( [n+1] )
1186	/i_pstring exch def
1187	/i_pindex exch def
1188	i_pstring i_pindex 2 getinterval stringwidth exch	% y2 x2
1189	i_pstring i_pindex 1 add 1 getinterval stringwidth		% y2 x2 x1 y1
1190	4 1 roll sub											% y1 y2 (x2-x1)
1191	3 1 roll exch sub										% (x2-x1) (y2-y1)
1192} bind def
1193
1194
1195/i_kerningIII		% index string   i_kerning   dx dy
1196{
1197	% stringwidth( [n..n+1] ) - stringwidth( [n+1] )
1198	/i_pstring exch def
1199	/i_pindex exch def
1200	i_pstring i_pindex 2 getinterval (l) exch concatenate stringwidth exch	% y2 x2
1201	i_pstring i_pindex 1 add 1 getinterval (l) exch concatenate stringwidth		% y2 x2 x1 y1
1202	4 1 roll sub											% y1 y2 (x2-x1)
1203	3 1 roll exch sub										% (x2-x1) (y2-y1)
1204} bind def
1205
1206/i_kerning /i_kerningII load def
1207
1208/show % string show -
1209{
1210	userdict begin
1211	storeMatrix
1212	currentfont /FontName known
1213	% stack: string
1214	{
1215		currentfont /FontType get dup 3 eq exch 0 eq or
1216		{
1217			currentpoint /ycur exch def /xcur exch def
1218			currentpoint	% x y
1219			newpath
1220			/clipCnt 0 def
1221			moveto
1222			(n\n)print			% start polygon
1223			writecurrentcolor	% write color
1224			storeMatrix
1225			dup
1226			stringwidth
1227			/curwidthy exch def /curwidthx exch def
1228			false root_charpath
1229			{i_move} {i_line} {i_curve} {i_close} pathforall
1230			(f\n)print			% close polygon
1231			newpath
1232			curwidthx xcur add curwidthy ycur add moveto
1233			currentpoint /ycur exch def /xcur exch def
1234			newpath			% clear graphic stack
1235			xcur ycur moveto
1236		}
1237		{
1238			currentpoint /ycur exch def /xcur exch def
1239			currentpoint	% x y
1240			newpath
1241			/clipCnt 0 def
1242			moveto
1243			/completeString exch def
1244			% we process each char separately to get smaller paths
1245			0 1 completeString length 1 sub
1246			{
1247				(n\n)print			% start polygon
1248				writecurrentcolor	% write color
1249				storeMatrix
1250				dup completeString length 1 sub eq
1251				{ dup completeString exch 1 getinterval stringwidth }
1252				{ dup completeString i_kerning } ifelse
1253				/curwidthy exch def /curwidthx exch def
1254				completeString exch 1 getinterval dup /curstr exch def
1255				false root_charpath
1256				{i_move} {i_line} {i_curve} {i_close} pathforall
1257				(f\n)print			% close polygon
1258				newpath
1259				curwidthx xcur add curwidthy ycur add moveto
1260				currentpoint /ycur exch def /xcur exch def
1261				newpath			% clear graphic stack
1262				xcur ycur moveto
1263			} for
1264			currentpoint	% x y
1265			newpath				% clear graphic stack (and current point)
1266			moveto
1267		} ifelse
1268	}
1269	{
1270		currentfont /FontType known
1271		{
1272			currentfont /FontType get dup 3 eq exch 0 eq or
1273			{
1274				currentpoint /ycur exch def /xcur exch def
1275				currentpoint	% x y
1276				newpath
1277				/clipCnt 0 def
1278				moveto
1279				(n\n)print			% start polygon
1280				writecurrentcolor	% write color
1281				storeMatrix
1282				dup
1283				stringwidth
1284				/curwidthy exch def /curwidthx exch def
1285				false root_charpath
1286				{i_move} {i_line} {i_curve} {i_close} pathforall
1287				(f\n)print			% close polygon
1288				newpath
1289				curwidthx xcur add curwidthy ycur add moveto
1290				currentpoint /ycur exch def /xcur exch def
1291				newpath			% clear graphic stack
1292				xcur ycur moveto
1293			}
1294			{
1295				pop
1296			} ifelse
1297		}
1298		{
1299			pop
1300		} ifelse
1301	} ifelse
1302	end
1303} i_shortcutOverload
1304
1305/ashow
1306{
1307	% ax ay string
1308	exch /ydist exch def
1309	exch /xdist exch def
1310	userdict begin
1311	storeMatrix
1312	currentfont /FontName known
1313	% stack: string
1314	{
1315		currentpoint /ycur exch def /xcur exch def
1316		currentpoint	% x y
1317		newpath
1318		/clipCnt 0 def
1319		moveto
1320		/completeString exch def
1321		% we process each char separately to get smaller paths
1322		0 1 completeString length 1 sub
1323		{
1324			(n\n)print			% start polygon
1325			writecurrentcolor	% write color
1326			storeMatrix
1327			dup completeString length 1 sub eq
1328			{ dup completeString exch 1 getinterval stringwidth }
1329			{ dup completeString i_kerning } ifelse
1330			/curwidthy exch def /curwidthx exch def
1331			completeString exch 1 getinterval dup /curstr exch def
1332			false root_charpath
1333			{i_move} {i_line} {i_curve} {i_close} pathforall
1334			(f\n)print			% close polygon
1335			newpath
1336			curwidthx xcur add curwidthy ycur add
1337			exch xdist add exch ydist add moveto
1338			currentpoint /ycur exch def /xcur exch def
1339			newpath			% clear graphic stack
1340			xcur ycur moveto
1341		} for
1342		currentpoint	% x y
1343		newpath				% clear graphic stack (and current point)
1344		moveto
1345	} {
1346		pop
1347	} ifelse
1348	end
1349} i_shortcutOverload
1350
1351/awidthshow		% cx cy char ax ay string
1352{
1353	% ax ay string
1354	exch /ydist exch def
1355	exch /xdist exch def
1356	% cx cy char string
1357	exch /char exch def
1358	exch /cydist exch def
1359	exch /cxdist exch def
1360	userdict begin
1361	storeMatrix
1362	currentfont /FontName known
1363	% stack: string
1364	{
1365		currentpoint /ycur exch def /xcur exch def
1366		currentpoint	% x y
1367		newpath
1368		/clipCnt 0 def
1369		moveto
1370		/completeString exch def
1371		% we process each char separately to get smaller paths
1372		0 1 completeString length 1 sub
1373		{
1374			(n\n)print			% start polygon
1375			writecurrentcolor	% write color
1376			storeMatrix
1377			dup completeString length 1 sub eq
1378			{ dup completeString exch 1 getinterval stringwidth }
1379			{ dup completeString i_kerning } ifelse
1380			/curwidthy exch def /curwidthx exch def
1381			completeString exch 1 getinterval dup /curstr exch def
1382			false root_charpath
1383			{i_move} {i_line} {i_curve} {i_close} pathforall
1384			(f\n)print			% close polygon
1385			newpath
1386			curwidthx xcur add curwidthy ycur add
1387			exch xdist add exch ydist add moveto
1388			curstr 0 get char eq
1389			{
1390				currentpoint exch cxdist add exch cydist add moveto
1391			} if
1392			currentpoint /ycur exch def /xcur exch def
1393			newpath			% clear graphic stack
1394			xcur ycur moveto
1395		} for
1396		currentpoint	% x y
1397		newpath				% clear graphic stack (and current point)
1398		moveto
1399	} {
1400		pop
1401	} ifelse
1402	end
1403} i_shortcutOverload
1404
1405/widthshow	% cx cy char string
1406{
1407	0 exch
1408	0 exch
1409	awidthshow
1410} bind def
1411
1412%/cshow	% proc string
1413%{
1414%	exch pop
1415%	show
1416%} i_shortcutOverload
1417
1418/kshow	% proc string
1419{
1420	dup length 1 sub
1421	dup 0 ne
1422	{
1423		1 index 0 1 getinterval
1424		show
1425		1 sub
1426		dup 0 ne
1427		{
1428			1 add
1429			1 exch 1 exch
1430			{
1431				dup 1 sub
1432				2 index exch get
1433				2 index 2 index get
1434				4 index exec
1435				1 index exch 1 getinterval
1436				show
1437			} for
1438		} if
1439	}
1440	{
1441		pop dup show
1442	} ifelse
1443	pop pop
1444} i_shortcutOverload
1445
1446/xshow	% string array
1447{
1448	pop %FIXME
1449	show
1450} i_shortcutOverload
1451
1452/xyshow	% string array
1453{
1454	pop %FIXME
1455	show
1456} i_shortcutOverload
1457
1458/yshow	% string array
1459{
1460	pop %FIXME
1461	show
1462} i_shortcutOverload
1463
1464/i_reencode % newfontname reencodevector origfontdict -> i_reencode -> newfontdict
1465{
1466	userdict begin
1467 dup begin dup maxlength dict begin
1468  { 1 index /FID ne {def} {pop pop} ifelse
1469  } forall
1470  /Encoding exch def
1471  currentdict
1472  end end
1473  definefont
1474	end
1475} bind def
1476
1477/glyphshow {
1478    save % So can reclaim VM from reencoding
1479    currentfont /Encoding get dup length array copy dup 0 5 -1 roll put
1480    /GlyphShowTempFont exch currentfont i_reencode
1481    setfont
1482    (\000) show
1483	currentpoint 3 -1 roll % curx cury -save-
1484	restore
1485	newpath
1486	moveto
1487} i_shortcutOverload
1488
1489/showpage
1490{
1491	(sp\n) print
1492} i_shortcutOverload
1493
1494
1495