% version = 1.06 of xyplom 2010 Sep 20 % 2010 Sep 20, 1.06: add filldiamond % 2003 Aug 26, 1.05: added marks.arrow functions! % 2003 Aug 26, 1.04: added examples of direct use % 2000 Apr 5, 1.03: added hollowsquare % origin 1996 Oct 10 % PostScript definitions of additional symbols for xyplo % This is an example xy plotter marks file (xyplom) % It is to be used with the xyplo program: % % https://alum.mit.edu/www/toms/delila/xyplo.html % % Detailed documentation is there. % This file contains two simple examples, % for making a filled square and a hollow square. % It also has a very complex example (but simple to use!!) % of an arrow definition. The use is at the bottom of the file. % IF YOU ARE NOT USING THESE FUNCTIONS SIMPLY USE AN EMPTY % FILE FOR YOUR xyplom. Otherwise all these functions will be % added to your output file, and that would be a waste. /fillsquare { % xsize ysize fillsquare - % make a filled square centered at the current location % xsize x size in points % ysize y size in points /ysize exch def /xsize exch def xsize -2 div ysize -2 div translate 0 0 moveto xsize 0 lineto xsize ysize lineto 0 ysize lineto closepath fill } bind def /filldiamond { % xsize ysize filldiamond - % make a filled diamond centered at the current location % xsize x size in points % ysize y size in points % make the diamond the same size (in x and y) as the square % by reducing the size by the square root of 2 /root2 2 sqrt def /ysize exch root2 div def /xsize exch root2 div def % xsize -2 div ysize -2 div translate % 0 0 moveto % xsize 0 lineto % xsize ysize lineto % 0 ysize lineto xsize 0 moveto 0 ysize lineto xsize neg 0 lineto 0 ysize neg lineto closepath fill } bind def /hollowsquare { % xsize ysize hollowsquare - % make a hollowed square with the left corner at the current location % xsize x size in points % ysize y size in points /ysize exch def /xsize exch def % xsize -2 div ysize -2 div translate % xsize -2 div ysize -2 div translate 0 0 moveto xsize 0 lineto xsize ysize lineto 0 ysize lineto closepath stroke } bind def % The following code uses the above two examples % to draw the components before the rest of the graph is drawn. % gsave % 5 cm 8 cm translate % 5 cm 3 cm fillsquare % 5 cm 8 cm translate % 2 cm 4 cm hollowsquare % grestore % from version = 1.50 of marks.arrow 2003 Feb 19 % define arrow and rectangle marks % origin before 1996 June 29 % * version = 1.50 of marks.arrow 2003 Feb 19 % * define arrow and rectangle marks % * origin before 1996 June 29 % * History: % * 2003 Feb 19: 1.50: cleanup % * 2000 Sep 2: 1.48: positionedletters defined % * 2000 Jul 5: 1.47: unshift defined % * 2000 Jun 29: 1.46: introduce greenish and pink % * 1999 Aug 15: incredibly stupid definition fixed: /limegreen {limegreen} def % * 1998 Mar 29: definition of fixedrectangle corrected to shift properly % * 1999 May 11: definition of zeroedline and zeroedarrow % u % % define error message that will show up if the user forgets % % to use this file % /You_need_a_marks.arrow_definition {} def % define font size as a unit of measure: /fontsize 1 cm def % keeps the standard routines happy /charwidth fontsize def % keeps the standard routines happy /fs {fontsize mul} def % Define an arrow % Source: page 141 of the PostScript Cookbook /arrowdict 14 dict def arrowdict begin /mtrx matrix def end /arrow { arrowdict begin /headlength exch def /halfheadthickness exch 2 div def /halfthickness exch 2 div def /tipy exch def /tipx exch def /taily exch def /tailx exch def /dx tipx tailx sub def /dy tipy taily sub def /arrowlength dx dx mul dy dy mul add sqrt def /angle dy dx atan def /base arrowlength headlength sub def /savematrix mtrx currentmatrix def tailx taily translate angle rotate 0 halfthickness neg moveto base halfthickness neg lineto base halfheadthickness neg lineto arrowlength 0 lineto base halfheadthickness lineto base halfthickness lineto 0 halfthickness lineto closepath savematrix setmatrix end } def % Define a worra, the end of an arrow % Source: page 141 of the PostScript Cookbook /worradict 14 dict def worradict begin /mtrx matrix def end /worra { worradict begin /headlength exch def /halfheadthickness exch 2 div def /halfthickness exch 2 div def /tipy exch def /tipx exch def /taily exch def /tailx exch def /dx tipx tailx sub def /dy tipy taily sub def /worralength dx dx mul dy dy mul add sqrt def /angle dy dx atan def /base worralength headlength sub def /savematrix mtrx currentmatrix def tailx taily translate angle rotate % 0 halfthickness neg moveto % base halfthickness neg lineto % base halfheadthickness neg lineto % worralength 0 lineto % base halfheadthickness lineto % base halfthickness lineto % 0 halfthickness lineto /h2 headlength 2 div def /h3 headlength 3 div def base 0 moveto base h3 neg add halfheadthickness neg lineto base 0 add halfheadthickness neg lineto base h3 add 0 lineto base 0 add halfheadthickness lineto base h3 neg add halfheadthickness lineto base 0 add 0 lineto % now do a rectangle: base 0 add halfthickness neg lineto base h2 add halfthickness neg lineto base h2 add halfthickness lineto base 0 add halfthickness lineto closepath %grestore savematrix setmatrix end } def /edgebox{ % Define an edgebox, a box with only some edges drawn % input parameters: % {fillcolor} {edgecolor} % edgeboxlength edgeboxheight % bottomside rightside topside leftside % % edgecolors define the red, green and blue components of the edge % fillcolors define the filling color % box length is the x axis length % box height is the y axis length % The four sides are booleans that determine which side edges are drawn /leftside exch def /topside exch def /rightside exch def /bottomside exch def /edgeboxheight exch def /edgeboxlength exch def /edgecolor exch def /fillcolor exch def /segment { /point2y exch def /point2x exch def /point1y exch def /point1x exch def /doside exch def doside { didside not {point1x point1y moveto} if point2x point2y lineto /didside true def } { /didside false def } ifelse } def gsave /x edgeboxlength def /y edgeboxheight def fillcolor 0 0 moveto x 0 lineto x y lineto 0 y lineto 0 0 lineto closepath gsave % fill but keep the path fill grestore gsave edgecolor newpath 0 0 moveto % lastpoint /didside true def bottomside 0 0 x 0 segment rightside x 0 x y segment topside x y 0 y segment leftside 0 y 0 0 segment bottomside 0 0 x 0 segment % repeat bottomside instead of doing a closepath % since the closepath may cut a diagonal! 0 setlinejoin stroke grestore grestore } def /makeanybox{ % make any kind of edged box AROUND the current point /theedgecolor exch def /thefillcolor exch def /shiftbase exch def /heady exch def /headx exch def /taily exch def /tailx exch def tailx shiftbase % redefine boxes AROUND current point 0.5 sub charwidth mul 2 mul add taily moveto currentpoint translate {thefillcolor} {theedgecolor} headx tailx sub % redefine boxes AROUND current point charwidth 2 mul add heady taily sub } def /leftbox{ % draw a filled box with the right side open gsave makeanybox true false true true edgebox grestore } def /midbox{ % draw a filled box with both the left and right sides open gsave makeanybox true false true false edgebox grestore } def /rightbox{ % draw a filled box with the left side open gsave makeanybox true true true false edgebox grestore } def /fullbox{ % draw a filled box with the no sides open gsave makeanybox true true true true edgebox grestore } def /colorpath { % color the path. If fillfirst is true, % fill the path then stroke, otherwise % stroke first and then fill. % fillfirst gives thicker edges. % the fill color is 'bodycolor'. % the stroke color is 'strokecolor'. { dofill {bodycolor fill} if} { dostroke {strokecolor stroke} if} fillfirst {exch} if gsave exec grestore % use the path and restore it exec % use up the path forever } def /fixedarrow { % make a fixed position arrow % These are put on the stack: % TailX TailY HEadX HeadY Shift % bases bits bases bits bases % The arrow goes from the point (TailX,TailY) % to the point (HeadX,HeadY), and has a thickness of % BodyThick around this line segment. % on the stack give bases to move the arrow % globally defined parameters: % BodyThick: thickness of body of arrow % HeadWidth: How wide the tip of the arrow is % Headlength: How long the tip of the arrow is % bodycolor: function that sets the body of the rectangle % strokecolor: function that sets the edge of the rectangle % dostroke: stroke if true % dofill: fill if true charwidth mul 2 mul 0 translate BodyThick HeadWidth HeadLength arrow colorpath } def /fixedworra { % make a fixed position worra % These are put on the stack: % TailX TailY HEadX HeadY Shift % bases bits bases bits bases % The worra goes from the point (TailX,TailY) % to the point (HeadX,HeadY), and has a thickness of % BodyThick around this line segment. % on the stack give bases to move the worra % globally defined parameters: % BodyThick: thickness of body of worra % HeadWidth: How wide the tip of the worra is % Headlength: How long the tip of the worra is % bodycolor: function that sets the body of the rectangle % strokecolor: function that sets the edge of the rectangle % dostroke: stroke if true % dofill: fill if true charwidth mul 2 mul 0 translate BodyThick HeadWidth HeadLength worra colorpath } def /fixedrectangle { % make a fixed position rectangle % on the stack give bases to move the rectangle % globally defined parameters: % BodyThick: thickness of body of rectangle % bodycolor: function that sets the body of the rectangle % strokecolor: function that sets the edge of the rectangle % dostroke: stroke if true % dofill: fill if true % old definition which doesn't work correctly for shifting!!: % charwidth mul 2 mul 0 translate charwidth mul 0 translate % BodyThick BodyThick 0 arrow colorpath } def /HTrecompute { % recompute the head and tail and stick onto stack % so that they run from the corners. % Also, define the BodyThick of the arrow /shiftbase exch def /hy exch def /hx exch def /ty exch def /tx exch def /BodyThick hy ty sub abs def /centery ty hy add 2 div def tx centery hx centery shiftbase } def /boundarrow { % make an arrow % Like fixedarrow but the endpoints are % the opposite ends of the arrow % so it is easier to position the edges. % BodyThick of the arrow is computed from these points HTrecompute fixedarrow } def /boundrectangle { % make a rectangle % Like fixedrectangle but the endpoints are % the opposite ends of the rectangle % so it is easier to position the edges. % BodyThick of the arrow is computed from these points HTrecompute fixedrectangle } def /wiggle { % tx ty dummy dummy shift wiggle % make a wiggle mark upwards from tx, ty. Ignore the two dummy variables. % shift the wiggle horizontally by the given amount in bases /shiftbase exch def /hy exch def /hx exch def /ty exch def /tx exch def tx shiftbase fs add -0.25 fs add ty moveto % % first pass, relative: % +0.5 fs 0.5 fs rlineto % -0.5 fs 0.5 fs rlineto % +0.5 fs 0.5 fs rlineto % % second pass, absolute: % currentpoint translate % +0.50 fs 0.5 fs lineto % -0.00 fs 1.0 fs lineto % +0.50 fs 1.5 fs lineto % currentpoint translate +0.50 fs 0.5 fs -0.00 fs 1.0 fs +0.50 fs 1.5 fs curveto % % 1 0 0 setrgbcolor 3 setlinewidth stroke } def % U 710680.0 -2.5 0 0 +3.6 wiggle % standard definitions /BodyThick 8.00 fs def /HeadWidth 12.00 fs def /HeadLength 8.00 fs def /bodycolor {limegreen} def /strokecolor {blue} def /fillfirst true def /dostroke true def /dofill true def 1 setlinewidth % define some convenient colors /white {1 1 1 setrgbcolor} def /black {0 0 0 setrgbcolor} def /red {1 0 0 setrgbcolor} def /green {0 1 0 setrgbcolor} def /blue {0 0 1 setrgbcolor} def /orange {1 0.7 0 setrgbcolor} def /yellow {1 1 0 setrgbcolor} def /purple {1 0 1 setrgbcolor} def % standard pink and greenish from lister /pink {1 0.2 1 sethsbcolor} def /greenish {0.4 0.2 1 sethsbcolor} def /lightblue {0.60 0.1 1.0 sethsbcolor} def /lightgreen {0.35 0.1 1.0 sethsbcolor} def /lightpurple {0.80 0.1 1.0 sethsbcolor} def /lightyellow {0.10 0.1 1.0 sethsbcolor} def /limegreen {lightgreen} def /lightred {pink} def % You can change any of the standard definitions % fs is the font size vertically % charwidth is assumed to exist (it does in makelogo and lister) % as the width of the characters horizontally. /forceforward {% don't do anything so that the next mark position is used pop pop pop pop % throw away the coordinates } def % --------------------------------------------------------------------------- % define a line and arrow based on the zero coordinate /zeroedinitialize { % zeroedlinethick zeroedheadthick zeroedheadlength % zeroedshiftdown zeroedbetweenlines zeroedinitialize - % initialize variables for: % zeroedlinethick thickness of lines % zeroedheadthick thickness of arrowhead % zeroedheadlength length of arrowhead % zeroedshiftdown initial amount to shift downward % zeroedbetweenlines amount to shift downward between lines /zeroedbetweenlines exch def /zeroedshiftdown exch def /zeroedheadlength exch def /zeroedheadthick exch def /zeroedlinethick exch def /zeroedshiftdowncounter zeroedshiftdown def } def 2 6 8 -1.0 cm -0.20 cm zeroedinitialize % start out /arrowshape {zeroedlinethick zeroedheadthick zeroedheadlength} def /zeroedline {% 0 0 0 0 xfrom xto zeroedline % mark a line at the zero coordinate. % all marks are started from base zero. % This allows them to be in any order and any size. % % first see if there is a (-) or (+) on the line (like zeroedarrow) % and remove it if so. This makes the two compatable. dup (-) eq {pop} if dup (+) eq {pop} if /xto exch 0.5 add def /xfrom exch 0.5 add def pop pop pop pop % throw away the coordinate and base positions gsave zeroedbetweenlines 0.5 mul setlinewidth xfrom charwidth mul zeroedshiftdowncounter moveto xto charwidth mul zeroedshiftdowncounter lineto zeroedlinethick setlinewidth stroke /zeroedshiftdowncounter zeroedshiftdowncounter zeroedbetweenlines add def grestore } def /zeroedarrow {% 0 0 0 0 xfrom xto direction zeroedarrow % mark an arrow at the zero coordinate. % all marks are started from base zero. % This allows them to be in any order and any size. % the range is xfrom to xto. The arrow direction is either (+) % (to the right) or (-) (to the left). % /direction exch def /xto exch 0.5 add def /xfrom exch 0.5 add def pop pop pop pop % throw away the coordinate and base positions zeroedbetweenlines 0.5 mul setlinewidth % direction (+) eq { xfrom fs zeroedshiftdowncounter xto fs zeroedshiftdowncounter } { xto fs zeroedshiftdowncounter xfrom fs zeroedshiftdowncounter } ifelse % arrowshape arrow black fill % % experimental: show a literal after the end of the arrow. % xto fs % zeroedshiftdowncounter zeroedbetweenlines 0.5 mul add % moveto % ( something) show % /zeroedshiftdowncounter zeroedshiftdowncounter zeroedbetweenlines add def zeroedlinethick setlinewidth } def /zeroedname {% 0 0 0 0 atlocation (the string) zeroedname % mark a name at the location given relative to the zero coordinate. % the vertical coordinate is given by zerowedshiftdowncounter % /thestring exch def /atlocation exch def pop pop pop pop % throw away the coordinate and base positions % % direction (+) eq % { xfrom fs zeroedshiftdowncounter xto fs zeroedshiftdowncounter } % { xto fs zeroedshiftdowncounter xfrom fs zeroedshiftdowncounter } % ifelse % gsave atlocation fs % zeroedshiftdowncounter zeroedshiftdowncounter zeroedbetweenlines 0.5 mul add moveto thestring show grestore } def /unshift{ % zeroedarrow automatically shifts down; sometimes one doesn't % want this. This little routine counters it. To use it: % U 0 0 0 0 -3.5 +0.5 (+) zeroedarrow unshift % -3 to 0 /zeroedshiftdowncounter zeroedshiftdowncounter zeroedbetweenlines sub def } def % --------------------------------------------------------------------------- /doubleY {% 0 0 0 0 doubleY % Put a double Y just to the right of the current base position, % but shift it by the amount shiftY. % A double Y is like a captal Y letter joined at its base to the base of % an upsidedown capital Y. % pop pop pop pop % throw away the coordinate and base positions /shiftY exch def /hy exch def /hx exch def /ty exch def /tx exch def gsave /earlength {4 div fs} def 1.5 setlinewidth shiftY charwidth 2 mul mul ty moveto gsave -1 earlength -1 earlength rlineto stroke grestore gsave +1 earlength -1 earlength rlineto stroke grestore shiftY charwidth 2 mul mul hy lineto gsave -1 earlength +1 earlength rlineto stroke grestore gsave +1 earlength +1 earlength rlineto stroke grestore stroke grestore } def % --------------------------------------------------------------------------- /positionedletters {% x y 0 0 morex morey theletters positionedletters % Position a set of letters (theletters) at point (x,y), where x % is in bases along the sequences (the trigger location for the mark) % and y is the vertical position in bits. The next two parameters % are ignored by the mechanism. In addition, one may move the string % of letters by additinal increments of characters horizontally (morex) % and in additional increments of bits vertically (morey). % This allows one to center a class of letters and place them around % the center. % The allowed letters are the 4 bases (a,c,g,t) and the amino % acids (capital letters) % example: % U 20 -1.5 0 0 1 0 (t a g c t t) positionedletters % Technical Note: This routine is for use with the lister program and depends % on the letters being functions that write to the postscript output. % For example, sequences in lister are produced by 'a e u e g', % where a u and g are routines to draw those letters and e is a space. % Therefore this routine will not work with makelogo. /theletters exch def /morey exch fontsize mul def /morex exch charwidth mul def pop pop /y exch def /x exch def gsave x morex add y morey add moveto % the mechanism is to convert the literal string % into an executable set on the stack and then % to execute it. Letters are defined to write % in the lister code. theletters cvx exec grestore } def % end of standard part ------------------------------------------------------ % ! % * Zeroed marks % % * this works: % *U -10.5 -0.62 10.5 -0.62 arrowshape arrow red fill % trxC bottom % *U 0.0 -0.25 5.0 -0.25 arrowshape arrow black fill % *U 0.0 -0.25 5.0 -0.25 arrowshape arrow black fill % % * examples: % *U 0 0 0 0 -0.5 +0.5 zeroedline % *U 0 0 0 0 -5.5 +5.5 (+) zeroedarrow % *U 0 0 0 0 -5.5 +5.5 (-) zeroedarrow % % * U 0 0 0 0 -0.5 +0.5 (+) zeroedarrow % * U 0 0 0 0 -0.5 +1.5 (+) zeroedarrow % * U 0 0 0 0 +0.0 -3.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 -2.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 -1.0 (+) zeroedarrow % * *U 0 0 0 0 0.0 +0.0 (+) zeroedarrow CANNOT DO - error % * U 0 0 0 0 +0.0 +1.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 +2.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 +3.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 +4.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 +5.0 (+) zeroedarrow % * U 0 0 0 0 +0.0 +6.0 (+) zeroedarrow % % * U 0 0 0 0 +0.5 -0.5 (-) zeroedarrow % * U 0 0 0 0 +0.5 -1.5 (-) zeroedarrow % * U 0 0 0 0 +0.0 +3.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 +2.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 +1.0 (-) zeroedarrow % * *U 0 0 0 0 0.0 -0.0 (-) zeroedarrow CANNOT DO - error % * U 0 0 0 0 +0.0 -1.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 -2.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 -3.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 -4.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 -5.0 (-) zeroedarrow % * U 0 0 0 0 +0.0 -6.0 (-) zeroedarrow % % * you can use unshift to undo a down shift by zeroedarrow: % * U 0 0 0 0 -3.5 +0.5 (+) zeroedarrow unshift % -3 to 0 % % *U 0 0 0 0 -0.5 +0.5 zeroedline % *U 0 0 0 0 -0.5 +1.5 zeroedline % *U 0 0 0 0 0.0 -3.0 zeroedline % *U 0 0 0 0 0.0 -2.0 zeroedline % *U 0 0 0 0 0.0 -1.0 zeroedline % *U 0 0 0 0 0.0 +0.0 zeroedline % *U 0 0 0 0 0.0 +1.0 zeroedline % *U 0 0 0 0 0.0 +2.0 zeroedline % *U 0 0 0 0 0.0 +3.0 zeroedline % *U 0 0 0 0 0.0 +4.0 zeroedline % *U 0 0 0 0 0.0 +5.0 zeroedline % *U 0 0 0 0 0.0 +6.0 zeroedline % % ******************************************************************************** % % * Coordinate based marks % % * Give the coordinates of the tail (in bases and bits) of the arrow. % * Give the coordinates of the head (in bases and bits) of the arrow. % * The head is the pointy end: tail => head. % * You can use a fixed rectangle instead. % * Then give the bases to shift the tail of the arrow. % * The reason for this feature is that marks are drawn in the order % * given, and so later ones overlap earlier ones. % * By moving the tail, you will have full control. % % *23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 % * 1 2 3 4 5 6 7 8 % % * examples: % * TailX TailY HEadX HeadY Shift % * bases bits bases bits bases % * U -10.0 0.00 -5.0 0.00 0 fixedrectangle % * U 0.0 -1.25 5.0 -1.25 0 fixedarrow % * U -10.0 0.00 -5.0 1.00 0 boundrectangle % * U 0.0 -1.25 5.0 -2.25 0 boundarrow % * U 1244.0 -0.25 1262.0 1.00 -15.50 boundrectangle % * U 1244.0 -0.25 1262.0 1.00 forceforward % % * define corners: lower left to upper right: % % * U 140.00 -0.30 141.00 -0.10 0 {lightgreen} {black} fullbox % * U 140.00 -1.30 141.00 -0.10 1 {lightgreen} {black} fullbox % * U 140.00 -2.30 141.00 -0.10 2 {lightgreen} {black} fullbox % * U 140.00 -3.30 141.00 -0.10 3 {lightgreen} {black} fullbox % * U 140.00 -4.30 141.00 -0.10 4 {lightgreen} {black} fullbox % * U 140.00 -5.30 141.00 -0.10 5 {lightgreen} {black} fullbox % * U 140.00 -6.30 141.00 -0.10 6 {lightgreen} {black} fullbox % * U 145.45 -1.30 146.55 -0.10 1 {yellow} {black} fullbox % * U 150.45 -1.30 151.55 -0.10 0 {lightgreen} {black} leftbox % * U 151.45 -1.30 152.55 -0.10 0 {lightgreen} {black} midbox % * U 152.45 -1.30 153.55 -0.10 0 {lightgreen} {black} rightbox % % ******************************************************************************** % standard definitions /BodyThick 0.020 fs def /HeadWidth 0.110 fs def /HeadLength 0.100 fs def /bodycolor {black} def /strokecolor {black} def /fillfirst true def /dostroke true def /dofill true def 1 setlinewidth /holdme { /locx 9.1 cm def /locy 18.8 cm def /length 0.5 cm def /tailx locx def /taily locy length add def /headx locx def /heady locy def % * TailX TailY HEadX HeadY Shift tailx taily headx heady 0 fixedarrow } def /downarrow { % locx locy length downarrow - % draw a downward arrow /length exch cm def /locy exch cm def /locx exch cm def /tailx locx def /taily locy length add def /headx locx def /heady locy def % * TailX TailY HEadX HeadY Shift tailx taily headx heady 0 fixedarrow } def % Unearth these to see examples of downarrow %9.1 18.8 0.5 downarrow %8.7 17.3 0.5 downarrow