% % psi.prolog % % Copyright (C) 1996-2000 by vhf computer GmbH + vhf interservice GmbH % Author: Georg Fleischmann % % created: 2000-09-09 % modified: % %%% this file also contains a section taken from GPL Ghostscript 8.50 "traceimg.ps", see below % this PostScript code writes a file with the structure below. % # # # # l (x0 y0 x1 y1) line % # # # # # # # #c (x0 y0 x1 y1 x2 y2 x3 y3) curve % # w (width) width % # # # # # co (c m y k a) color % n new list % f list is a filled polygon % s list is a group % cl list is a clip list (clip with old clip list and use it) % gs save current clip list and width to top of stack % gr use last clip list (on top of stack) and width % # # # # # # # # # # (x y a b c d e f text font) text % % Adapted for Scribus by Franz Schmid 15.05.2004 % Also removed the hardcoded Output Filename % and changed it in a way the -sOutputFile Option of Ghostscript can be used % Speeded up the flattening of Text by removing unneeded calculations. % Changed the Output slightly to ease parsing % m moveto % l # # # # (x0 y0 x1 y1) line % c # # # # # # # # (x0 y0 x1 y1 x2 y2 x3 y3) curve % w # (width) Linewidth % co # # # # # (c m y k a) color % n new list % f list is a filled polygon % s list is a stroke path % cp close current subpath % ci list is a clip list (clip with old clip list and use it) % sp end of page % lj # linejoin % lc # linecap % ld # # #n linedash count offset d1, d2, dx % im # image % pat # # makepattern params tmpfilename % mask imagemask, followed by b/w image % fill-evenodd set fill rule % fill-winding - " - % 15.05.2004 Added the Glyphshow Operator. % 17.05.2004 Made clipping working. % 20.05.2004 kshow is working now. % 22.02.2006 added image and colorimage ops -- av % 02.03.2006 added code to divide reported coordinates by (device resolution/72) -- av % 23.03.2006 added code to trace PDF commands % some hacks to get access to PDF operators, needs -sDELAYBIND currentglobal true setglobal GS_PDF_ProcSet begin currentdict /setshowstate { dup WordSpacing 0 32 TextSpacing 0 6 -1 roll awidthshow //setshowstate exec } .forceput currentdict /endpage { (sp\n) print //endpage exec } .forceput currentdict /doimage known not { currentdict /doimage { } .forceput } if currentdict /doimage { currentdict i_image //doimage exec } .forceput end setglobal .bindnow /cfile TraceFile (w) file def /print { cfile exch writestring } bind def /==write % any ==write - { dup type dup /arraytype eq exch /packedarraytype eq or { i_file ([) writestring { ==write i_file ( ) writestring } forall i_file (]) writestring } { dup type /nametype eq { i_file (/) writestring i_file exch i_str cvs writestring } { dup type /stringtype eq { true 1 index { 32 ge and } forall { i_file (\() writestring i_file exch writestring i_file (\)) writestring } { i_file (<) writestring i_file /ASCIIHexEncode filter dup 3 -1 roll writestring closefile % close filter i_file (\n) writestring } ifelse } { dup type /dicttype eq { i_file (<<) writestring { ==write ( ) =write ==write (\n) =write } forall i_file (>>) writestring } { i_file exch i_str cvs dup dup length 1 sub get (-) 0 get eq { pop (null) } if writestring } ifelse } ifelse } ifelse } ifelse } def /=write % any =write - { dup type dup /arraytype eq exch /packedarraytype eq or { { =write i_file ( ) writestring } forall } { dup type /nametype eq { i_file exch i_str cvs writestring } { dup type /stringtype eq { i_file exch writestring } { dup type /dicttype eq { i_file (<<) writestring { =write ( ) =write =write (\n) =write } forall i_file (>>) writestring } { i_file exch i_str cvs writestring } ifelse } ifelse } ifelse } ifelse } def % flag to deactivate our substitutions /i_shortcut false def % defines an overloaded function name proc i_shortcutOverload - % equvalent to /name { i_shortcut { //name } { proc } ifelse } bind def /i_shortcutOverload { [ /i_shortcut /load load [ 5 index load ] cvx 4 index /ifelse load ] cvx exch pop bind def } def % whether we have to flatten the text /flattenText 1 def % is a Clipping there /clipCnt 0 def % remember the current point /currentX 0 def /currentY 0 def % 1st point of path to close the path /beginX 0 def /beginY 0 def % dummy for converting strings /i_str 50 string def % 0 = mirror at /mirror 0 def % mirror a at 0 /mir { mirror 0 ne { 0 exch sub }if } bind def % scale currentpagedevice /HWResolution get aload pop 72 div /i_vscale exch def 72 div /i_hscale exch def /m_a 1 def /m_b 0 def /m_c 0 def /m_d 1 def /m_x 0 def /m_y 0 def /matrix_x % x y { % ax + cy + tx m_c mul exch m_a mul add m_x add i_hscale div } bind def /matrix_y % x y { % bx + dy + ty m_d mul exch m_b mul add m_y add i_vscale div } bind def /concatenate % str1 str2 concatenate str12 { dup length 2 index length add string dup 3 index length 3 index putinterval dup 0 4 index putinterval exch pop exch pop } bind def % this is like search but returns the last match in string /rsearch % string seek rsearch post match pre true // string false { 2 copy search % string seek post1 match1 pre1 true { 2 index 4 index rsearch % string seek post1 match1 pre1 post2 match2 pre2 true { 6 -1 roll pop % string seek match1 pre1 post2 match2 pre2 % combine (pre1 match1 pre2) into one string 5 -1 roll exch concatenate % string seek pre1 post2 match2 (match1+pre2) 4 -1 roll exch concatenate % string seek post2 match2 (pre1+match1+pre2) } { % string seek post1 match1 pre1 post1 pop } ifelse % string seek post match pre 5 -2 roll pop pop true } { % string seek string pop pop false } ifelse } bind def % returns a unique filename for the given extension /i_exportfilename % string i_exportfilename string { /ExportFiles where { /ExportFiles get (.) rsearch { exch pop exch pop } if } { (imagefile) } ifelse (-) concatenate dup /i_basename exch def i_filecount 9 string cvs concatenate { i_filecount 1 add /i_filecount exch store dup 2 index concatenate status not { exit } if pop pop pop pop pop i_basename i_filecount 9 string cvs concatenate } loop exch pop } bind def % Code for reading patters is currently commented out, as it % doesn't seem to work correctly. % /makepattern { % dict matrix makepattern patterndict % %/makepattern = % % we will do some real painting here: % /i_shortcut true store % % params: % /i_m exch def % /i_dict exch def % % define export filename % /i_basename (.png) i_exportfilename (.png) concatenate def % i_dict /BBox get % dup 0 get /i_x exch def % dup 1 get /i_y exch def % dup 2 get i_x sub /i_w exch def % 3 get i_y sub /i_h exch def % % we want those in devspace: % i_x i_y i_m itransform matrix currentmatrix transform % i_vscale div /i_y exch def i_hscale div /i_x exch def % i_w i_h i_m idtransform matrix currentmatrix dtransform % i_vscale div /i_h exch def i_hscale div /i_w exch def % % i_h < 0 ? % i_h 0 le % { % /i_y i_h i_y add def % /i_h i_h neg def % } if % % i_w < 0 ? % i_w 0 le % { % /i_x i_w i_x add def % /i_w i_w neg def % } if % % now we can use the current matrix as pattern matrix, but with (0,0) origin % i_m == % i_x i_y matrix currentmatrix translate /i_m exch def % i_m == % i_dict /BBox [ 0 0 i_w i_h ] put % (w x h =) = i_w = i_h = % % paint pattern to png file % gsave % currentcolor currentcolorspace % << % /OutputFile i_basename % /OutputDevice (pngalpha) % /TextAlphaBits 4 % /GraphicsAlphaBits 4 % % /BackgroundColor 16777215 % % /BackgroundColor 0 % /PageUsesTransparency true % /HWResolution [ 72 72 ] % /ProcessColorModel /DeviceRGB % /PageSize [i_w i_h] % /pngalpha finddevice putdeviceprops setdevice % setcolorspace setcolor % % matrix currentmatrix == % % 0 0 transform exch = = % % 1 1 transform exch = = % i_dict i_w i_h matrix identmatrix scale % %matrix identmatrix % //makepattern setpattern % 0 0 i_w i_h rectfill % showpage % grestore % % create pattern with our extensions: % i_dict dup /ExportFile i_basename put % dup /Origin [ 0 0 transform ] put % i_m //makepattern % /i_shortcut false store % %/makepatternE = % } i_shortcutOverload /writecurrentpattern { currentcolor (pat ) print dup /Origin get dup 0 get i_hscale div i_str cvs print ( ) print 1 get i_vscale div i_str cvs print ( ) print /ExportFile get print (\n) print } bind def /writecurrentcmykcolor { currentcmykcolor % -> c m y k (co )print 3 index i_str cvs print ( ) print 2 index i_str cvs print ( ) print 1 index i_str cvs print ( ) print i_str cvs print ( ) print pop pop pop .currentopacityalpha % a i_str cvs print (\n) print } bind def /writecurrentrgbcolor { currentrgbcolor % -> r g b (corgb )print 2 index i_str cvs print ( ) print 1 index i_str cvs print ( ) print i_str cvs print ( ) print pop pop .currentopacityalpha % a i_str cvs print (\n) print } bind def /writecurrentcolor { currentcolorspace 0 get % try to find a base colorspace first dup /Indexed eq { pop currentcolorspace 1 get dup type /arraytype eq { 0 get } if } if dup dup /DeviceN eq exch /Separation eq or { pop currentcolorspace 2 get dup type /arraytype eq { 0 get } if } if % now write values dup /CIEBasedABC eq { % this must be a hack.... gsave currentcolor setrgbcolor writecurrentrgbcolor grestore } { dup /DeviceRGB eq { writecurrentrgbcolor } { dup dup /DeviceCMYK eq exch /DeviceGray eq or { writecurrentcmykcolor } { dup /Pattern eq { writecurrentpattern } { % TODO: other CIE writecurrentrgbcolor % will always be 0 } ifelse } ifelse } ifelse } ifelse pop } bind def /writecurrentlinecap { (lc ) print currentlinecap i_str cvs print (\n) print } bind def /writecurrentlinejoin { (lj ) print currentlinejoin i_str cvs print (\n) print } bind def /writecurrentdash { (ld ) print currentdash 1 index length i_str cvs print ( ) print i_str cvs print ( ) print 0 1 2 index length 1 sub { 1 index exch get storeMatrix 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 i_hscale div i_str cvs print ( ) print } for pop (\n) print } bind def /writecurrentlinewidth { userdict begin currentlinewidth % w storeMatrix % (wb + wd + wa + wc) / 2 %?? 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 i_hscale div % transform (w,w) and take length %av-test: dup dtransform i_vscale div dup mul exch i_hscale div dup mul add sqrt (w ) print i_str cvs print (\n) print end } bind def /i_move % x y { userdict begin (m\n) print /currentY exch def /currentX exch def /beginX currentX def /beginY currentY def end } bind def /i_line { userdict begin /y1 exch def /x1 exch def % x x1 ne y y1 ne or currentX x1 sub abs 0.001 gt currentY y1 sub abs 0.001 gt or { (l ) print currentX currentY matrix_x i_str cvs print ( ) print currentX currentY matrix_y i_str cvs print ( ) print x1 y1 matrix_x i_str cvs print ( ) print x1 y1 matrix_y i_str cvs print (\n) print /currentX x1 def /currentY y1 def }if end } bind def /i_curve { userdict begin % x1 y1 x2 y2 x3 y3 (c ) print currentX currentY matrix_x i_str cvs print ( ) print currentX currentY matrix_y i_str cvs print ( ) print 5 index 5 index matrix_x i_str cvs print ( ) print 5 index 5 index matrix_y i_str cvs print ( ) print 3 index 3 index matrix_x i_str cvs print ( ) print 3 index 3 index matrix_y i_str cvs print ( ) print /currentY exch def /currentX exch def currentX currentY matrix_x i_str cvs print ( ) print currentX currentY matrix_y i_str cvs print (\n)print pop pop pop pop end } bind def % modified: 18.10.96 /i_close { beginX beginY i_line (cp\n) print } bind def /storeMatrix { userdict begin matrix currentmatrix dup 0 get /m_a exch def dup 1 get /m_b exch def dup 2 get /m_c exch def dup 3 get /m_d exch def dup 4 get /m_x exch def 5 get /m_y exch def end } bind def /pathClipAndClose % this is not nice: closes all open paths & flattens the path :-( { clipsave clip % combine clippath and path newpath clippath % copy (closed) clippath to path cliprestore } bind def % find out if the point is within the clipping area /i_in_clip % x y i_in_clip bool { gsave newpath clippath infill grestore } bind def % find out if two points are within the clipping area /i_in_clip2 % x1 y1 x2 y2 i_in_clip bool1 bool2 { gsave newpath clippath infill % x1 y1 bool2 3 1 roll % bool2 x1 y1 infill % bool2 bool1 exch grestore } bind def /i_clip_move { /beginY exch store /beginX exch store /currentX beginX store /currentY beginY store % test if within cliparea currentX currentY i_in_clip { currentX currentY /moveto load } if } bind def % find intersection with line x1,y1 -> x2,y2 with clip path. % x1,y2 is outside the clip area, x2, y2, x3, y3 inside /i_find_clip_intersect % x1 y1 x2 y2 i_find_clip_intersect x3 y3 { 3 index 2 index sub % x1 y1 x2 y2 dx 3 index 2 index sub % x1 y1 x2 y2 dx dy gsave newpath clippath { 2 div exch 2 div exch % half interval 2 copy abs 0.01 lt exch abs 0.01 lt and { exit } if % done 2 copy 4 index add exch % x1 y1 x2 y2 dx dy (y2+dy) dx 5 index add exch % x1 y1 x2 y2 dx dy (x2+dx) (y2+dy) % /Intersect = 7 index = 6 index = 5 index = 4 index = 3 index = 2 index = 1 index = 0 index = 2 copy infill { % replace x2,y2 6 -2 roll pop pop 4 2 roll } { 8 -2 roll pop pop % replace x1,y1 6 2 roll } ifelse } loop grestore 6 -2 roll % return x2,y2 4 { pop } repeat } bind def /i_clip_line { /endY exch store /endX exch store currentX currentY endX endY i_in_clip2 { % end in { % both in. just draw it. FIXME check if line leaves cliparea endX endY /lineto load } { % current not in % find new current point currentX currentY endX endY i_find_clip_intersect /moveto load endX endY /lineto load } ifelse } { % end not in { % current in % find new endpoint endX endY currentX currentY i_find_clip_intersect /lineto load } { % both not in % try to find a point within cliparea currentX currentY endX endY i_find_clip_intersect 2 copy i_in_clip { % yeah /moveto load % now find point from other end endX endY currentX currentY i_find_clip_intersect /lineto load } { pop pop } ifelse } ifelse } ifelse /currentX endX store /currentY endY store } bind def /pathClipForStroke { % only lines flattenpath % create a userpath from currentpath userdict begin /beginX 0 def /beginY 0 def /currentX 0 def /currentY 0 def /endX 0 def /endY 0 def systemdict begin % some EPS redefine moveto & Co :-( [ { i_clip_move } % remember last move { i_clip_line } % clip lines individually { 6 {pop} repeat /OOPS = } % won't happen { beginX beginY i_clip_line } % close with line pathforall ] cvx % dup == newpath % uappend % userpaths SUCK! end end exec } bind def /rectfill { userdict begin (n\n)print % start polygon writecurrentcolor writecurrentlinewidth writecurrentlinecap writecurrentlinejoin writecurrentdash storeMatrix % x y width height dup type /arraytype ne { /hr exch def /wr exch def /yr exch def /xr exch def xr yr i_move xr wr add yr i_line xr wr add yr hr add i_line xr yr hr add i_line xr yr i_line } % numarray % numstring { /ar exch def 0 4 ar length 1 sub { /n exch def ar n get /xr exch def ar n 1 add get /yr exch def ar n 2 add get /wr exch def ar n 3 add get /hr exch def xr yr i_move xr wr add yr i_line xr wr add yr hr add i_line xr yr hr add i_line xr yr i_line } for }ifelse (cp\n)print (f\n)print % close polygon end } i_shortcutOverload /rectstroke { userdict begin (n\n)print % start rect writecurrentcolor writecurrentlinewidth writecurrentlinecap writecurrentlinejoin writecurrentdash storeMatrix % x y width height dup type dup /arraytype ne exch /stringtype ne and { /hr exch def /wr exch def /yr exch def /xr exch def xr yr i_move xr wr add yr i_line xr wr add yr hr add i_line xr yr hr add i_line xr yr i_line } % numarray % numstring { /ar exch def 0 4 ar length 1 sub { /n exch def ar n get /xr exch def ar n 1 add get /yr exch def ar n 2 add get /wr exch def ar n 3 add get /hr exch def xr yr i_move xr wr add yr i_line xr wr add yr hr add i_line xr yr hr add i_line xr yr i_line } for }ifelse (cp\n)print (s\n)print % stroke rect end } i_shortcutOverload /stroke { (n\n) print writecurrentcolor writecurrentlinewidth writecurrentlinecap writecurrentlinejoin writecurrentdash % clipCnt 1 eq % { pathClipForStroke } if storeMatrix {i_move} {i_line} {i_curve} {i_close} pathforall (s\n)print % stroke path newpath } i_shortcutOverload /eofill { (n\n) print % start polygon writecurrentcolor % write color writecurrentlinewidth writecurrentlinecap writecurrentlinejoin writecurrentdash % clipCnt 1 eq % { pathClipAndClose } if storeMatrix % take transformation, scaling, rotation from PostScript {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath % clear stack } i_shortcutOverload /fill { (fill-winding\n) print eofill (fill-evenodd\n) print } i_shortcutOverload /clip { userdict begin (n\n)print % start clip polygon % FIXME: pathClipAndClose first? storeMatrix % take transformation, scaling, rotation from PostScript {i_move} {i_line} {i_curve} {i_close} pathforall (ci\n)print % close clip polygon begin path % we have to close the path!! % clip % /clipCnt 1 def newpath % clear stack end } i_shortcutOverload /eoclip { userdict begin (n\n)print % start clip polygon % FIXME: pathClipAndClose first? storeMatrix % take transformation, scaling, rotation from PostScript {i_move} {i_line} {i_curve} {i_close} pathforall (ci\n)print % close clip polygon begin path % we have to close the path!! % clip % /clipCnt 1 def newpath % clear stack end } i_shortcutOverload % we don't clip % because this doesn't work for flattening text (show, charpath) with NeXT PostScript Code /rectclip { % let Scribus decide what to do with ci; was: pop pop pop pop userdict begin (n\n)print % start clip polygon storeMatrix % take transformation, scaling, rotation from PostScript dup type dup /arraytype ne exch /stringtype ne and { 4 copy /i_h exch def /i_w exch def /i_y exch def /i_x exch def i_x i_y i_move i_x i_w add i_y i_line i_x i_w add i_y i_h add i_line i_x i_y i_h add i_line } { % array or string 0 4 dup length 1 sub { 1 index 1 index get /i_x exch def 1 add 1 index 1 index get /i_y exch def 1 add 1 index 1 index get /i_w exch def 1 add 1 index 1 index get /i_y exch def i_x i_y i_move i_x i_w add i_y i_line i_x i_w add i_y i_h add i_line i_x i_y i_h add i_line } for } ifelse (ci\n)print % close clip polygon begin path % we have to close the path!! % rectclip % /clipCnt 1 def newpath % clear stack end } i_shortcutOverload % Code for reading images is currently commented out, as it % doesn't seem to work correctly. % Copyright (C) 1994 Aladdin Enterprises. All rights reserved. % % This software is provided AS-IS with no warranty, either express or % implied. % % This software is distributed under license and may not be copied, % modified or distributed except as expressly authorized under the terms % of the license contained in the file LICENSE in this distribution. % % For more information about licensing, please refer to % http://www.ghostscript.com/licensing/. For information on % commercial licensing, go to http://www.artifex.com/licensing/ or % contact Artifex Software, Inc., 101 Lucas Valley Road #110, % San Rafael, CA 94903, U.S.A., +1(415)492-9861. % $Id: import.prolog 13454 2009-05-08 19:04:32Z jghali $ % traceimg.ps % Trace the data supplied to the 'image' operator. % This code currently handles only the (Level 2) dictionary form of image, % with a single data source and 8-bit pixels. % changed for Scribus image import by Andreas Vox, 2006-2-21 % added support for colorimage and other image variant /i_image % i_image - { %dup { == == } forall /i_image = begin /i_left Width Height mul Decode length 2 idiv mul BitsPerComponent mul 8 idiv dup /i_size exch store store /i_dict currentdict store /i_nsources 1 store /i_source 0 store /i_datasource currentdict /DataSource get store currentdict /MultipleDataSources known not { /MultipleDataSources false def } if MultipleDataSources { /i_nsources DataSource length store /i_datasource DataSource 0 get store } if end storeMatrix i_dict /ImageMatrix get matrix invertmatrix matrix currentmatrix matrix concatmatrix /i_m exch def i_dict /Width get 0 i_m dtransform dup mul exch dup mul add sqrt /i_w exch def 0 i_dict /Height get i_m dtransform dup mul exch dup mul add sqrt /i_h exch def 0 0 i_m transform /i_y exch def /i_x exch def i_dict /Width get i_dict /Height get i_m transform /i_hflip -1 def /i_vflip 1 def dup i_y le { /i_y exch def } { pop /i_vflip -1 def } ifelse dup i_x le { /i_x exch def } { pop /i_hflip 1 def } ifelse 0 i_dict /Height get i_m dtransform atan /i_angle exch def (.dat) i_exportfilename (im ) print % im x y w h angle ... i_x i_hscale div i_str cvs print ( ) print i_y i_vscale div i_str cvs print ( ) print i_w i_hscale div i_str cvs print ( ) print i_h i_vscale div i_str cvs print ( ) print i_angle i_str cvs print ( ) print i_dict /Width get i_str cvs print ( ) print % ... hpix vpix ... i_dict /Height get i_str cvs print ( ) print currentcolorspace 0 get /DeviceRGB eq { (tiff24nc ) print } { currentcolorspace 0 get /DeviceCMYK eq { (psdcmyk ) print } { currentcolorspace 0 get /DeviceGray eq { (tiffgray ) print } { (tiff32nc ) print } ifelse } ifelse } ifelse dup (.tif) concatenate print (\n) print flush % ... dev filename (.dat) concatenate (w) file /i_file exch store % temp file currentcolorspace ==write ( setcolorspace\n) =write (<<\n) =write i_dict { exch dup /DataSource eq { pop pop (/DataSource currentfile\n) =write } { dup /ImageMatrix eq { pop pop (/ImageMatrix [) =write i_hflip ==write ( 0 0 ) =write i_vflip ==write ( ) =write i_hflip 0 lt { i_dict /Width get } { 0 } ifelse ==write ( ) =write i_vflip 0 lt { i_dict /Height get} { 0 } ifelse ==write (]\n) =write } { ==write ( ) =write ==write (\n) =write } ifelse } ifelse } forall (>>\nimage\n) =write i_file flushfile { %loop i_left 0 le { i_source 1 add /i_source exch def i_source i_nsources ge { exit } if i_dict /DataSource get i_source get /i_datasource exch def /i_left i_size def } if /i_datasource load exec dup type /filetype eq { i_buf 0 i_left 32 .min getinterval readstring pop } if dup length 0 eq {pop i_zero 0 i_left 32 .min getinterval} if dup i_file exch writestring i_left exch length sub /i_left exch def } loop i_file flushfile /i_imageE = } bind def /colorimage { /colorimage = % width height bits/sample matrix datasource0..n-1 multi ncomp /tmpN exch def /tmpMulti exch def tmpMulti { /tmpN load array astore } if /tmpN load 6 add dict dup 7 -1 roll /Width exch put dup 6 -1 roll /Height exch put dup 5 -1 roll /BitsPerComponent exch put dup 4 -1 roll /ImageMatrix exch put dup 3 -1 roll /DataSource exch put tmpMulti { dup /MultipleDataSources true put } if dup /ImageType 1 put gsave /tmpN load dup 1 eq { 1 index /Decode [0 1] /Decode put /DeviceGray setcolorspace } if dup 3 eq { 1 index /Decode [0 1 0 1 0 1] put /DeviceRGB setcolorspace } if dup 4 eq { 1 index /Decode [0 1 0 1 0 1 0 1] put /DeviceCMYK setcolorspace } if pop i_image grestore /colorimageE = } i_shortcutOverload /image { /image = gsave dup type /dicttype ne { % width height bits/sample matrix datasource 7 dict dup 7 -1 roll /Width exch put dup 6 -1 roll /Height exch put dup 5 -1 roll /BitsPerComponent exch put dup 4 -1 roll /ImageMatrix exch put dup 3 -1 roll /DataSource exch put dup 1 /ImageType exch put dup [0 1] /Decode exch put /DeviceGray setcolorspace } if i_image grestore /imageE = } i_shortcutOverload /imagemask { /imagemask = writecurrentcolor (mask\n) print gsave dup type /dicttype ne { % width height pol matrix datasource 7 dict dup 7 -1 roll /Width exch put dup 6 -1 roll /Height exch put dup 5 -1 roll { [0 1] } { [1 0] } ifelse /Decode exch put dup 4 -1 roll /ImageMatrix exch put dup 3 -1 roll /DataSource exch put } if dup 1 /ImageType exch put dup 1 /BitsPerComponent exch put /DeviceGray setcolorspace i_image grestore /imagemaskE = } i_shortcutOverload % declare some global vars /i_left 0 def /i_size 0 def /i_dict null def /i_buf 32 string def /i_nsources 1 def /i_source 0 def /i_datasource { (x) } def /i_file null def /i_filecount 1 def /i_zero 32 string def %%%% End of traceimage code /stateArray 500 array def /stateTop 0 def /gsave { (gs\n) print userdict begin % (gs\n) print stateArray stateTop gstate currentgstate put /stateTop stateTop 1 add def end } i_shortcutOverload /grestore { (gr\n) print userdict begin stateTop 1 lt { } { % (gr\n) print stateArray stateTop 1 sub get setgstate /stateTop stateTop 1 sub def stateArray stateTop 0 put }ifelse end } i_shortcutOverload /stringwidth { /i_shortcut true store stringwidth /i_shortcut false store } i_shortcutOverload % a bind def of the show operator doesn't work, % so this is our way to get a charpath entry for flattening text /root_charpath { charpath } bind def /i_kerningI { exch 1 getinterval stringwidth } bind def % find kerning value /i_kerningII % index string i_kerning dx dy { % stringwidth( [n..n+1] ) - stringwidth( [n+1] ) /i_pstring exch def /i_pindex exch def i_pstring i_pindex 2 getinterval stringwidth exch % y2 x2 i_pstring i_pindex 1 add 1 getinterval stringwidth % y2 x2 x1 y1 4 1 roll sub % y1 y2 (x2-x1) 3 1 roll exch sub % (x2-x1) (y2-y1) } bind def /i_kerningIII % index string i_kerning dx dy { % stringwidth( [n..n+1] ) - stringwidth( [n+1] ) /i_pstring exch def /i_pindex exch def i_pstring i_pindex 2 getinterval (l) exch concatenate stringwidth exch % y2 x2 i_pstring i_pindex 1 add 1 getinterval (l) exch concatenate stringwidth % y2 x2 x1 y1 4 1 roll sub % y1 y2 (x2-x1) 3 1 roll exch sub % (x2-x1) (y2-y1) } bind def /i_kerning /i_kerningII load def /show % string show - { userdict begin storeMatrix currentfont /FontName known % stack: string { currentfont /FontType get dup 3 eq exch 0 eq or { currentpoint /ycur exch def /xcur exch def currentpoint % x y newpath /clipCnt 0 def moveto (n\n)print % start polygon writecurrentcolor % write color storeMatrix dup stringwidth /curwidthy exch def /curwidthx exch def false root_charpath {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath curwidthx xcur add curwidthy ycur add moveto currentpoint /ycur exch def /xcur exch def newpath % clear graphic stack xcur ycur moveto } { currentpoint /ycur exch def /xcur exch def currentpoint % x y newpath /clipCnt 0 def moveto /completeString exch def % we process each char separately to get smaller paths 0 1 completeString length 1 sub { (n\n)print % start polygon writecurrentcolor % write color storeMatrix dup completeString length 1 sub eq { dup completeString exch 1 getinterval stringwidth } { dup completeString i_kerning } ifelse /curwidthy exch def /curwidthx exch def completeString exch 1 getinterval dup /curstr exch def false root_charpath {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath curwidthx xcur add curwidthy ycur add moveto currentpoint /ycur exch def /xcur exch def newpath % clear graphic stack xcur ycur moveto } for currentpoint % x y newpath % clear graphic stack (and current point) moveto } ifelse } { currentfont /FontType known { currentfont /FontType get dup 3 eq exch 0 eq or { currentpoint /ycur exch def /xcur exch def currentpoint % x y newpath /clipCnt 0 def moveto (n\n)print % start polygon writecurrentcolor % write color storeMatrix dup stringwidth /curwidthy exch def /curwidthx exch def false root_charpath {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath curwidthx xcur add curwidthy ycur add moveto currentpoint /ycur exch def /xcur exch def newpath % clear graphic stack xcur ycur moveto } { pop } ifelse } { pop } ifelse } ifelse end } i_shortcutOverload /ashow { % ax ay string exch /ydist exch def exch /xdist exch def userdict begin storeMatrix currentfont /FontName known % stack: string { currentpoint /ycur exch def /xcur exch def currentpoint % x y newpath /clipCnt 0 def moveto /completeString exch def % we process each char separately to get smaller paths 0 1 completeString length 1 sub { (n\n)print % start polygon writecurrentcolor % write color storeMatrix dup completeString length 1 sub eq { dup completeString exch 1 getinterval stringwidth } { dup completeString i_kerning } ifelse /curwidthy exch def /curwidthx exch def completeString exch 1 getinterval dup /curstr exch def false root_charpath {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath curwidthx xcur add curwidthy ycur add exch xdist add exch ydist add moveto currentpoint /ycur exch def /xcur exch def newpath % clear graphic stack xcur ycur moveto } for currentpoint % x y newpath % clear graphic stack (and current point) moveto } { pop } ifelse end } i_shortcutOverload /awidthshow % cx cy char ax ay string { % ax ay string exch /ydist exch def exch /xdist exch def % cx cy char string exch /char exch def exch /cydist exch def exch /cxdist exch def userdict begin storeMatrix currentfont /FontName known % stack: string { currentpoint /ycur exch def /xcur exch def currentpoint % x y newpath /clipCnt 0 def moveto /completeString exch def % we process each char separately to get smaller paths 0 1 completeString length 1 sub { (n\n)print % start polygon writecurrentcolor % write color storeMatrix dup completeString length 1 sub eq { dup completeString exch 1 getinterval stringwidth } { dup completeString i_kerning } ifelse /curwidthy exch def /curwidthx exch def completeString exch 1 getinterval dup /curstr exch def false root_charpath {i_move} {i_line} {i_curve} {i_close} pathforall (f\n)print % close polygon newpath curwidthx xcur add curwidthy ycur add exch xdist add exch ydist add moveto curstr 0 get char eq { currentpoint exch cxdist add exch cydist add moveto } if currentpoint /ycur exch def /xcur exch def newpath % clear graphic stack xcur ycur moveto } for currentpoint % x y newpath % clear graphic stack (and current point) moveto } { pop } ifelse end } i_shortcutOverload /widthshow % cx cy char string { 0 exch 0 exch awidthshow } bind def %/cshow % proc string %{ % exch pop % show %} i_shortcutOverload /kshow % proc string { dup length 1 sub dup 0 ne { 1 index 0 1 getinterval show 1 sub dup 0 ne { 1 add 1 exch 1 exch { dup 1 sub 2 index exch get 2 index 2 index get 4 index exec 1 index exch 1 getinterval show } for } if } { pop dup show } ifelse pop pop } i_shortcutOverload /xshow % string array { pop %FIXME show } i_shortcutOverload /xyshow % string array { pop %FIXME show } i_shortcutOverload /yshow % string array { pop %FIXME show } i_shortcutOverload /i_reencode % newfontname reencodevector origfontdict -> i_reencode -> newfontdict { userdict begin dup begin dup maxlength dict begin { 1 index /FID ne {def} {pop pop} ifelse } forall /Encoding exch def currentdict end end definefont end } bind def /glyphshow { save % So can reclaim VM from reencoding currentfont /Encoding get dup length array copy dup 0 5 -1 roll put /GlyphShowTempFont exch currentfont i_reencode setfont (\000) show currentpoint 3 -1 roll % curx cury -save- restore newpath moveto } i_shortcutOverload /showpage { (sp\n) print } i_shortcutOverload