--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "array.h"
+#include "gjutil.h"
+#include "version.h"
+
+/****************************************************************************
+
+ ALPS - Main routines for ALSCRIPT alignment formatting tool
+
+ Copyright: Geoffrey J. Barton (1992,1993,1997)
+
+ email: geoff@ebi.ac.uk
+
+All use of this program must cite: Barton, G. J. (1993), ALSCRIPT: A Tool to
+Format Multiple Sequence Alignments, Protein Engineering, Volume 6, No. 1,
+pp. 37-40.
+
+ Please see README file for details of limitations of use.
+
+ $Id: alps.c,v 1.3 1998/09/17 17:34:26 geoff Exp $
+ $Log: alps.c,v $
+ Revision 1.3 1998/09/17 17:34:26 geoff
+ Add the new README file and the LICENSE and RELEASE_NOTES
+
+ Revision 1.2 1998/09/17 16:54:58 geoff
+ Check consistency with archive
+
+
+****************************************************************************
+
+ Main routine for ALSCRIPT - formally called ALPS
+
+ alps: 11th June 1992.
+ Author: G. J. Barton
+
+ This file contains a set of subroutines that provide for flexible
+formatting of multiple sequence alignments in PostScript at
+publication quality.
+
+11-18th June 1992:
+
+1. Modified getbloc.c to Agetbloc.c. Agetbloc reads all characters
+(ie not just legal amino acid codes) from an AMPS blocfile format
+multiple alignment file.
+
+2. Wrote basic page scaling features to allow arbitrary page
+dimensions to be defined and to allow all x,y locations to be defined
+in terms of characters of the chosen pointsize. The number of
+residues per line and hence number of pages is determined by the
+pointsize. The page is divided into four areas. (a) The main region
+for plotting out the amino acid sequences. (b) A region to the left of
+a for plotting sequence identifier codes - the width of this region is
+set by variable Cidwidth. (c) A region above region a, and (d) a
+region below a. Regions c and d are initially set to zero size.
+Routine ALReserveSpace() allows a selected number of lines to be
+reserved above or below for plotting.
+
+3. Routines ALOutID and ALOutSeq written and multi-page plotting of
+the sequences sorted out. Still limited to one page in the vertical
+direction - toyed with the idea of writing single page PostScript and
+using PostScript to modify clipping boundaries like in the Poster demo
+program in the CookBook.
+
+4. Experiment with simple boxing facility - ALDrawSimpleBox(). This
+routine is incompatible with multi-page output since page breaks are
+unpredictable.
+
+5. Develop sophisticated (!) boxing facility - defines boxes in terms
+of TOP BOTTOM LEFT and RIGHT lines that may be defined around each
+character routine ALLineRes() implements this feature. The details of
+TOP etc for each character are stored in the unsigned char array
+"lines". This uses the rightmost four bits to encode LEFT RIGHT etc.
+Thus a line to the LEFT line is coded by decimal 1 (0001 binary), a
+full box by decimal 15 (1111 binary). ALBoxRes and ALBoxRegion
+written to allow boxing of arbitrary regions.
+
+6. The y coordinate sent to the low level ALLineRes routine
+refers directly to the index to the lines array. If you want to work in
+residue coordinate space, you need to flip the y coordinate before
+writing to the lines array (also the fill array). Routines ALSurroundChars
+and ALFillChars do this directly. Routines ALBoxRegion and ALFilRegion
+make use of the Yindx array which does the flip in a much cleaner and more
+elegant way. If I'd thought of it at the
+time, I would have used this in ALSurroundChars and ALFillChars as well!
+
+7. Now add capability to split alignments vertically as well as horizontally.
+There is now no limit on pointsize or number/length of sequences
+(in principle!). Next move on the page layout front will be to allow
+multiple blocks on a single page - this would permit alignments of a
+few sequences, or small fonts to make better use of paper!
+
+8. We now have most of the subroutines working OK. So time to tidy up the
+input. Add simple command parser to main programme - this is in two steps,
+step 1 reads the basic page layout commands, step 2 reads the boxing/shading
+font changing commands - Oh yes, added the font changing option as well.
+
+Current commands as follows:
+Commands are delimited by space, comma, or tab. Newline signals the end of a
+command. Unless otherwise stated, units are in characters of the default pointsize.
+For a full list see the file "alscript.doc".
+
+step 1 commands:
+
+BLOCK_FILE <input filename> %The name of the alignment file to format
+OUTPUT_FILE <file> %must have this near the beginning
+LANDSCAPE %Longest side horizontal
+PORTRAIT % vertical
+POINTSIZE <float> %Pointsize for page calculations and character spacing/default size.
+IDENT_WIDTH <integer> %Width allocated to identifiers.
+NUMBER_SEQS 1 || 0 %1=number identifiers, 0= no numbers (default).
+DEFINE_FONT <font number integer> <font name> <pointsize> %define a font to be referred to as font number.
+e.g.
+ DEFINE_FONT 0 Helvetica 10 %font 0 is Helvetica at 10 point
+ DEFINE_FONT 4 Times-Roman DEFAULT %font 4 is Times-Roman at the default pointsize.
+SETUP %signals end of step 1 commands.
+
+step 2 commands:
+
+RESERVE_SPACE_TOP <integer> %make space at the top of the alignment
+RESERVE_SPACE_BOTTOM <integer> % bottom DOES NOT WORK.
+SURROUND_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq>
+ %surround (box) the characters chars within the ranges specified
+e.g.
+ SURROUND_CHARS PG 1 7 20 12 %surround P and G characters from residues 1 to 20 of sequences 7 to 12.
+ SURROUND_CHARS DEKHR ALL %surround D and E and K and R characters for the whole alignment.
+
+SHADE_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq> <grey>
+ %similar syntax to SURROUND_CHARS with the addition of a grey value
+ % 0 = black, 1 = white. Note that shading is done before outputing the
+ % alignment.
+e.g.
+ SHADE_CHARS PG 1 7 20 12 0.5 % shade P and G in the range shown with a grey value of 0.5
+ SHADE_CHARS ILV ALL 0 % shade all I and L and V in black.
+
+FONT_CHARS <chars> <start_res> <start_seq> <end_res> <end_seq> <fontnumber>
+ %same syntax as SHADE_CHARS, only give the font number in place of grey.
+ %font numbers must first be defined with the DEFINE_FONT command above.
+FONT_RESIDUE sx sy font %allows setting of font for one residue (use with TEXT command)
+
+BOX_REGION <start_res> <start_seq> <end_res> <end_seq>
+ %draw a rectangular box around the characters within the defined range.
+SHADE_REGION <start_res> <start_seq> <end_res> <end_seq> <grey>
+ %shade the region by the chosed grey value.
+
+9. Add option to place arbitrary text string at a character location.
+e.g
+ TEXT 1 7 "SIGNAL PEPTIDE" %puts this text at sequence position 1 7.
+ %to change fonts use the FONT_RESIDUE or FONT_REGION commands.
+10. Add option to change fonts of identifiers.
+ID_FONT <sequence> <font>
+e.g.
+ ID_FONT 3 1 %sets font to 1 for sequence identifier 3
+ ID_FONT ALL 7 %uses font 7 for all identifiers
+
+19th June 1992:
+Still fiddling - must get back to some real work soon.
+Split alps away from the scanps program. Now have a separate main() for the routine.
+
+Add options to redefine all defaults: e.g. MAXslen (maximum sequence
+length etc.) Add arbitrary line drawing options: eg. LINE TOP 20 15 50
+draws a line along the top of the characters from residue 20 to 50 or
+sequence 15. Think about adding the option to change line thickness at
+different parts of the plot. Decide not to implement that option right
+now. Add option to include dummy sequences (ADD_SEQ)
+
+Check the programme compiles on the 386 PC. It does!
+Write documentation and brief report of the programme.
+
+22nd June 1992: Get back to some real work!
+
+19th October: Add SILENT_MODE Command and carriage returns to all .PS print statements.
+21st October: Add VERTICAL_SPACING command and ability to output multiple blocks per page.
+15th November: Add pipe options to alscript.c Tidy up file handling.
+
+6th December: Add Colour options.
+18th Jan 1993: Tidy up citations: modify Inverse chars to allow reversion.
+1 March 1993: Fix bug in colour option. Pass use_colour to ALDrawLines routine to
+ specify black for line colour. Previously, this was drawn in white
+ if coloured shading had been specified on the same characters.
+2 March 1993: Fix bug in colour option to output identifiers in black, not white!
+9 March 1993: Add NO_NUMBERS option to avoid printing residue numbers.
+24 March 1993: Add mask features.
+
+11 March 1994: At PERI - Add special text features - preliminary version only.
+ This permits strands and helices to be plotted as cylinders and arrows.
+ Special text features also permit triangles and circles etc etc. through
+ use of text command.
+
+23 May 1995: Numerous changes and additions over the last year - these
+include the option to colour backgrounds differently, ommission of
+idents on second and subsequent lines, helix, strand and other special
+characters, relative numbering, error checking of ranges on input,
+bounding box, screening, conservation colouring...
+
+
+*/
+
+#define TOKENS "\" ,\n\t" /* standard command token delimiters */
+#define POINT 72 /* Work in points throughout */
+#define C_ID_WIDTH 10 /* Default width for writing id's (in characters) */
+#define DEF_POINTSIZE 10.0
+#define X_OFFSET 40 /* offset for bottom lh corner of page (points) */
+#define Y_OFFSET 30
+#define DEF_YPOS 0 /* default first printinf position (character units) */
+#define LINE_WIDTH_FACTOR 0.05 /* Multiply pointsize by this to get linewidth */
+#define MAX_ADD_SEQ 10 /* Maximum number of ADD_SEQ commands allowed */
+
+/*#define MAX_S 10.5 max and min page side in inches */
+/*#define MIN_S 6.5 */
+/*#define MAXSIDE (MAX_S * POINT) Default Max and min dimensions of paper */
+/*#define MINSIDE (MIN_S * POINT) */
+
+#define SCREENSIZE 120 /* define default size for screen */
+
+
+int width = 0; /* max width and height of drawing area */
+int height = 0;
+char *tokens = TOKENS;
+
+float MAXside = 10.5 * POINT; /* values to hold Max and min page side in points */
+float MINside = 6.5 * POINT;
+
+int xoff = X_OFFSET;
+int yoff = Y_OFFSET;
+
+int Cidwidth = C_ID_WIDTH; /* width of id region in characters (left of sequence block)*/
+int Cseqwidth; /* width of sequence region in characters */
+int Cwidth; /* width/height of page in characters */
+int Cheight;
+int Xspace; /* spacing between characters in X */
+int Yspace; /* spacing between characters in Y */
+float XspaceFactor = 0.2; /* extra bit to add to horizontal character spacing */
+float YspaceFactor = 0.0; /* extra bit to add to vertical character spacing */
+float XshiftFactor = 0.12; /* *pointsize gives the shift for vertical lines */
+float YshiftFactor = 0.12; /* horizontal lines */
+
+int CseqTop = 0;
+int CseqVoffset = 0; /* vertical offset for sequence block (characters)*/
+int CtopSpace =0; /* extra space above sequence block (characters) */
+int CbottomSpace = 0; /* " " below " " " */
+int Csheet = 1; /* number of vertical splits in sequence block */
+
+int TVspace = 0; /* total vertical space reserved (characters)*/
+
+float Xshift = 0; /* offsets for drawing box lines */
+float Yshift = 0;
+float LineWidthFactor = LINE_WIDTH_FACTOR;
+
+float pointsize = DEF_POINTSIZE;
+int npage;
+
+int Vspacing = 0; /* vertical spacing in characters between blocks on a page */
+
+
+enum Orientations{
+ LANDSCAPE,
+ PORTRAIT
+};
+
+enum Spaces{
+ TOP,
+ BOTTOM
+};
+
+struct addseq {
+ int pos;
+ int num;
+};
+
+/* bit masks for the lines array */
+unsigned char LINE_LEFT = 1; /* mask for line at left of char */
+unsigned char LINE_RIGHT= 2; /* right */
+unsigned char LINE_TOP = 4; /* top */
+unsigned char LINE_BOTTOM=8; /* bottom */
+
+void ALOutId(struct seqdat *,int,unsigned char *colour,
+ unsigned char *,int,int,int,int, FILE *);
+void ALOutSeq(struct seqdat *,unsigned char **,
+ char ***,
+ unsigned char **,int ,unsigned char **,
+ unsigned char **text_colour,
+ unsigned char background_colour,
+ int ,int ,int ,int ,FILE *);
+void PSPutText(int,int,char *,FILE *);
+void PSPutChar(int,int,char,FILE *);
+void PSShowPage(FILE *);
+void ALSetFont(char *,int,FILE *);
+void ALCheckSinglePage(int ,int ,int );
+void ALSetPageLimits(void);
+void PSSetOrientation(int, FILE *);
+void PSPreamble(FILE *,int, int*, int screensize);
+void PSLandscape(FILE *);
+void PSPortrait(FILE *);
+void PSSetupPage(int,int,FILE *);
+void ALReserveSpace(int, int);
+void ALReportInfo(int, FILE *);
+char **ALCreateNumbers(int,int,int,int);
+char *ALCreateTicks(int,int,int);
+void ALOutTicks(char *,int,int,int,int,FILE *);
+void ALOutNumbers(char **,int,int,int,int,FILE *);
+void PSDrawBox(float,float,float,float,float,FILE *);
+void ALSimpleBox(int,int,int,int,float,FILE *);
+void PSline(float,float,float,float,FILE *);
+void ALLineChar(unsigned char **,int,int,unsigned char);
+void ALLineRes(unsigned char **,int,int,unsigned char);
+void ALDrawLines(unsigned char **,int,
+ unsigned char **left_line_colour,
+ unsigned char **right_line_colour,
+ unsigned char **top_line_colour,
+ unsigned char **bottom_line_colour,
+ int,int,int,int,int,int,FILE *);
+void ALBoxRes(unsigned char **,int,int);
+void ALDrawFills(signed char **,int ,unsigned char **,
+ int,int ,int,int ,int ,int, FILE *);
+void ALFilRes(signed char **,int,int,float);
+void ALBoxRegion(unsigned char **,int,int,int,int,int *);
+void ALFilRegion(signed char **,int ,int,int,int , int *,float);
+void ALSurroundChars(struct seqdat *,unsigned char **,int,int,int,int,int,char *);
+void ALShadeChars(struct seqdat *,signed char **,
+ int ,int,int,int,int,char *,float);
+void ALDefineFont(int,char *,float,FILE *);
+void echo(char *);
+void ALGetFourInt(int *,int *,int *,int *);
+void ALGetThreeInt(int *,int *,int *);
+void ALGetTwoInt(int *,int *);
+void ALFontChars(struct seqdat *,unsigned char **,
+ int,int,int,int,char *,unsigned char);
+void ALFontRegion(unsigned char **,int,int,int,int,unsigned char);
+void PSSetFont(unsigned char,FILE *);
+void ALDoLine(unsigned char **,int,int,int,int,int *);
+void ALSubChars(struct seqdat *,int,int,int,int,char,char);
+char ALChekSpace(const char *);
+void PSSetGrey(float,FILE *);
+void ALInverseChars(struct seqdat *,unsigned char **,int,int,int,int,char *);
+int Agetbloc(FILE *,struct seqdat *,int *);
+void ALDefineColour(int,char *coltype, float,float,float,FILE *);
+void ALSColChars(struct seqdat *,unsigned char **,
+ int,int,int,int,int,char *,unsigned char);
+void ALColourChars(struct seqdat *,unsigned char **,
+ int ,int,int,int,char *,unsigned char);
+void ALColRes(unsigned char **,int ,int , int );
+void PSSetColour(unsigned char,FILE *);
+void ALColRegion(unsigned char **,int,int,int,int,int *,unsigned char);
+void ALColRRegion(unsigned char **,int,int,int,int,unsigned char);
+void ckdd(struct seqdat *, int);
+int Ifound(struct seqdat *,int,int,char *,int);
+void ALSColMask(unsigned char **,unsigned char **,
+ int, int, int, int,int, unsigned char);
+void ALInverseMask(unsigned char **,unsigned char **,int, int, int, int);
+void ALFontMask(unsigned char **,unsigned char **,int, int, int, int,unsigned char);
+void ALShadeMask(unsigned char **,signed char **,int,int,int,int,int *, float);
+void ALGetAllRange(int *, int *, int *, int *,int ,int );
+void ALid_mask(unsigned char **,struct seqdat *,int, int, int, int, int, char *, char *);
+void ALfre_mask(unsigned char **mask,struct seqdat *,int, int, int, int, char *, char *);
+int Ifound(struct seqdat *,int,int,char *,int);
+void ALagree_mask(unsigned char **,struct seqdat *,int,int,int,int,int);
+void ALnot_mask(unsigned char **,int, int, int, int);
+void ALsub_mask(unsigned char **,struct seqdat *,int, int, int, int, char);
+void ALMask(unsigned char **,int, int, int, int);
+void ALConsMask(unsigned char **mask,
+int sx,int sy,int ex,int ey,int *consval,int conscut);
+void ALColourMask(unsigned char **,unsigned char **,int,int,int,int,unsigned char);
+void ALSurroundMask(unsigned char **,struct seqdat *,unsigned char **,int,int,int,int,int);
+int save_pir(struct seqdat *,int,FILE *);
+void ALDrawHorizLine(
+ float Xpos, /* bottom left hand corner of character posn */
+ float Ypos, /* */
+ float Xspace, /* horizontal width of character position */
+ float Yspace, /* vertical height of character position */
+ float width_fac,FILE *outf); /* proportion of vertical height that the line will fill */
+void ALDrawRightArrow(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawLeftArrow(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawUpArrow(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawDownArrow(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawCircle(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawPseudoEllipse(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,
+ FILE *outf);
+void ALDrawLeftSemiEnd(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawRightSemiEnd(float Xpos,float Ypos, float Xspace,
+ float Yspace, float width_fac,FILE *outf);
+void ALDrawRightHalfHorizLine(float Xpos,float Ypos,float Xspace,
+ float Yspace,float width_fac,FILE *outf);
+void ALDrawLeftHalfHorizLine(float Xpos,float Ypos,float Xspace,float
+ Yspace,float width_fac,FILE *outf);
+void PSmoveto(float x,float y,FILE *outf);
+void PSlineto(float x,float y,FILE *outf);
+void PSPutSpecialText(float Xpos,float Ypos,float Xspace,
+ float Yspace,char *text,unsigned char current_col,
+ unsigned char background_colour,
+ float YspaceFactor,FILE *outf);
+void PSstroke(FILE *outf);
+void PSnewpath(FILE *outf);
+void ALColourBackground(FILE *outf,int colour,int *background_region);
+void ALCheckLegalRange(int sx,int sy, int ex, int ey, int xmin, int ymin, int xmax, int ymax);
+void ALMakeCoilText(int sx, int sy, int ex, char ***texts);
+void ALMakeStrandText(int sx, int sy, int ex, char ***texts);
+void ALMakeHelixText(int sx, int sy, int ex, char ***texts);
+int ALrel(char *pos,int *relnum);
+int GJindex(char *str,char c);
+float mzcons(unsigned char *pos,int n);
+int *ALCalCons(struct seqdat *bloc,
+ int sx,int sy,int ex,int ey,int *ret_val,int len);
+int save_msf(struct seqdat *bloc,int nseq,FILE *msff);
+
+int alps(char *command_file,int silent, int pipe, int singlepage)
+{
+ FILE *cf,*inf,*outf,*pirf,*msff;
+ char *buff;
+ char *token;
+ char *charstring;
+ struct seqdat *bloc;
+ struct seqdat *temp;
+ int orientation;
+ extern int MAXtlen,MAXnbloc;
+ extern int MAXilen,precis,MAXslen;
+ int nseq;
+ int start_aa;
+ int start_seq;
+ int i,j,k;
+ int totalpage;
+ char **numbers;
+ char *ticks;
+ unsigned char **lines;
+#ifdef VAX
+ char **fills;
+#else
+ signed char **fills;
+#endif
+ unsigned char **fonts;
+ unsigned char *idfonts;
+ unsigned char **inverse;
+ char ***texts;
+ int *Yindx;
+ int number_seqs = 0;
+
+ int Xtemp,Ytemp;
+ int sx,sy,ex,ey;
+
+ int fnum;
+ char *fname;
+ float fpoint;
+ int rowsiz;
+
+ char oldchar,newchar;
+
+ struct seqdat *addbloc;
+ struct addseq *adds;
+ int nadds;
+ int natot;
+ int l;
+ int do_ticks = 0;
+ int number_int = 10;
+ int pirsave = 0;
+ int msfsave = 0;
+
+ int nbp,nspage; /*counter and total for number of blocks per page */
+ int lastY;
+ int nbpage;
+
+ /* bounding_box - allows explicit fiddling with the bounding_box */
+ int *bounding_box;
+
+ /* colours */
+ float red,green,blue;
+ unsigned char **s_colour; /*colour number for shading */
+ unsigned char **c_colour; /*colour number for characters */
+ /* new 4th Oct 1994 */
+ unsigned char *id_colour; /*colour for identifiers */
+ unsigned char **left_line_colour; /*colours for lines */
+ unsigned char **right_line_colour;
+ unsigned char **top_line_colour;
+ unsigned char **bottom_line_colour;
+ unsigned char **text_colour; /*colour for text */
+ char *colname;
+
+ int background_colour = 99; /*set background to white */
+ int *background_region; /* use this to set the region for background colouring */
+
+ int number_colour = 100; /* colour for numbers along top of plot */
+ /* end new */
+ char *tstring;
+
+ int use_colour; /* flag set if the define_colour command is seen */
+ int res_numbers;
+
+ int msl;
+
+ /* min and max ranges in the sequence alignment */
+ int xmin, ymin, xmax, ymax;
+
+ /* masking variables */
+ unsigned char **mask;
+ char *illegal;
+ char *legal;
+ int id_cut;
+
+ /* screen size variable - for printer screen */
+ int screensize = SCREENSIZE;
+
+ /* set up relative numbering - allows commands to follow
+ a specific sequence numbering
+ firstres defines the number of the first residue */
+ int relative_seq = 0;
+ int firstres = 0;
+ int i1;
+ int *relnum;
+ /* temp relnum */
+ int *trelnum;
+
+ /* flag for idents */
+ int id_only_on_first = 0;
+ int tempCseqwidth;
+ int tempCidwidth;
+
+ /* conservation values */
+ int *consval; /* array */
+ int conscut; /* cutoff */
+
+ /* counter for add_seq errors */
+ int adderr;
+
+ /* file streams */
+ extern FILE *std_in, *std_out, *std_err;
+
+ /* By default read and write to stdin and stdout */
+ outf = std_out;
+ inf = std_in;
+
+
+ /* default is no colour */
+ use_colour = 0;
+
+ /* if set, residue numbers are output */
+ res_numbers = 1;
+
+
+
+ /* set the bounding box to default values for portrait A4*/
+ bounding_box = (int *) GJmalloc(sizeof(int) * 4);
+ bounding_box[0] = 0;
+ bounding_box[1] = 0;
+ bounding_box[2] = 590;
+ bounding_box[3] = 826;
+
+ /* set the background colour region equal to the default bounding box */
+ background_region = (int *) GJmalloc(sizeof(int) * 4);
+ background_region[0] = 0;
+ background_region[1] = 0;
+ background_region[2] = 590;
+ background_region[3] = 826;
+
+ /* initialise the mask */
+ mask = NULL;
+ illegal = NULL;
+ legal = NULL;
+
+ adds = (struct addseq *) malloc(sizeof(struct addseq) * (MAX_ADD_SEQ+1));
+ nadds = 0;
+
+
+ fname = (char *) malloc(sizeof(char)*MAXtlen);
+
+ buff = (char *) malloc(MAXtlen * sizeof(char));
+ if(buff == NULL)error("No Space for buff",1);
+
+ if((cf = fopen(command_file,"r")) == NULL){
+ error("Cannot open ALSCRIPT command file",0);
+ return 0;
+ }
+
+ /*
+ This is a little inelegant at the moment - when I get the generalized
+ parser finished this could be cleaned up substantially
+ */
+
+ /* main loop to read commands */
+ if(pipe){
+ /* Alscript is being used as a pipe so write preamble to std_out */
+ outf = std_out;
+ PSPreamble(outf,singlepage,bounding_box,screensize);
+ }
+
+ if(!silent)fprintf(std_err,"Starting ALSCRIPT\n");
+
+ while(buff = fgets(buff,MAXtlen,cf)){
+ if(!silent)echo(buff);
+ if(buff == NULL) continue;
+ token = strtok(buff,TOKENS);
+ if(token == NULL) continue;
+ token = GJstoup(token);
+ if(*token == '#'){
+ if(!silent)echo("Comment\n");
+ }else if(strcmp(token,"SILENT_MODE")==0){
+ if(!silent){
+ silent=1;
+ }else{
+ silent=0;
+ }
+ }else if(strcmp(token,"MAX_INPUT_LEN")==0){
+ if(!silent) fprintf(std_err,"Max input len was:\t%d\n",MAXtlen);
+ token = strtok(NULL,TOKENS);
+ MAXtlen = atoi(token);
+ if(!silent)fprintf(std_err,"Max input len now:\t%d\n",MAXtlen);
+ }else if(strcmp(token,"MAX_NSEQ")==0){
+ if(!silent)fprintf(std_err,"Max No. of sequences was:\t%d\n",MAXnbloc);
+ token = strtok(NULL,TOKENS);
+ MAXnbloc = atoi(token);
+ MAXtlen = MAXnbloc;
+ fprintf(std_err,"Max No. of sequences now:\t%d\n",MAXnbloc);
+ }else if(strcmp(token,"MAX_ILEN")==0){
+ if(!silent)fprintf(std_err,"Max Identifier length was:\t%d\n",MAXilen);
+ token = strtok(NULL,TOKENS);
+ MAXilen = atoi(token);
+ if(!silent)fprintf(std_err,"Max Identifier length now:\t%d\n",MAXilen);
+ }else if(strcmp(token,"PRECISION")==0){
+ token = strtok(NULL,TOKENS);
+ precis = atoi(token);
+ }else if(strcmp(token,"MAX_SEQ_LEN")==0){
+ if(!silent)fprintf(std_err,"Max Sequence Length was:\t%d\n",MAXslen);
+ token = strtok(NULL,TOKENS);
+ MAXslen = atoi(token);
+ if(!silent)fprintf(std_err,"Max Sequence Length now:\t%d\n",MAXslen);
+ }else if(strcmp(token,"X_OFFSET")==0){
+ if(!silent)fprintf(std_err,"X offset was:\t%d\n",xoff);
+ token = strtok(NULL,TOKENS);
+ xoff = atoi(token);
+ if(!silent)fprintf(std_err,"X offset now:\t%d\n",xoff);
+ }else if(strcmp(token,"Y_OFFSET")==0){
+ if(!silent)fprintf(std_err,"Y offset was:\t%d\n",yoff);
+ token = strtok(NULL,TOKENS);
+ yoff = atoi(token);
+ if(!silent)fprintf(std_err,"Y offset now:\t%d\n",yoff);
+ }else if(strcmp(token,"MAX_SIDE")==0){
+ if(!silent)fprintf(std_err,"Longest page side was:\t%.2f inches\n",MAXside/POINT);
+ token = strtok(NULL,TOKENS);
+ MAXside = POINT * atof(token);
+ if(!silent)fprintf(std_err,"Longest page side now:\t%.2f inches\n",MAXside/POINT);
+ }else if(strcmp(token,"MIN_SIDE")==0){
+ if(!silent)fprintf(std_err,"Shortest page side was:\t%.2f inches\n",MINside/POINT);
+ token = strtok(NULL,TOKENS);
+ MINside = POINT * atof(token);
+ if(!silent)fprintf(std_err,"Shortest page side now:\t%.2f inches\n",MINside/POINT);
+ }else if(strcmp(token,"LINE_WIDTH_FACTOR")==0){
+ if(!silent)fprintf(std_err,"Line width multiplication factor was:\t%f\n",LineWidthFactor);
+ token = strtok(NULL,TOKENS);
+ LineWidthFactor = atof(token);
+ if(!silent)fprintf(std_err,"Line width multiplication factor now:\t%f\n",LineWidthFactor);
+ }else if(strcmp(token,"SCREENSIZE")==0){
+ if(!silent)fprintf(std_err,"Screensize was:\t%d\n",screensize);
+ token = strtok(NULL,TOKENS);
+ screensize = atoi(token);
+ if(!silent)fprintf(std_err,"Screensize now:\t%d\n",screensize);
+ }else if(strcmp(token,"BLOCK_FILE") == 0){
+ token = strtok(NULL,TOKENS);
+ if(!pipe){
+ inf = fopen(token,"r");
+ if(inf == NULL)error("Cannot open BLOCK_FILE\n",1);
+ }
+ }else if(strcmp(token,"OUTPUT_FILE")==0){
+ token = strtok(NULL,TOKENS);
+ if(!pipe){
+ outf = fopen(token,"w");
+ if(outf == NULL)error("Cannot open OUTPUT_FILE\n",1);
+ PSPreamble(outf,singlepage,bounding_box,screensize);
+ }
+ }else if(strcmp(token,"PIR_SAVE")==0){
+ token = strtok(NULL,TOKENS);
+ pirf = fopen(token,"w");
+ if(pirf == NULL)error("Cannot open PIR_SAVE file\n",1);
+ pirsave = 1;
+ }else if(strcmp(token,"MSF_SAVE")==0){
+ token = strtok(NULL,TOKENS);
+ msff = fopen(token,"w");
+ if(msff == NULL)error("Cannot open MSF_SAVE file\n",1);
+ msfsave = 1;
+ }else if(strcmp(token,"LANDSCAPE")==0){
+ orientation = LANDSCAPE;
+ }else if(strcmp(token,"PORTRAIT")==0){
+ orientation = PORTRAIT;
+
+ }else if(strcmp(token,"POINTSIZE")==0){
+ token = strtok(NULL,TOKENS);
+ pointsize = atof(token);
+ }else if(strcmp(token,"IDENT_WIDTH")==0){
+ token = strtok(NULL,TOKENS);
+ Cidwidth = atoi(token);
+ if(Cidwidth > MAXilen)error("INCREASE MAX_ID_LEN value",1);
+ }else if(strcmp(token,"NUMBER_SEQS")==0){
+ number_seqs=1;
+ }else if(strcmp(token,"X_SPACE_FACTOR")==0){
+ if(!silent)fprintf(std_err,"Was:\t%.2f\n",XspaceFactor);
+ token = strtok(NULL,TOKENS);
+ XspaceFactor = atof(token);
+ if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",XspaceFactor);
+ }else if(strcmp(token,"Y_SPACE_FACTOR")==0){
+ if(!silent)fprintf(std_err,"Was:\t%.2f\n",YspaceFactor);
+ token = strtok(NULL,TOKENS);
+ YspaceFactor = atof(token);
+ }else if(strcmp(token,"X_SHIFT_FACTOR")==0){
+ if(!silent)fprintf(std_err,"Was:\t%.2f\n",XshiftFactor);
+ token = strtok(NULL,TOKENS);
+ XshiftFactor = atof(token);
+ if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",XshiftFactor);
+ }else if(strcmp(token,"Y_SHIFT_FACTOR")==0){
+ if(!silent)fprintf(std_err,"Was:\t%.2f\n",YshiftFactor);
+ token = strtok(NULL,TOKENS);
+ YshiftFactor = atof(token);
+ if(!silent)fprintf(std_err,"Now Is:\t%.2f\n",YshiftFactor);
+ }else if(strcmp(token,"VERTICAL_SPACING")==0){
+ if(!silent)fprintf(std_err,"Was:\t%d\n",Vspacing);
+ token = strtok(NULL,TOKENS);
+ Vspacing = (int) atol(token);
+ if(!silent)fprintf(std_err,"Now Is:\t%d\n",Vspacing);
+ }else if(strcmp(token,"DEFINE_FONT")==0){
+ token = strtok(NULL,TOKENS);
+ fnum = atoi(token); /* font number */
+ token = strtok(NULL,TOKENS); /* font name */
+ fname = strcpy(fname,token);
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"DEFAULT")==0){
+ fpoint = pointsize;
+ }else if(strcmp(token,"REL")==0){
+ token = strtok(NULL,TOKENS);
+ fpoint = pointsize * atof(token);
+ }else{
+ fpoint = atof(token);
+ }
+ ALDefineFont(fnum,fname,fpoint,outf);
+ }else if(strcmp(token,"DEFINE_COLOUR")==0 || strcmp(token,"DEFINE_COLOR")==0){
+ /* new style
+ define_colour <colour_number | colour type> colour_name r g b <colour_number> */
+ /* e.g. define_colour 1 1.0 1.0 1.0
+ (same as before)
+ define_colour rgb red 1.0 0.0 0.0 7
+ (define an rgb colour (red,green,blue),colour_number)
+ define_colour hsb red 1.0 0.0 0.0 9
+ (define an hsb colour (hue,sat,bright),colour_number)
+ currently can use either hsb OR rgb, but not mix them
+ */
+ use_colour = 1;
+ token = strtok(NULL,TOKENS);
+ tstring = GJstoupper(token);
+ if(strcmp(tstring,"RGB")==0 || strcmp(tstring,"HSB")==0){
+ token = strtok(NULL,TOKENS);
+ colname = GJstrdup(token);
+ token = strtok(NULL,TOKENS);
+ red = atof(token);
+ token = strtok(NULL,TOKENS);
+ green = atof(token);
+ token = strtok(NULL,TOKENS);
+ blue = atof(token);
+ token = strtok(NULL,TOKENS);
+ fnum = atoi(token);
+ }else{
+ fnum = atoi(token); /* colour number */
+ token = strtok(NULL,TOKENS);
+ red = atof(token);
+ token = strtok(NULL,TOKENS);
+ green = atof(token);
+ token = strtok(NULL,TOKENS);
+ blue = atof(token);
+
+ }
+ /* for now just ignore the colour name - we'll allow use of this later */
+ ALDefineColour(fnum,tstring,red,green,blue,outf);
+ GJfree(tstring);
+ }else if(strcmp(token,"ADD_SEQ")==0){
+ token = strtok(NULL,TOKENS);
+ adds[nadds].pos = atoi(token);
+ token = strtok(NULL,TOKENS);
+ adds[nadds].num = atoi(token);
+ ++nadds;
+ }else if(strcmp(token,"DO_TICKS")==0){
+ do_ticks=1;
+ }else if(strcmp(token,"NUMBER_INT")==0){
+ token = strtok(NULL,TOKENS);
+ number_int = atoi(token);
+ if(!silent)fprintf(std_err,"Sequence Numbering interval now:\t%d\n",number_int);
+ }else if(strcmp(token,"NO_NUMBERS")==0){
+ res_numbers = 0;
+ }else if(strcmp(token,"NUMBER_COLOUR")==0){
+ token = strtok(NULL,TOKENS);
+ number_colour = atoi(token);
+ }else if(strcmp(token,"SINGLE_PAGE")==0){
+ /* if this is set, then alscript assumes a single page -
+ just adds a bounding box for now*/
+ if(!silent)fprintf(std_err,"Single page was: %d\n",singlepage);
+ singlepage = 1;
+ if(!silent)fprintf(std_err,"Single page now: %d\n",singlepage);
+ }else if(strcmp(token,"BOUNDING_BOX")==0){
+ ALGetFourInt(&bounding_box[0],&bounding_box[1],
+ &bounding_box[2],&bounding_box[3]);
+ if(!silent){
+ fprintf(std_err,"Bounding box set to: %d %d %d %d\n",
+ bounding_box[0],bounding_box[1],
+ bounding_box[2],bounding_box[3]);
+ }
+ }else if(strcmp(token,"BACKGROUND_REGION") == 0){
+ /* set the region of the background to colour */
+ ALGetFourInt(&background_region[0],&background_region[1],
+ &background_region[2],&background_region[3]);
+ if(!silent){
+ fprintf(std_err,"Background region set to: %d %d %d %d\n",
+ background_region[0],background_region[1],
+ background_region[2],background_region[3]);
+ }
+ }else if(strcmp(token,"ID_ONLY_ON_FIRST_LINE")==0){
+ /* flag to indicate identifiers only on first line!*/
+ id_only_on_first = 1;
+ }else if(strcmp(token,"BACKGROUND_COLOUR") ==0){
+ /* set the colour for background defined by background_region */
+ token = strtok(NULL,TOKENS);
+ background_colour = atoi(token);
+ }else if(strcmp(token,"SETUP")==0){
+ if(!silent)fprintf(std_err,"Initial Commands read - Establishing basic settings\n");
+ break;
+ }else{
+ fprintf(std_err,"%s",buff);
+ error("Unrecognised Step 1 command",1);
+
+ }
+ }
+
+ if(outf == std_out){
+ if(!silent)fprintf(std_err,"Output file undefined - will write to stdout\n");
+ }
+
+
+ if(inf == std_in){
+ if(!silent)fprintf(std_err,"Block file undefined - will read from stdin\n");
+ }
+
+ bloc = (struct seqdat *) malloc(sizeof(struct seqdat) * MAXnbloc);
+ mcheck((char *) bloc,"Cannot get space for bloc");
+ if(!Agetbloc(inf,bloc,&nseq))error("Cannot read bloc file",1);
+
+ ckdd(bloc,nseq);
+
+ if(pirsave){
+ if(!save_pir(bloc,nseq,pirf))error("Cannot write to pirf file",1);
+ exit(0);
+ }
+
+ if(msfsave){
+ if(!save_msf(bloc,nseq,msff))error("Cannot write to msf file",1);
+ exit(0);
+ }
+
+ /* Initialise relnum to 1..n*/
+ /* relnum = (int *) GJmalloc(sizeof(int) * MAXslen); */
+ /* for(i=1;i<MAXslen;++i){ */
+ /* relnum[i]=i; */
+ /* } */
+
+ /* Initialise relnum to 1..n*/
+ /* 29 July 1998 - allocate relnum to MAXslen *2. with pointer in the middle */
+
+ trelnum = (int *) GJmalloc(sizeof(int) * MAXslen * 2);
+ for(i=1;i<(MAXslen +1);++i){
+ trelnum[i]=0;
+ }
+ relnum = &trelnum[MAXslen];
+ for(i=1;i<MAXslen;++i){
+ relnum[i] = i;
+ }
+
+ /* do a check of the adds array to make sure there are no out of bounds
+ requests
+ */
+ adderr = 0;
+ for(i=0;i<nadds;++i){
+ if(adds[i].pos > nseq){
+ ++adderr;
+ fprintf(std_err,"Error in ADD_SEQ request: %d %d\n",adds[i].pos,adds[i].num);
+ fprintf(std_err,"%d is greater than the number of sequences in the block file(%d)\n",adds[i].pos,nseq);
+ fprintf(std_err,"Please see the manual for help on using ADD_SEQ\n");
+ }
+ }
+ if(adderr > 0){
+ fprintf(std_err,"%d ADD_SEQ errors - exiting\n",adderr);
+ exit(-1);
+ }
+
+
+ if(nadds > 0){
+ if(!silent)fprintf(std_err,"Making extra space for %d additions\n",nadds);
+ natot = 0;
+ for(i=0;i<nadds;++i){
+ natot += adds[i].num;
+ }
+ if(!silent)fprintf(std_err,"Total of %d extra sequences\n",natot);
+ addbloc = (struct seqdat *) malloc(sizeof(struct seqdat) *(nseq+natot+1));
+ i = 0;
+ j = 0;
+ k = 0;
+ while(i < nseq+1){
+ if(k < nadds && i==adds[k].pos){
+ /* reserve space for the new sequences and set to blank*/
+ for(l=0;l<adds[k].num;++l){
+ ++j;
+ addbloc[j].id = (char *) malloc(sizeof(char) * MAXilen);
+ addbloc[j].id = GJstrblank(addbloc[j].id,MAXilen);
+ addbloc[j].seq = (char *) malloc(sizeof(char) * (bloc[1].slen+1));
+ addbloc[j].seq = GJstrblank(addbloc[j].seq,bloc[1].slen+1);
+ }
+ ++k;
+ }else{
+ /* just copy the pointers to the bloc sequences */
+ ++i;
+ ++j;
+ if(i<nseq+1){
+ addbloc[j].id = bloc[i].id;
+ addbloc[j].title = bloc[i].title;
+ addbloc[j].seq = bloc[i].seq;
+ }
+ }
+ }
+ addbloc[1].slen = bloc[1].slen;
+ temp = bloc;
+ bloc = addbloc;
+ addbloc = temp;
+ nseq += natot;
+ if(!silent)fprintf(std_err,"Total number of sequences now: %d\n",nseq);
+ }
+ msl = bloc[1].slen-2; /* maximum sequence length defined */
+
+ xmin = 1; ymin = 1; xmax = msl+1; ymax = nseq;
+
+ PSSetupPage(orientation,1,outf);
+ ALSetPageLimits();
+
+ CtopSpace = 2; /* set top 2 lines for numbers */
+
+ /* now set up the bounding box and background
+ based on current values of xoff, yoff, width and height
+ these can be overridden by step 2 commands
+
+ bounding_box[0] = 0;
+ bounding_box[1] = 0;
+ bounding_box[2] = width;
+ bounding_box[3] = height;
+ */
+
+ /* set the background colour region equal to the default bounding box
+ background_region[0] = bounding_box[0];
+ background_region[1] = bounding_box[1];
+ background_region[2] = bounding_box[2];
+ background_region[3] = bounding_box[3];
+ */
+
+ if(background_colour != 99)ALColourBackground(outf,background_colour,background_region);
+
+
+
+/* TVspace = nseq;*/
+/* ALReserveSpace(TOP,2);*/
+
+
+ /* allocate to +1 size to allow indexing from 1...max */
+ /* lines array - stored info on where to draw lines */
+ lines = uchararr(bloc[1].slen+1,nseq+1);
+ if(lines == NULL)error("No space for lines array\n",1);
+ GJUCinit(lines,bloc[1].slen+1,nseq+1,0);
+
+ /* array holds grey value for each character fill*/
+ fills = chararr(bloc[1].slen+1,nseq+1);
+ if(fills == NULL)error("No space for fills array\n",1);
+ GJCinit(fills,bloc[1].slen+1,nseq+1,-1);
+
+ /* allocate to +1 size to allow indexing from 1...max */
+ /* fonts array - stores a number representing the font to use for each residue */
+ /* default font is font 0 */
+ fonts = uchararr(bloc[1].slen+1,nseq+1);
+ if(fonts == NULL)error("No space for fonts array\n",1);
+ GJUCinit(fonts,bloc[1].slen+1,nseq+1,0);
+
+ /* inverse indicates whether the the text at i j should be printed in white */
+ inverse = uchararr(bloc[1].slen+1,nseq+1);
+ if(inverse == NULL)error("No space for inverse array\n",1);
+ GJUCinit(inverse,bloc[1].slen+1,nseq+1,0);
+
+ /* colour arrays - define the colour to use for shading and lettering */
+ /* default colour numbers are 99 for white and 100 for black */
+ s_colour = uchararr(bloc[1].slen+1,nseq+1); /* shading colour */
+ if(s_colour == NULL)error("No space for s_colour array\n",1);
+ GJUCinit(s_colour,bloc[1].slen+1,nseq+1,background_colour);
+ c_colour = uchararr(bloc[1].slen+1,nseq+1); /* character colour */
+ if(c_colour == NULL)error("No space for c_colour array\n",1);
+ GJUCinit(c_colour,bloc[1].slen+1,nseq+1,100);
+ left_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* left line colour */
+ if(left_line_colour == NULL)error("No space for left_line_colour array\n",1);
+ GJUCinit(left_line_colour,bloc[1].slen+1,nseq+1,100);
+ right_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* right line colour */
+ if(right_line_colour == NULL)error("No space for right_line_colour array\n",1);
+ GJUCinit(right_line_colour,bloc[1].slen+1,nseq+1,100);
+ top_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* top line colour */
+ if(top_line_colour == NULL)error("No space for top_line_colour array\n",1);
+ GJUCinit(top_line_colour,bloc[1].slen+1,nseq+1,100);
+ bottom_line_colour = uchararr(bloc[1].slen+1,nseq+1); /* bottom line colour */
+ if(bottom_line_colour == NULL)error("No space for bottom_line_colour array\n",1);
+ GJUCinit(bottom_line_colour,bloc[1].slen+1,nseq+1,100);
+ text_colour = uchararr(bloc[1].slen+1,nseq+1); /* text colour */
+ if(text_colour == NULL)error("No space for text_colour array\n",1);
+ GJUCinit(text_colour,bloc[1].slen+1,nseq+1,100);
+
+ /* holds font information for each identifier */
+ idfonts = (unsigned char *) malloc(sizeof(unsigned char) * nseq+1);
+ for(i=0;i<nseq+1;++i){
+ idfonts[i]= (unsigned char) 0;
+ }
+ /* holds colour information for each identifier */
+ id_colour = (unsigned char *) GJmalloc(sizeof(unsigned char) * nseq+1);
+ for(i=0;i<nseq+1;++i){
+ id_colour[i]= (unsigned char) 100;
+ }
+ /* holds conservation values */
+ consval = (int *) GJmalloc(sizeof(int) * bloc[1].slen);
+ GJIinit(consval,bloc[1].slen,0);
+
+
+ /* array holds pointers to text strings at each [i][j] point*/
+ texts = (char ***) malloc(sizeof(char **) * (bloc[1].slen+1));
+ rowsiz = sizeof(char *) * (nseq + 1);
+ for(k=0;k<bloc[1].slen+1;++k){
+ texts[k] = (char **) malloc(rowsiz);
+ for(i=0;i<(nseq+1);++i){
+ texts[k][i]=NULL;
+ }
+ }
+
+ Yindx = (int *) malloc(sizeof(int)*(nseq+1));
+ for(i=1,j=nseq;i<nseq+1;++i,--j){
+ Yindx[i] = j;
+ }
+
+ numbers = ALCreateNumbers(0,number_int,bloc[1].slen,4);
+ ticks = ALCreateTicks(0,number_int,bloc[1].slen);
+ CseqTop = nseq;
+
+ while(buff = fgets(buff,MAXtlen,cf)){
+ if(buff == NULL) break;
+ if(!silent)echo(buff);
+ token = strtok(buff,TOKENS);
+ if(token == NULL) break;
+ token = GJstoup(token);
+ if(*token == '#'){
+ if(!silent)echo("Comment\n");
+ }else if(strcmp(token,"SILENT_MODE")==0){
+ if(!silent){
+ silent=1;
+ }else{
+ silent=0;
+ }
+/* This block has moved to the MODE 1 section
+ }else if(strcmp(token,"BOUNDING_BOX")==0){
+ ALGetFourInt(&bounding_box[0],&bounding_box[1],
+ &bounding_box[2],&bounding_box[3]);
+
+ }else if(strcmp(token,"BACKGROUND_REGION") == 0){
+ set the region of the background to colour
+ ALGetFourInt(&background_region[0],&background_region[1],
+ &background_region[2],&background_region[3]);
+*/
+ }else if(strcmp(token,"RESERVE_SPACE_TOP")==0){
+ token = strtok(NULL,TOKENS);
+ ALReserveSpace(TOP,atoi(token));
+ }else if(strcmp(token,"RESERVE_SPACE_BOTTOM")==0){
+ token = strtok(NULL,TOKENS);
+ ALReserveSpace(BOTTOM,atoi(token));
+ CseqTop = nseq + CbottomSpace;
+ }else if(strcmp(token,"SURROUND_CHARS")==0){
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALSurroundChars(bloc,lines,relnum[sx],sy,relnum[ex],ey,nseq,charstring);
+ }else if(strcmp(token,"SHADE_CHARS")==0){
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALShadeChars(bloc,fills,relnum[sx],sy,relnum[ex],ey,nseq,charstring,(float)atof(token));
+ }else if(strcmp(token,"FONT_CHARS")==0){
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALFontChars(bloc,fonts,relnum[sx],sy,relnum[ex],ey,charstring,atoi(token));
+ }else if(strcmp(token,"CCOL_CHARS")==0){ /* colour characters */
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColourChars(bloc,c_colour,relnum[sx],sy,relnum[ex],ey,charstring,atoi(token));
+ }else if(strcmp(token,"SCOL_CHARS")==0){ /* colour character backgrounds */
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALSColChars(bloc,s_colour,relnum[sx],sy,relnum[ex],ey,nseq,charstring,(unsigned char) atoi(token));
+ }else if(strcmp(token,"INVERSE_CHARS")==0){
+ token = strtok(NULL,TOKENS);
+ charstring = token;
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALInverseChars(bloc,inverse,relnum[sx],sy,relnum[ex],ey,charstring);
+ }else if(strcmp(token,"SUB_CHARS")==0){
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"ALL")==0){
+ token = strtok(NULL,TOKENS);
+ oldchar = ALChekSpace(token);
+ token = strtok(NULL,TOKENS);
+ newchar = ALChekSpace(token);
+ ALSubChars(bloc,1,1,bloc[1].slen-1,nseq,oldchar,newchar);
+ }else{
+ sx = atoi(token);
+ ALGetThreeInt(&sy,&ex,&ey);
+ token = strtok(NULL,TOKENS);
+ oldchar = ALChekSpace(token);
+ token = strtok(NULL,TOKENS);
+ newchar = ALChekSpace(token);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALSubChars(bloc,relnum[sx],sy,relnum[ex],ey,oldchar,newchar);
+ }
+ }else if(strcmp(token,"SUB_ID")==0){
+ token = strtok(NULL,"\"");
+ sx = atoi(token);
+ token = strtok(NULL,"\"");
+ ALCheckLegalRange(xmin,1,xmax,sx,xmin,ymin,xmax,ymax);
+ bloc[sx].id = (char *) realloc(bloc[sx].id,sizeof(char)*(strlen(token)+1));
+ bloc[sx].id = strcpy(bloc[sx].id,token);
+ }else if(strcmp(token,"FONT_REGION")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ token = strtok(NULL,TOKENS);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALFontRegion(fonts,relnum[sx],sy,relnum[ex],ey,atoi(token));
+ }else if(strcmp(token,"FONT_RESIDUE")==0){
+ token = strtok(NULL,TOKENS);
+ sx = atoi(token);
+ token=strtok(NULL,TOKENS);
+ sy = atoi(token);
+ token=strtok(NULL,TOKENS);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
+ ALFontRegion(fonts,relnum[sx],sy,relnum[sx],sy,atoi(token));
+ }else if(strcmp(token,"LINE")==0){
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"TOP")==0){
+ ALGetThreeInt(&sx,&sy,&ex);
+ if(ex > bloc[1].slen-1) ex = bloc[1].slen-1;
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
+ ALDoLine(lines,relnum[sx],sy,relnum[ex],LINE_TOP,Yindx);
+ }else if(strcmp(token,"BOTTOM")==0){
+ ALGetThreeInt(&sx,&sy,&ex);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
+ if(ex > bloc[1].slen-1) ex = bloc[1].slen-1;
+ ALDoLine(lines,relnum[sx],sy,relnum[ex],LINE_BOTTOM,Yindx);
+ }else if(strcmp(token,"LEFT")==0){
+ ALGetThreeInt(&sx,&sy,&ey);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],ey,xmin,ymin,xmax,ymax);
+ if(ey > nseq) ey = nseq;
+ ALDoLine(lines,relnum[sx],sy,ey,LINE_LEFT,Yindx);
+ }else if(strcmp(token,"RIGHT")==0){
+ ALGetThreeInt(&sx,&sy,&ey);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],ey,xmin,ymin,xmax,ymax);
+ if(ey > nseq) ey = nseq;
+ ALDoLine(lines,relnum[sx],sy,ey,LINE_RIGHT,Yindx);
+ }else{
+ error("Illegal LINE command\n",1);
+ }
+ }else if(strcmp(token,"BOX_REGION")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALBoxRegion(lines,relnum[sx],sy,relnum[ex],ey,Yindx);
+ }else if(strcmp(token,"SHADE_REGION")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALFilRegion(fills,relnum[sx],sy,relnum[ex],ey,Yindx,(float)atof(token));
+ }else if(strcmp(token,"SHADE_RES")==0){
+ ALGetTwoInt(&sx,&sy);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALFilRegion(fills,relnum[sx],sy,relnum[sx],sy,Yindx,(float)atof(token));
+ }else if(strcmp(token,"COLOUR_REGION")==0 || strcmp(token,"COLOR_REGION")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColRegion(s_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
+ }else if(strcmp(token,"COLOUR_TEXT_REGION")==0 || strcmp(token,"COLOR_TEXT_REGION")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColRRegion(text_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
+ }else if(strcmp(token,"COLOUR_RES")==0 || strcmp(token,"COLOR_RES")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetTwoInt(&sx,&sy);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColRRegion(s_colour,relnum[sx],sy,relnum[sx],sy,(unsigned char) atoi(token));
+ }else if(strcmp(token,"CCOLOUR_REGION")==0 || strcmp(token,"CCOLOR_REGION")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColRRegion(c_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
+ }else if(strcmp(token,"COLOUR_LINE_REGION")==0 || strcmp(token,"COLOR_LINE_REGION")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColRegion(left_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
+ ALColRegion(right_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
+ ALColRegion(top_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
+ ALColRegion(bottom_line_colour,relnum[sx],sy,relnum[ex],ey,Yindx,(unsigned char) atoi(token));
+ }else if(strcmp(token,"CCOLOUR_RES")==0 || strcmp(token,"CCOLOR_RES")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetTwoInt(&sx,&sy);
+ token = strtok(NULL,TOKENS);
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
+ ALColRRegion(c_colour,relnum[sx],sy,relnum[sx],sy,(unsigned char) atoi(token));
+ }else if(strcmp(token,"MASK")==0){
+ /* mask commands */
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"SETUP")==0){
+ if(mask == NULL){
+ mask = uchararr(bloc[1].slen+1,nseq+1);
+ GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
+ }else{
+ GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
+ }
+ }else if(strcmp(token,"RESET")==0){
+ GJUCinit(mask,bloc[1].slen+1,nseq+1,0);
+ }else if(strcmp(token,"LEGAL")==0){
+ /* get the legal character list */
+ token = strtok(NULL,TOKENS);
+ if(legal != NULL) GJfree(legal);
+ legal = GJstrdup(token);
+ if(!silent)fprintf(stderr,"legal:%s\n",legal);
+ }else if(strcmp(token,"ILLEGAL")==0){
+ /* get the illegal character list */
+ token = strtok(NULL,TOKENS);
+ if(illegal != NULL) GJfree(illegal);
+ illegal = GJstrdup(token);
+ if(!silent)fprintf(stderr,"illegal:%s:\n",illegal);
+ }else if(strcmp(token,"ID")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ id_cut = atoi(token);
+ if(id_cut < (int) ( ( ((float) (ey-sy+1) / 2.0) + 0.6))){
+ error("ID cutoff must be > half the number of sequences",1);
+ }
+ ALid_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,id_cut,legal,illegal);
+ }else if(strcmp(token,"AGREE")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token= strtok(NULL,TOKENS);
+ ALagree_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,atoi(token));
+ }else if(strcmp(token,"FRE")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALfre_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,legal,illegal);
+ }else if(strcmp(token,"NOT")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALnot_mask(mask,relnum[sx],sy,relnum[ex],ey);
+ }else if(strcmp(token,"SUB")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token=strtok(NULL,TOKENS);
+ ALsub_mask(mask,bloc,relnum[sx],sy,relnum[ex],ey,token[0]);
+ }else if(strcmp(token,"REGION")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALMask(mask,relnum[sx],sy,relnum[ex],ey);
+ }else if(strcmp(token,"CONSERVATION")==0){
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token=strtok(NULL,TOKENS);
+ conscut = atoi(token);
+ if(!silent)fprintf(std_err,"Conservation Cutoff:%d\n",conscut);
+ ALConsMask(mask,relnum[sx],sy,relnum[ex],ey,consval,conscut);
+ }else if(strcmp(token,"BOX")==0){
+ /* box the masked residues - ie surround them*/
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ ALSurroundMask(mask,bloc,lines,relnum[sx],sy,relnum[ex],ey,nseq);
+ }else if(strcmp(token,"SHADE")==0){
+ /* shade the masked residues - */
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALShadeMask(mask,fills,relnum[sx],sy,relnum[ex],ey,Yindx,(float)atof(token));
+ }else if(strcmp(token,"FONT")==0){
+ /* set the font of the masked residues - */
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALFontMask(mask,fonts,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
+ }else if(strcmp(token,"INVERSE")==0){
+ /* invert the masked residues - */
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALInverseMask(mask,inverse,relnum[sx],sy,relnum[ex],ey);
+ }else if(strcmp(token,"SCOL")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALSColMask(mask,s_colour,relnum[sx],sy,relnum[ex],ey,nseq,(unsigned char) atoi(token));
+ }else if(strcmp(token,"CCOL")==0){
+ if(!use_colour)error("You must use the DEFINE_COLOUR command first",1);
+ ALGetAllRange(&sx,&sy,&ex,&ey,xmax,nseq);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],ey,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ ALColourMask(mask,c_colour,relnum[sx],sy,relnum[ex],ey,(unsigned char) atoi(token));
+ }else{
+ error("Unrecognised MASK qualifier\n",1);
+ }
+ }else if(strcmp(token,"TEXT")==0){
+ token=strtok(NULL,TOKENS);
+ sx = atoi(token);
+ token=strtok(NULL,"\"");
+ sy = atoi(token);
+ token=strtok(NULL,"\"");
+ ALCheckLegalRange(relnum[sx],sy,relnum[sx],sy,xmin,ymin,xmax,ymax);
+ texts[relnum[sx]][sy] = (char *) malloc(sizeof(char)*(strlen(token)+1));
+ texts[relnum[sx]][sy] = (char *) strcpy(texts[relnum[sx]][sy],token);
+ }else if(strcmp(token,"NUMBERS")==0){
+ error("Numbers not implemented",1);
+ }else if(strcmp(token,"ID_FONT")==0){
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"ALL")==0){
+ token = strtok(NULL,TOKENS);
+ for(i=1;i<nseq+1;++i)idfonts[i]= (unsigned char) atoi(token);
+ }else{
+ sx = atoi(token);
+ token = strtok(NULL,TOKENS);
+ ALCheckLegalRange(xmin,ymin,xmax,sx,xmin,ymin,xmax,ymax);
+ idfonts[sx] = atoi(token);
+ }
+ }else if(strcmp(token,"ID_COLOUR")==0){
+ token = strtok(NULL,TOKENS);
+ if(strcmp(token,"ALL")==0){
+ token = strtok(NULL,TOKENS);
+ for(i=1;i<nseq+1;++i)id_colour[i]= (unsigned char) atoi(token);
+ }else{
+ sx = atoi(token);
+ ALCheckLegalRange(xmin,ymin,xmax,sx,xmin,ymin,xmax,ymax);
+ token = strtok(NULL,TOKENS);
+ id_colour[sx] = atoi(token);
+ }
+ }else if(strcmp(token,"HELIX")==0){
+ ALGetThreeInt(&sx,&sy,&ex);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
+ ALMakeHelixText(relnum[sx],sy,relnum[ex],texts);
+ }else if(strcmp(token,"STRAND")==0){
+ ALGetThreeInt(&sx,&sy,&ex);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
+ ALMakeStrandText(relnum[sx],sy,relnum[ex],texts);
+ }else if(strcmp(token,"COIL")==0){
+ ALGetThreeInt(&sx,&sy,&ex);
+ ALCheckLegalRange(relnum[sx],sy,relnum[ex],sy,xmin,ymin,xmax,ymax);
+ ALMakeCoilText(relnum[sx],sy,relnum[ex],texts);
+ }else if(strcmp(token,"CALCONS")==0){
+ /* calculate conservation for the range */
+ ALGetFourInt(&sx,&sy,&ex,&ey);
+ ALCheckLegalRange(relnum[sx],relnum[sy],relnum[ex],relnum[ey],xmin,ymin,xmax,ymax);
+ consval = ALCalCons(bloc,relnum[sx],relnum[sy],relnum[ex],relnum[ey],
+ consval,bloc[1].slen);
+/* fprintf(std_err,"Conservation Values\n"); */
+/* for(k=1;k<bloc[1].slen-1;++k){*/
+/* fprintf(std_err,"%d:%d\n",k,consval[k]);*/
+/* }*/
+ }else if(strcmp(token,"RELATIVE_TO")==0){
+ token = strtok(NULL,TOKENS);
+ relative_seq = atoi(token);
+ fprintf(stderr,"RELATIVE SEQ %d\n",relative_seq);
+ fprintf(stderr,"bloc[relative_seq].slen+1] %d\n",
+ bloc[relative_seq].slen+1);
+ token = strtok(NULL,TOKENS);
+ if(token != NULL){
+ /* there is a first residue definition */
+ firstres = atoi(token);
+ fprintf(stderr,"First position is number: %d\n",firstres);
+ }else{
+ firstres = 1;
+ }
+ if(relative_seq != 0){
+ k= firstres - 1;
+ for(i=1;i<bloc[1].slen+1;++i){
+ /* for now assume all gaps are blanks */
+ if(bloc[relative_seq].seq[i] != ' '){
+ ++k;
+ relnum[k] = i;
+ }
+ }
+ /* increase the max allowed X value to the max of xmax and k */
+ /* leave the minimum value at 1 since otherwise we will not be able to mix
+ absolute and relative numbers without the Check routine skwawking */
+ if(k > xmax ) xmax = k;
+ }else{
+ for(i=1;i<bloc[1].slen+1;++i){
+ relnum[i] = i;
+ }
+ }
+ }else{
+ fprintf(std_err,"%s",buff);
+ error("Unrecognised Step 2 command\n",1);
+ }
+ }
+ if(!silent){
+ ALReportInfo(nseq,std_err);
+ }
+ ALCheckSinglePage(nseq,bloc[1].slen,silent);
+
+ start_aa = 1;
+ totalpage = npage * Csheet;
+
+ /* get how many blocks of sequence we can fit per page */
+ nspage = Cheight/(nseq+CtopSpace+Vspacing);
+ if(nspage < 1){
+ nspage = 1;
+ }
+ nbp = 0;
+
+ if(!silent)fprintf(std_err,"Will write a maximum of %d blocks of sequence per page\n",nspage);
+ if(!silent)fprintf(std_err,"Background region: %d %d %d %d\n",
+ background_region[0],
+ background_region[1],
+ background_region[2],
+ background_region[3]);
+ if(!silent && singlepage)fprintf(std_err,"Bounding box: %d %d %d %d\n",
+ bounding_box[0],
+ bounding_box[1],
+ bounding_box[2],
+ bounding_box[3]);
+
+ /* MARKER */
+
+ if((Cwidth - Cidwidth > 0)){
+ if(!silent)fprintf(std_err,"Saving (%d) Pages to file\n",totalpage/nspage);
+ }else{
+ fprintf(std_err,"This pointsize is too large to print even a single character on the page\n");
+ fprintf(std_err,"Try a smaller pointsize - or\n");
+ fprintf(std_err,"Try reducing the Identifier width\n");
+ fprintf(std_err,"Increase the paper size\n");
+ fprintf(std_err,"You could do some PostScrip-ery to print partial characters\n");
+ fprintf(std_err,"After creating an alignment on a single page - see the CookBook\n");
+ exit(1);
+ }
+ lastY = 0;
+ nbpage = 0;
+ k = 0;
+ start_seq = 1;
+ while(k < totalpage){
+ start_aa = 1;
+ Ytemp = start_seq+Cheight-CtopSpace - 1;
+ if(Ytemp > nseq) Ytemp = nseq;
+ for(i=0;i<npage;++i){
+
+ if(nspage > 1){ /* more than one block per page */
+/* fprintf(stderr,"nbp nspage %d %d\n",nbp,nspage);*/
+ if(k>0 && nbp == 0){ /* if not the first page, then setup page*/
+ PSSetupPage(orientation,nbpage+1,outf);
+ if(background_colour != 99){
+ ALColourBackground(outf,background_colour,background_region);
+ }
+ }
+ if(nbp>0){
+ /* if this is not the first block on the page, then */
+ /* translate the block of alignment back to origin */
+ fprintf(outf,"%d %d translate\n",0,-lastY);
+ }
+ /* get new position for drawing and translate to this posn*/
+ lastY = Yspace*( Cheight-(nseq+CtopSpace)*(nbp+1) - (nbp*Vspacing) );
+ fprintf(outf,"%d %d translate\n",0,lastY);
+ }else{
+ if(k>0)PSSetupPage(orientation,k+1,outf);
+ if(background_colour != 99){
+ ALColourBackground(outf,background_colour,background_region);
+ }
+ }
+ if(id_only_on_first == 1 && nbp > 0 ){
+ /* save the Cseqwidth, then reset it to Cwidth - also set Cidwidth to 0*/
+ tempCseqwidth = Cseqwidth;
+ tempCidwidth = Cidwidth;
+ Cseqwidth = Cwidth;
+ Cidwidth = 0;
+ }
+
+ Xtemp = start_aa+Cseqwidth-1;
+ if(Xtemp > bloc[1].slen) Xtemp = bloc[1].slen;
+
+ fprintf(outf,"2 setlinecap\n");
+ fprintf(outf," %.2f setlinewidth\n",LineWidthFactor*pointsize);
+
+ ALDrawFills(fills,use_colour,s_colour,start_aa,nseq-Ytemp+1,Xtemp,nseq-start_seq+1,Cidwidth,CseqVoffset,outf);
+ ALDrawLines(lines,use_colour,
+ left_line_colour,
+ right_line_colour,
+ top_line_colour,
+ bottom_line_colour,
+ start_aa,nseq-Ytemp+1,Xtemp,nseq-start_seq+1,Cidwidth,CseqVoffset,outf);
+ if(!(id_only_on_first == 1 && (nbp > 0 || k > 0))){
+ /* don't output ID string if this is not the first block on the first page*/
+ ALOutId(bloc,use_colour,
+ id_colour,idfonts,start_seq,Ytemp,CseqVoffset,number_seqs,outf);
+ }
+ ALOutSeq(bloc,fonts,texts,inverse,use_colour,c_colour,
+ text_colour,background_colour,start_seq,Ytemp,start_aa,CseqVoffset,outf);
+
+ if(res_numbers){
+ if(use_colour)PSSetColour(number_colour,outf);
+ if(do_ticks){
+ ALOutTicks(ticks,start_aa,Cidwidth,Ytemp-start_seq+1,bloc[1].slen,outf);
+ ALOutNumbers(numbers,start_aa,Cidwidth,Ytemp-start_seq+2,bloc[1].slen,outf);
+ }else{
+ ALOutNumbers(numbers,start_aa,Cidwidth,Ytemp-start_seq+1,bloc[1].slen,outf);
+ }
+ }
+ start_aa += Cseqwidth;
+
+ if(nspage > 1){
+ ++nbp;
+ if(nbp == nspage || k == totalpage-1){ /* put showpage command for page or last page */
+ PSShowPage(outf);
+ nbp = 0;
+ ++nbpage;
+ }
+ }else{
+ PSShowPage(outf);
+ }
+ ++k;
+ }
+ start_seq = Ytemp + 1;
+ if(id_only_on_first == 1 && nbp > 0){
+ /* reset the values - not strictly necessary */
+ Cseqwidth = tempCseqwidth;
+ Cidwidth = tempCidwidth;
+ }
+ }
+ return 1;
+}
+
+void ALShadeChars(struct seqdat *bloc,
+signed char **fill,
+int start_x,int start_y,int end_x,int end_y,
+int maxY,
+char *charlist,
+float grey)
+
+/* shade residues in charlist by grey value */
+
+{
+ int i,j,jpos;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
+ if(strchr(charlist,bloc[j].seq[i])!=NULL){
+ ALFilRes(fill,i,jpos,grey);
+ }
+ }
+ }
+}
+void ALSColChars(struct seqdat *bloc,unsigned char **colour,int start_x,
+int start_y,int end_x,int end_y,int maxY,char *charlist,unsigned char colnum)
+
+/* colour residue backgrounds in charlist by colnum value */
+
+{
+ int i,j,jpos;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
+ if(strchr(charlist,bloc[j].seq[i])!=NULL){
+ ALColRes(colour,i,jpos,colnum);
+ }
+ }
+ }
+}
+
+void ALSColMask(unsigned char **mask,unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,int maxY,
+ unsigned char colnum)
+
+/* colour residue backgrounds in mask by colnum value */
+
+{
+ int i,j,jpos;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
+ if(mask[i][j]==1){
+ ALColRes(colour,i,jpos,colnum);
+ }
+ }
+ }
+}
+void ALInverseChars(struct seqdat *bloc,unsigned char **inverse,
+ int start_x,int start_y,int end_x,int end_y,char *charlist)
+
+/* Invert the characters within the range */
+/* 18/Jan/93: Allow inverted chars to be reverted */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(strchr(charlist,bloc[j].seq[i])!=NULL){
+ if(inverse[i][j] == 1){
+ inverse[i][j] = (unsigned char) 0;
+ }else{
+ inverse[i][j] = (unsigned char ) 1;
+ }
+ }
+ }
+ }
+}
+void ALInverseMask(unsigned char **mask,unsigned char **inverse,
+ int start_x,int start_y,int end_x,int end_y)
+/* Invert the characters within the range of the mask*/
+/* 18/Jan/93: Allow inverted chars to be reverted */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(mask[i][j]){
+ if(inverse[i][j] == 1){
+ inverse[i][j] = (unsigned char) 0;
+ }else{
+ inverse[i][j] = (unsigned char ) 1;
+ }
+ }
+ }
+ }
+}
+
+void ALFontChars(struct seqdat *bloc,unsigned char **fonts,
+ int start_x,int start_y,int end_x,int end_y,char *charlist,unsigned char fontnum)
+
+/* set the characters within the range to the fontnum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(strchr(charlist,bloc[j].seq[i])!=NULL){
+ fonts[i][j] = fontnum;
+ }
+ }
+ }
+}
+void ALFontRegion(unsigned char **fonts,
+ int start_x,int start_y,int end_x,int end_y,
+ unsigned char fontnum)
+/* set the characters within the range to the fontnum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ fonts[i][j] = fontnum;
+ }
+ }
+}
+void ALFontMask(unsigned char **mask,unsigned char **fonts,
+ int start_x,int start_y,int end_x,int end_y,
+ unsigned char fontnum)
+
+/* set the characters within the range to the fontnum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(mask[i][j]==1){
+ fonts[i][j] = fontnum;
+ }
+ }
+ }
+}
+
+void ALColourChars(struct seqdat *bloc,unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,
+ char *charlist,unsigned char colournum)
+
+/* set the characters within the range to the colour defined by colournum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(strchr(charlist,bloc[j].seq[i])!=NULL){
+ colour[i][j] = colournum;
+ }
+ }
+ }
+}
+void ALColourRegion(unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,
+ unsigned char colournum)
+
+/* set the characters within the range to the colournum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ colour[i][j] = colournum;
+ }
+ }
+}
+
+void ALColourMask(unsigned char **mask,unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,
+ unsigned char colournum)
+
+/* set the characters within the range to the colournum */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(mask[i][j] == 1){
+ colour[i][j] = colournum;
+ }
+ }
+ }
+}
+
+
+void ALSubChars(struct seqdat *bloc,
+ int start_x,int start_y,int end_x,int end_y,
+ char oldchar,char newchar)
+
+/* substitute oldchar for newchar at each position in bloc */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(bloc[j].seq[i] == oldchar) bloc[j].seq[i] = newchar;
+ }
+ }
+}
+
+
+void ALSurroundChars(struct seqdat *bloc,unsigned char **lines,
+ int start_x,int start_y,int end_x,int end_y,
+ int maxY,char *charlist)
+
+/*
+within the range of start_x etc. Draw lines such that every character that
+is present within charlist is surrounded by a box.
+*/
+{
+ int i,j,jpos;
+ char above,below,left,right;
+
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
+ if(strchr(charlist,bloc[j].seq[i]) != NULL){
+/* fprintf(std_err,"%d %d %c %c\n",i,j,bloc[j].seq[i]*/
+ if(j == end_y){
+ below = '!';
+ }else{
+ below = bloc[j+1].seq[i];
+ }
+ if(j == start_y){
+ above = '!';
+ }else{
+ above = bloc[j-1].seq[i];
+ }
+ if(i == start_x){
+ left = '!';
+ }else{
+ left = bloc[j].seq[i-1];
+ }
+ if(i == end_x){
+ right = '!';
+ }else{
+ right = bloc[j].seq[i+1];
+ }
+
+ if(strchr(charlist,above)== NULL){
+ ALLineRes(lines,i,jpos,LINE_TOP);
+ }
+ if(strchr(charlist,below)== NULL){
+ ALLineRes(lines,i,jpos,LINE_BOTTOM);
+ }
+ if(strchr(charlist,left)==NULL){
+ ALLineRes(lines,i,jpos,LINE_LEFT);
+ }
+ if(strchr(charlist,right)==NULL){
+ ALLineRes(lines,i,jpos,LINE_RIGHT);
+ }
+ }
+ }
+ }
+}
+void ALSurroundMask(unsigned char **mask,struct seqdat *bloc,unsigned char **lines,
+ int start_x,int start_y,int end_x,int end_y,
+ int maxY)
+/*
+within the range of start_x etc. Draw lines such that every
+masked position is isolated from every non-masked position
+*/
+{
+ int i,j,jpos;
+ char above,below,left,right;
+
+/* fprintf(stdout,"ALSurroundMask: %d %d %d %d\n",start_x,start_y,end_x,end_y);*/
+
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y,jpos=(maxY-start_y+1);j<end_y+1;++j,--jpos){
+ if(mask[i][j] == 1){
+/* fprintf(std_err,"%d %d %c %c\n",i,j,bloc[j].seq[i]*/
+ if(j == end_y){
+ below = 0;
+ }else{
+ below = mask[i][j+1];
+ }
+ if(j == start_y){
+ above = 0;
+ }else{
+ above = mask[i][j-1];
+ }
+ if(i == start_x){
+ left = 0;
+ }else{
+ left = mask[i-1][j];
+ }
+ if(i == end_x){
+ right = 0;
+ }else{
+ right = mask[i+1][j];
+ }
+ /*
+ fprintf(stdout,"IN ALSurroundMask\n");
+ fprintf(stdout,"%d %d (%d %d %d %d)\n",i,j,above,below,left,right);
+ */
+
+ if(mask[i][j] != above){
+ ALLineRes(lines,i,jpos,LINE_TOP);
+ }
+ if(mask[i][j] != below){
+ ALLineRes(lines,i,jpos,LINE_BOTTOM);
+ }
+ if(mask[i][j] != left){
+ ALLineRes(lines,i,jpos,LINE_LEFT);
+ }
+ if(mask[i][j] != right){
+ ALLineRes(lines,i,jpos,LINE_RIGHT);
+ }
+ }
+ }
+ }
+}
+
+void ALFilRegion(signed char **fill,
+ int start_x,int start_y,int end_x,int end_y,
+ int *Yindx,float grey)
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ ALFilRes(fill,i,Yindx[j],grey);
+ }
+ }
+}
+
+void ALShadeMask(unsigned char **mask,signed char **fill,
+ int start_x,int start_y,int end_x,int end_y,int *Yindx,
+ float grey)
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ if(mask[i][j]==1){
+ ALFilRes(fill,i,Yindx[j],grey);
+ }
+ }
+ }
+}
+
+
+void ALColRegion(unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,
+ int *Yindx,unsigned char colnum)
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ ALColRes(colour,i,Yindx[j],colnum);
+ }
+ }
+}
+
+void ALColRRegion(unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,
+ unsigned char colnum)
+/* version of ALColRegion that is indexed by characters rather than position */
+/* 18/1/1995 */
+
+{
+ int i,j;
+ for(i=start_x;i<end_x+1;++i){
+ for(j=start_y;j<end_y+1;++j){
+ colour[i][j] = colnum;
+ }
+ }
+}
+
+void ALBoxRegion(unsigned char **lines,
+ int start_x,int start_y,int end_x,int end_y,
+ int *Yindx)
+{
+ int i;
+ for(i=start_x;i<end_x+1;++i){
+ ALLineRes(lines,i,Yindx[end_y],LINE_BOTTOM);
+ ALLineRes(lines,i,Yindx[start_y],LINE_TOP);
+ }
+ for(i=start_y;i<end_y+1;++i){
+ ALLineRes(lines,start_x,Yindx[i],LINE_LEFT);
+ ALLineRes(lines,end_x,Yindx[i],LINE_RIGHT);
+ }
+}
+void ALDoLine(unsigned char **lines,
+ int start_x,int start_y,int end,
+ int type,int *Yindx)
+{
+ int i;
+ if(type == LINE_TOP || type == LINE_BOTTOM){
+ for(i=start_x;i<end+1;++i){
+ ALLineRes(lines,i,Yindx[start_y],type);
+ }
+ }else{
+ for(i=start_y;i<end+1;++i){
+ ALLineRes(lines,start_x,Yindx[i],type);
+
+
+ }
+ }
+}
+
+void ALDrawFills(signed char **fill,int use_colour,unsigned char **colour,
+ int start_x,int start_y,int end_x,int end_y,int XOffset,int YOffset,FILE *outf)
+
+/* for values of fill >= 0 draw box and fill in with grey value */
+/* 6/12/92: add colour option */
+{
+ int i,j;
+ extern int precis;
+
+ XOffset *= Xspace;
+ YOffset *= Yspace;
+
+ for(i=end_x;i>(start_x-1);--i){
+ for(j=end_y;j>(start_y-1);--j){
+ if((int) fill[i][j] >= 0 || use_colour){
+
+/*
+Revise to use ML function 27th Oct 1992
+ fprintf(outf," newpath\n");
+ fprintf(outf,"%.2f %.2f moveto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset);
+ fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset);
+ fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset);
+ fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset);
+ fprintf(outf,"%.2f %.2f lineto \n",(float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset);
+ fprintf(outf,"closepath %.2f setgray fill 0 setgray \n",(float)fill[i][j]/(float)precis);
+*/
+ fprintf(outf," newpath\n");
+ fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f ML\n",
+ (float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,
+ (float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,
+ (float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,
+ (float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,
+ (float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset);
+ if(use_colour && fill[i][j] < 0){
+ /* 6/1/1995 - only set colour if grey is not set */
+ /* set to colour number */
+ fprintf(outf,"closepath C%-d fill \n",colour[i][j]);
+ }else{
+ fprintf(outf,"closepath %.2f setgray fill 0 setgray \n",(float)fill[i][j]/(float)precis);
+ }
+ }
+ }
+ }
+}
+
+void ALFilRes(signed char **fill,int i,int j,float grey)
+
+{
+ extern int precis;
+/* ALBoxRes(lines,i,j);
+ fill[i+Cidwidth][j+CseqVoffset] = grey * precis;
+*/
+ fill[i][j] = grey * precis;
+}
+
+void ALColRes(unsigned char **colour,int i,int j,int colnum)
+
+{
+ colour[i][j] = colnum;
+}
+
+
+void ALBoxRes(unsigned char **lines,int i,int j)
+
+{
+ ALLineRes(lines,i,j,LINE_TOP);
+ ALLineRes(lines,i,j,LINE_BOTTOM);
+ ALLineRes(lines,i,j,LINE_LEFT);
+ ALLineRes(lines,i,j,LINE_RIGHT);
+}
+
+
+void ALLineRes(
+unsigned char **lines,
+int i,int j,
+unsigned char value)
+{
+/*
+ i = i + Cidwidth;
+ j = j + CseqVoffset;
+*/
+ ALLineChar(lines,i,j,value);
+}
+
+void ALLineChar(unsigned char **lines,int i,int j,unsigned char value)
+
+{
+ lines[i][j] = lines[i][j] | value;
+}
+
+void ALDrawLines(unsigned char **lines,int use_colour,
+ unsigned char **left_line_colour,
+ unsigned char **right_line_colour,
+ unsigned char **top_line_colour,
+ unsigned char **bottom_line_colour,
+ int start_x,int start_y,int end_x,int end_y,
+ int XOffset,int YOffset,FILE *outf)
+
+/* draw the lines that are indicated by the lines array in the range of the
+array indicated by start_x etc
+*/
+{
+ int i,j;
+ XOffset *= Xspace;
+ YOffset *= Yspace;
+
+/*
+ if(use_colour){
+ fprintf(outf,"C100\n");
+ }
+*/
+
+ for(i=end_x;i>(start_x-1);--i){
+ for(j=end_y;j>(start_y-1);--j){
+ if(lines[i][j] != 0){
+ if((LINE_LEFT & lines[i][j]) == LINE_LEFT){
+ PSSetColour(left_line_colour[i][j],outf);
+ PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,
+ (float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
+ }
+ if((LINE_RIGHT & lines[i][j]) == LINE_RIGHT){
+ PSSetColour(right_line_colour[i][j],outf);
+ PSline((float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,
+ (float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
+ }
+ if((LINE_TOP & lines[i][j]) == LINE_TOP){
+ PSSetColour(top_line_colour[i][j],outf);
+ PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,
+ (float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+1)*Yspace-Yshift+YOffset,outf);
+ }
+ if((LINE_BOTTOM & lines[i][j]) == LINE_BOTTOM){
+ PSSetColour(bottom_line_colour[i][j],outf);
+ PSline((float)(i-start_x)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,
+ (float)(i-start_x+1)*Xspace-Xshift+XOffset,
+ (float)(j-start_y+0)*Yspace-Yshift+YOffset,outf);
+ }
+ }
+ }
+ }
+ /*
+ if(use_colour){
+ fprintf(outf,"C99\n");
+ }
+ */
+}
+
+void PSline(float x1,float y1,float x2,float y2,FILE *outf)
+
+{
+ fprintf(outf,"%.2f %.2f %.2f %.2f L\n ",x1,y1,x2,y2);
+}
+
+
+
+void ALSimpleBox(int x1,int y1,int x2,int y2,float pfactor, /* multiply pointsize by this to get linewidth */
+ FILE *outf)
+
+/* draw a box to include character coordinates x1,y1 to x2,y2 */
+/* x1 < x2 y1< y2 */
+{
+ float lshift = Xspace/6;
+ float rshift = Xspace - lshift;
+
+ x1 *= Xspace;
+ y1 *= Yspace;
+ x2 *= Xspace;
+ y2 *= Yspace;
+
+ x1 -= lshift;
+ x2 += rshift;
+ y1 -= lshift;
+
+ PSDrawBox((float)x1,(float)y1,(float)x2,(float)y2,pfactor,outf);
+}
+
+void PSDrawBox(float x1,float y1,float x2,float y2,float pfactor,FILE *out)
+
+{
+ fprintf(out,"%f setlinewidth\n ",pointsize*pfactor);
+ fprintf(out,"%f %f moveto %f %f lineto %f %f lineto %f %f lineto %f %f lineto closepath stroke\n",
+ x1,y1,x2,y1,x2,y2,x1,y2,x1,y1);
+}
+
+void ALOutTicks(char *array,int start_aa,int xpos,int ypos,int len,FILE *out)
+
+{
+ int right;
+ int j;
+
+ xpos *= Xspace;
+ ypos *= Yspace;
+
+ right = start_aa + Cseqwidth;
+ if(right > len)right = len;
+ for(j=start_aa;j<right;j++){
+ if(array[j] != '\0'){
+ PSPutChar(xpos,ypos,array[j],out);
+ }
+ xpos += Xspace;
+ }
+}
+
+void ALOutNumbers(char **array,int start_aa,int xpos,int ypos,int len,FILE *out)
+
+{
+ int right;
+ int j;
+
+ xpos *= Xspace;
+ ypos *= Yspace;
+
+ right = start_aa + Cseqwidth;
+ if(right > len)right = len;
+ for(j=start_aa;j<right;j++){
+ if(array[j][0] != '\0'){
+ PSPutText(xpos,ypos,array[j],out);
+ }
+ xpos += Xspace;
+ }
+}
+
+char *ALCreateTicks(int start, int interval, int len)
+
+/* create ticks at the desired interval starting with residue start */
+{
+ int i;
+ char *temp;
+ temp = (char *) malloc(sizeof(char) * len);
+ /* first set all ticks to '\0' */
+ for(i=0;i<len;++i){
+ temp[i]='\0';
+ }
+ for(i=0;i<len;i+=interval){
+ temp[i] = '|';
+ }
+ temp[0]='\0';
+ temp[1]='|';
+ return temp;
+}
+
+
+
+char **ALCreateNumbers(int start,int interval,int nres,int nwidth)
+
+/* create character array of numbers from start to nres at interval*/
+{
+ int i;
+ char **temp;
+ temp = (char **) malloc(nres*sizeof(char *));
+ for(i=0;i<nres;++i){
+ temp[i] = (char *) malloc(sizeof(char) *nwidth);
+ temp[i][0]='\0';
+ }
+ for(i=start;i<nres;i+=interval){
+ if(i==0){
+ sprintf(temp[i+1],"%-d",i+1);
+ }else{
+ sprintf(temp[i],"%-d",i);
+ }
+ }
+
+ return temp;
+}
+
+char **ALCreateNum2(
+int nstart, /* starting number */
+int ninterval, /* interval for numbers */
+int nend, /* end of number range */
+int nres, /* total length of sequence */
+int xstart, /* starting location for writing numbers */
+int nwidth) /* width of the number string */
+
+/* create character array of numbers from start to nres at interval*/
+{
+ int i,xp;
+ char **temp;
+ temp = (char **) malloc(nres*sizeof(char *));
+ for(i=0;i<nres;++i){
+ temp[i] = (char *) malloc(sizeof(char) *nwidth);
+ temp[i][0]='\0';
+ }
+ xp = xstart;
+ for(i=nstart;i<nend;i+=ninterval){
+ if(i==0){
+ sprintf(temp[xp+1],"%-d",i+1);
+ }else{
+ sprintf(temp[xp],"%-d",i);
+ }
+ xp += ninterval;
+ }
+
+ return temp;
+}
+
+void ALReportInfo(int nseq,FILE *out)
+
+{
+ fprintf(out,"Number of Sequences: %d\n",nseq);
+ fprintf(out,"Total Vertical Space per page: %d\n",Cheight);
+}
+
+void ALReserveSpace(int location,int nspace)
+
+{
+ extern int TVspace,CseqVoffset;
+
+ switch(location){
+ case TOP:
+ TVspace += nspace;
+ CtopSpace +=nspace;
+ break;
+ case BOTTOM:
+ TVspace += nspace;
+ CseqVoffset += nspace;
+ CbottomSpace += nspace;
+ break;
+ }
+}
+
+void PSSetupPage(int orientation,int npage,FILE *outf)
+
+{
+ fprintf(outf,"%%%%Page: ? %d\n",npage);
+ PSSetOrientation(orientation,outf);
+ PSSetFont(0,outf); /* set default font for document */
+}
+
+void ALOutSeq(struct seqdat *bloc,unsigned char **fonts,char ***texts,unsigned char **inverse,
+ int use_colour,
+ unsigned char **colour,
+ unsigned char **text_colour,
+ unsigned char background_colour,
+ int start_seq,int end_seq,int start_aa,int ypos,FILE *outf)
+
+{
+ extern int Xspace,Yspace;
+ extern int Cidwidth;
+
+ int i,j;
+ int xpos;
+ unsigned char current_col;
+
+ int right;
+
+ ypos *= Yspace;
+
+ current_col = background_colour;
+
+ right = start_aa + Cseqwidth;
+ if(right > bloc[1].slen-1)right = bloc[1].slen;
+
+ for(i=end_seq;i>(start_seq-1);--i){
+ xpos = Cidwidth * Xspace;
+ for(j=start_aa;j<right;++j){
+ if(texts[j][i] != NULL || bloc[i].seq[j] != ' '){
+ if(fonts[j][i]!=0)PSSetFont(fonts[j][i],outf);
+ if(inverse[j][i] != 0)PSSetGrey(1,outf);
+ if(use_colour && colour[j][i] != current_col){
+ PSSetColour(colour[j][i],outf);
+ current_col = colour[j][i];
+ }
+ if(bloc[i].seq[j] != ' '){
+ PSPutChar(xpos,ypos,bloc[i].seq[j],outf);
+ }
+ if(texts[j][i] != NULL){
+ if(text_colour[j][i] != current_col){
+ PSSetColour(text_colour[j][i],outf);
+ current_col = text_colour[j][i];
+ }
+ if(texts[j][i][0] == '@'){
+ PSPutSpecialText(xpos,ypos,Xspace,Yspace,texts[j][i],
+ text_colour[j][i],background_colour,0.9,outf);
+ }else{
+ PSPutText(xpos,ypos,texts[j][i],outf);
+ }
+ }
+ if(inverse[j][i] != 0)PSSetGrey(0,outf);
+ if(fonts[j][i]!=0)PSSetFont(0,outf);
+ }
+ xpos += Xspace;
+ }
+ ypos += Yspace;
+ }
+/*
+ if(use_colour){
+ PSSetColour(100,outf);
+ }
+*/
+}
+
+
+void ALOutId(struct seqdat *bloc,int use_colour,
+ unsigned char *colour,
+ unsigned char *fonts,
+ int start_seq,int end_seq,int ypos,int numbers,
+ FILE *outf)
+
+{
+ extern int MAXilen;
+ extern int Xspace,Yspace;
+ int i;
+ int xpos;
+ char *temp;
+
+ xpos = 0;
+ ypos *= Yspace;
+ temp = (char *) malloc(sizeof(char) * (MAXilen + 5));
+
+
+ for(i=end_seq;i>(start_seq-1);--i){
+ if(use_colour)PSSetColour(colour[i],outf);
+ if(fonts[i] != 0)PSSetFont(fonts[i],outf);
+ if(numbers){
+ sprintf(temp,"%4d:%s",i,bloc[i].id);
+ }else{
+ sprintf(temp,"%s",bloc[i].id);
+ }
+ PSPutText(xpos,ypos,temp,outf);
+ ypos += Yspace;
+ if(fonts[i] != 0)PSSetFont(0,outf);
+ }
+ free((char *) temp);
+
+}
+
+void PSPutText(int x,int y,char *text,FILE *outf)
+
+{
+ fprintf(outf," %d %d moveto (%s) show \n",x,y,text);
+}
+
+void PSPutChar(int x,int y,char c,FILE *outf)
+
+{
+ /* fprintf(outf," %d %d moveto (%c) show \n",x,y,c);*/
+ fprintf(outf,"(%c) %d %d P\n",c,x,y);
+}
+
+void PSShowPage(FILE *outf)
+
+{
+ fprintf(outf,"showpage\n");
+}
+
+void ALSetFont(char *font,int point,FILE *outf)
+
+{
+ fprintf(outf,"/%s findfont %d scalefont setfont\n",font,point);
+}
+
+void PSSetFont(unsigned char number,FILE *outf)
+
+{
+ fprintf(outf,"F%-d\n ",number);
+}
+
+void PSSetColour(unsigned char number,FILE *outf)
+
+{
+ fprintf(outf,"C%-d\n ",number);
+}
+
+void ALDefineFont(int number,char *font,float point,FILE *outf)
+
+/* define a PostScript function called /Fnumber which selects the
+font at point pointsize */
+{
+ fprintf(outf,"/F%-d {/%s findfont %.2f scalefont setfont } def\n",
+ number,font,point);
+}
+
+void ALDefineColour(int number,char *type,float red,float green,float blue,FILE *outf)
+
+/* define a PostScript function called /Cnumber which selects the
+colour defined by red,green, blue intensities
+
+new addition - if type is equal to "HSB" then define an hsb colour using red, green blue as
+the hue saturation and brightness.
+*/
+{
+ if(strcmp(type,"HSB")==0){
+ /* set an HSB colour */
+ fprintf(outf,"/C%-d {%f %f %f sethsbcolor } def\n", number,red,green,blue);
+ }else{
+ /* set an RGB colour */
+ fprintf(outf,"/C%-d {%f %f %f setrgbcolor } def\n", number,red,green,blue);
+ }
+}
+
+void ALCheckSinglePage(int nseq,int len,int silent)
+
+{
+ extern FILE *std_err;
+ Csheet = 1;
+
+
+ if(Cheight-CtopSpace < nseq){
+ if(!silent)fprintf(std_err,"Not enough height to print all sequences on a single page at this pointsize\n");
+ if(!silent)fprintf(std_err,"Pointsize: %.2f\n",pointsize);
+ if(!silent)fprintf(std_err,"Need a pointsize of < : %.2f\n",(float) height/(nseq+ CtopSpace));
+ Csheet = nseq/(Cheight-CtopSpace) + 1;
+ if(!silent)fprintf(std_err,"Will split alignment into %d segments\n",Csheet);
+ }
+
+ npage = len/(Cwidth - Cidwidth) + 1;
+}
+
+
+void ALSetPageLimits(void)
+/* Use the current width height and pointsize values to calculate:
+ Cwidth
+ Cheight
+ Xspace
+ Yspace
+*/
+{
+
+ Xspace = pointsize + pointsize * XspaceFactor;
+ Yspace = pointsize + pointsize * YspaceFactor;
+
+ Cwidth = width/Xspace;
+ Cheight = height/Yspace;
+
+ Cseqwidth = Cwidth - Cidwidth;
+
+ Xshift = Xspace * XshiftFactor;
+ Yshift = Yspace * YshiftFactor;
+}
+
+void PSSetOrientation(int orientation,FILE *outf)
+
+{
+ switch(orientation){
+ case LANDSCAPE:
+ PSLandscape(outf);
+ break;
+ case PORTRAIT:
+ PSPortrait(outf);
+ break;
+ default:
+ PSPortrait(outf);
+ }
+}
+
+void PSPreamble(FILE *out,int singlepage,int *b_box,int screensize)
+{
+ char *Alscript_Version = ALSCRIPT_VERSION;
+ fprintf(out,"%%!PS-Adobe-2.0\n");
+ fprintf(out,"%%%%Creator: %s\n",Alscript_Version);
+ fprintf(out,"%%%%Title: Alscript Output\n");
+ fprintf(out,"%% Barto,n G. J. (1993)\n");
+ fprintf(out,"%% ALSCRIPT - A Tool to format multiple sequence alignments\n");
+ fprintf(out,"%% Protein Engineering, 6, 37-40\n");
+ fprintf(out,"%%\n");
+ if(singlepage == 1){
+ fprintf(out,"%%%%BoundingBox: %d %d %d %d\n",
+ b_box[0],b_box[1],b_box[2],b_box[3]);
+ }
+ fprintf(out,"/P {moveto show} def\n");
+ fprintf(out,"/L {moveto lineto stroke} def\n");
+ fprintf(out,
+ "/ML {moveto lineto lineto lineto lineto} def\n");
+ fprintf(out,"2 setlinecap\n"); /* projecting line caps */
+ ALDefineColour(99,"RGB",1.0,1.0,1.0,out); /* white */
+ ALDefineColour(100,"RGB",0.0,0.0,0.0,out); /* black */
+ /* modify the screening - suggested by Michael D. Baron */
+ fprintf(out,"%d currentscreen 3 -1 roll pop setscreen\n",screensize);
+
+}
+
+void PSLandscape(FILE *out)
+
+{
+ width = MAXside;
+ height = MINside;
+
+ fprintf(out,"%d %d translate\n",xoff+height,yoff);
+ fprintf(out,"90 rotate\n");
+
+}
+
+void PSPortrait(FILE *out)
+
+{
+ width = MINside;
+ height = MAXside;
+ fprintf(out,"%d %d translate\n",xoff,yoff);
+}
+
+
+void echo(char *s)
+
+{
+ extern FILE *std_err;
+ fprintf(std_err,"%s",s);
+}
+
+void ALGetFourInt(int *sx,int *sy,int *ex,int *ey)
+
+{
+char *token;
+
+ token = strtok(NULL,TOKENS);
+ *sx = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *sy = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *ex = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *ey = atoi(token);
+}
+void ALGetThreeInt(int *sy,int *ex,int *ey)
+
+{
+char *token;
+
+ token = strtok(NULL,TOKENS);
+ *sy = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *ex = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *ey = atoi(token);
+}
+void ALGetTwoInt(int *sy,int *ex)
+
+{
+char *token;
+
+ token = strtok(NULL,TOKENS);
+ *sy = atoi(token);
+ token = strtok(NULL,TOKENS);
+ *ex = atoi(token);
+}
+
+char ALChekSpace(const char *token)
+{
+ if(strcmp(token,"SPACE") == 0){
+ return ' ';
+ }else{
+ return token[0];
+ }
+}
+
+void PSSetGrey(float grey,FILE *outf)
+{
+ fprintf(outf," %.2f setgray\n",grey);
+}
+
+int save_pir(struct seqdat *bloc,int nseq,FILE *pirf)
+
+{
+ int i,j;
+ int count;
+
+
+ for(i=1;i<(nseq+1);++i){
+ fprintf(pirf,">P1;%s\n",bloc[i].id);
+ fprintf(pirf,"%s\n",bloc[i].title);
+ count=0;
+ for(j=1;j<bloc[i].slen;++j){
+ ++count;
+ /* convert spaces to dashes */
+ if(bloc[i].seq[j] == ' ')bloc[i].seq[j] = '.';
+ fputc(bloc[i].seq[j],pirf);
+ if(count==50){
+ count=0;
+ fprintf(pirf,"\n");
+ }
+ }
+ fprintf(pirf,"*\n");
+ }
+ return 1;
+}
+
+int save_msf(struct seqdat *bloc,int nseq,FILE *msff)
+
+{
+ int i,j,s,e;
+ int count;
+
+ fprintf(msff,"\njunk.msf MSF: %d Type: P January 01, 1776 12:00 Check: 7110 ..\n\n",bloc[1].slen-1);
+
+ for(i=1;i<(nseq+1);++i){
+ fprintf(msff,"Name: %20s Len: %7d Check: 0 Weight: 1.00\n",
+ bloc[i].id,bloc[1].slen-1);
+ }
+ fprintf(msff,"\n//\n\n\n");
+
+
+ s = 1;
+
+ while(s < bloc[1].slen){
+ e = s + 50;
+ if(e > bloc[1].slen) e = bloc[1].slen;
+
+ for(i=1;i<(nseq+1);++i){
+ fprintf(msff,"%10s ",bloc[i].id);
+ for(j=s;j<e;++j){
+ if(bloc[i].seq[j] == ' ')bloc[i].seq[j]='.';
+ fputc(bloc[i].seq[j],msff);
+ }
+ fprintf(msff,"\n");
+ }
+ s += 50;
+ fprintf(msff,"\n\n");
+ }
+ return 1;
+}
+
+
+void ALGetAllRange(int *sx, int *sy, int *ex, int *ey,int dex,int dey)
+/* checks the next token if it is ALL then return box around whole alignment
+ else return box according to the integers found
+*/
+{
+ char *token;
+
+ token = strtok(NULL,TOKENS);
+
+ if(strcmp(token,"ALL")==0){
+ *sx = 1;
+ *sy = 1;
+ *ex = dex;
+ *ey = dey;
+ }else{
+ *sx = atoi(token);
+ ALGetThreeInt(sy,ex,ey);
+ }
+ if(*ex > dex) *ex = dex;
+ if(*ey > dey) *ey = dey;
+}
+
+void ALid_mask(
+unsigned char **mask,
+struct seqdat *bloc,
+int sx,int sy,int ex,int ey,
+int id_cut,
+char *legal,
+char *illegal)
+
+{
+ int i,j,k,iseen;
+ char fchar;
+ char *seen; /* array of characters that are seen at this position */
+ int *freq; /* array of frequencies of the characters */
+ int nc; /* number of different character types at this position */
+ int ns;
+ int mc; /* maximum character present */
+ int imc; /* location of max character */
+
+ ns = ey - sy + 1;
+ nc = 0;
+
+ seen = (char *) GJmalloc(sizeof(char) *ns);
+ freq = (int *) GJmalloc(sizeof(int) *ns);
+
+ for(i=0;i<ns;++i){
+ freq[i] = 0;
+ seen[i] = '\0';
+ }
+
+/* fprintf(stdout,"In ALidmask\n");*/
+
+ for(i=sx;i<(ex+1);++i){
+ /* for each position get the list of characters seen and their frequencies */
+ for(j=sy;j<(ey+1);++j){
+ iseen = Ifound(bloc,i,j,seen,nc);
+ if(iseen >= 0){
+ ++freq[iseen];
+ }else{
+ seen[nc] = bloc[j].seq[i];
+ ++freq[nc];
+ ++nc;
+ }
+ }
+ /*
+ for(k=0;k<nc;++k)fprintf(stdout,"%c ",seen[k]);
+ for(k=0;k<nc;++k)fprintf(stdout,"%d ",freq[k]);
+ fprintf(stdout,"\n");
+ */
+ /* find the most frequent character that is legal and not illegal*/
+ mc = 0;
+ for(k=0;k<nc;++k){
+ if(legal != NULL && illegal != NULL){
+ if( strchr(legal,seen[k]) != NULL
+ && strchr(illegal,seen[k]) == NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else if(legal != NULL){
+ if( strchr(legal,seen[k]) != NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else if(illegal != NULL){
+ if( strchr(illegal,seen[k]) == NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else{
+ if(freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }
+ }
+ if(mc >= id_cut){
+ /* only select the character if it is >= id_cut */
+ fchar = seen[imc];
+/* fprintf(stdout,"At %d %c\n",i,fchar);*/
+ for(j=sy;j<(ey+1);++j){
+ if(bloc[j].seq[i] == fchar){
+ mask[i][j] = 1;
+/* fprintf(stdout,"%d %d \n",i,j);*/
+ }
+ }
+ }
+ for(j=0;j<ns;++j){
+ freq[j] = 0;
+ seen[j] = '\0';
+ }
+ nc = 0;
+ }
+ GJfree(seen);
+ GJfree(freq);
+}
+
+void ALfre_mask(
+unsigned char **mask,
+struct seqdat *bloc,
+int sx,int sy,int ex,int ey,
+char *legal,
+char *illegal)
+
+{
+ int i,j,k,iseen;
+ char fchar;
+ char *seen; /* array of characters that are seen at this position */
+ int *freq; /* array of frequencies of the characters */
+ int nc; /* number of different character types at this position */
+ int ns;
+ int mc; /* maximum character present */
+ int imc; /* location of max character */
+
+ ns = ey - sy + 1;
+ nc = 0;
+
+ seen = (char *) GJmalloc(sizeof(char) *ns);
+ freq = (int *) GJmalloc(sizeof(int) *ns);
+
+ for(i=0;i<ns;++i){
+ freq[i] = 0;
+ seen[i] = '\0';
+ }
+
+/* fprintf(stdout,"In ALidmask\n");*/
+
+ for(i=sx;i<(ex+1);++i){
+ /* for each position get the list of characters seen and their frequencies */
+ for(j=sy;j<(ey+1);++j){
+ iseen = Ifound(bloc,i,j,seen,nc);
+ if(iseen >= 0){
+ ++freq[iseen];
+ }else{
+ seen[nc] = bloc[j].seq[i];
+ ++freq[nc];
+ ++nc;
+ }
+ }
+/* for(k=0;k<nc;++k)fprintf(stdout,"%c ",seen[k]);
+ for(k=0;k<nc;++k)fprintf(stdout,"%d ",freq[k]);
+ fprintf(stdout,"\n");
+*/
+ /* find the most frequent character that is legal and not illegal*/
+ mc = 0;
+ for(k=0;k<nc;++k){
+ if(legal != NULL && illegal != NULL){
+ if( strchr(legal,seen[k]) != NULL
+ && strchr(illegal,seen[k]) == NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else if(legal != NULL){
+ if( strchr(legal,seen[k]) != NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else if(illegal != NULL){
+ if( strchr(illegal,seen[k]) == NULL
+ && freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }else{
+ if(freq[k] > mc){
+ mc = freq[k];
+ imc = k;
+ }
+ }
+ }
+ fchar = seen[imc];
+/* fprintf(stdout,"At %d %c\n",i,fchar);*/
+ for(j=sy;j<(ey+1);++j){
+ if(bloc[j].seq[i] == fchar){
+ mask[i][j] = 1;
+/* fprintf(stdout,"%d %d \n",i,j);*/
+ }
+ }
+
+ for(j=0;j<ns;++j){
+ freq[j] = 0;
+ seen[j] = '\0';
+ }
+ nc = 0;
+ }
+ GJfree(seen);
+ GJfree(freq);
+}
+int Ifound(struct seqdat *bloc,
+int i,int j,
+char *seen,
+int nc)
+{
+ int k;
+
+ if(nc > 0){
+ for(k=0;k<nc;++k){
+ if(bloc[j].seq[i] == seen[k]){
+ return k;
+ }
+ }
+ }
+ return -1;
+}
+void ALagree_mask(
+unsigned char **mask,
+struct seqdat *bloc,
+int sx,int sy,int ex,int ey,
+int ns)
+
+{
+ int i,j;
+
+ for(i=sx;i<(ex+1);++i){
+ /* for each position mask the characters that are identical to sequence ns */
+ for(j=sy;j<(ey+1);++j){
+ if(bloc[j].seq[i] == bloc[ns].seq[i]){
+ mask[i][j] = 1;
+ }
+ }
+ }
+}
+
+void ALnot_mask(
+unsigned char **mask,
+int sx,int sy,int ex,int ey)
+
+{
+ int i,j;
+
+ for(i=sx;i<(ex+1);++i){
+ /* NOT on each mask element ie 1 goes to 0, 0 to 1 */
+ for(j=sy;j<(ey+1);++j){
+ if(mask[i][j]==1){
+ mask[i][j]=0;
+ }else if(mask[i][j]==0){
+ mask[i][j]=1;
+ }
+ }
+ }
+}
+
+
+void ALsub_mask(unsigned char **mask,struct seqdat *bloc,
+ int sx,int sy,int ex,int ey,char cchar)
+
+{
+ int i,j;
+
+ for(i=sx;i<(ex+1);++i){
+ /* substitute all characters in the mask for cchar */
+ for(j=sy;j<(ey+1);++j){
+ if(mask[i][j]==1){
+ bloc[j].seq[i] = cchar;
+ }
+ }
+ }
+}
+
+void ALMask(unsigned char **mask,
+int sx,int sy,int ex,int ey)
+
+{
+ int i,j;
+
+ for(i=sx;i<(ex+1);++i){
+ /* substitute all characters in the mask for cchar */
+ for(j=sy;j<(ey+1);++j){
+ mask[i][j] = 1;
+ }
+ }
+}
+
+void ALConsMask(unsigned char **mask,
+int sx,int sy,int ex,int ey,int *consval,int conscut)
+
+{
+ int i,j;
+
+ for(i=sx;i<(ex+1);++i){
+ /* set mask at all positions that are >= conscut in the consval array */
+ for(j=sy;j<(ey+1);++j){
+ if(consval[i] >= conscut){
+ mask[i][j] = 1;
+ }
+ }
+ }
+}
+
+
+void ALDrawHorizLine(
+ float Xpos, /* bottom left hand corner of character posn */
+ float Ypos, /* */
+ float Xspace, /* horizontal width of character position */
+ float Yspace, /* vertical height of character position */
+ float width_fac,FILE *outf) /* proportion of vertical height that the line will fill */
+
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+
+ /* width_fac defines the width of the line in terms of the height of the characters */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f ML\n",
+ Xpos,ymid-hline_w,
+ xright,ymid-hline_w,
+ xright,ymid+hline_w,
+ Xpos,ymid+hline_w,
+ Xpos,ymid-hline_w,outf);
+}
+
+void ALDrawRightArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+
+ /* width_fac defines the width of the Arrow in terms of the height of the characters */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(Xpos,Ypos,outf);
+ PSlineto(xright,ymid,outf);
+ PSlineto(Xpos,ytop,outf);
+ PSlineto(Xpos,Ypos,outf);
+
+}
+
+void ALDrawLeftArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+
+ /* width_fac defines the width of the Arrow in terms of the height of the characters */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(xright,Ypos,outf);
+ PSlineto(xright,ytop,outf);
+ PSlineto(Xpos,ymid,outf);
+ PSlineto(xright,Ypos,outf);
+}
+
+
+void ALDrawUpArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(Xpos,Ypos,outf);
+ PSlineto(xright,Ypos,outf);
+ PSlineto(xmid,ytop,outf);
+ PSlineto(Xpos,Ypos,outf);
+}
+
+void ALDrawDownArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(Xpos,ytop,outf);
+ PSlineto(xright,ytop,outf);
+ PSlineto(xmid,Ypos,outf);
+ PSlineto(Xpos,ytop,outf);
+}
+
+/* Draw a small up arrow. mok 980917 */
+void ALDrawSmallUpArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float xmid;
+ float x,y;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ PSmoveto(xmid, ytop, outf);
+ x = Xpos + (xright-Xpos)/5.0; y = Ypos + 2.0*(ytop-Ypos)/3.0;
+ PSlineto(x,y,outf);
+ x = Xpos + 2.0*(xright-Xpos)/5.0;
+ PSlineto(x, y, outf);
+ PSlineto (x, Ypos, outf);
+ x = Xpos + 3.0*(xright-Xpos)/5.0;
+ PSlineto (x, Ypos, outf);
+ PSlineto(x, y, outf);
+ x = Xpos + 4.0*(xright-Xpos)/5.0;
+ PSlineto(x, y, outf);
+ PSlineto(xmid, ytop, outf);
+}
+
+/* Draw a small down arrow. mok 980917 */
+void ALDrawSmallDownArrow(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float xmid;
+ float x,y;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ PSmoveto(xmid, Ypos, outf);
+ x = Xpos + 4.0*(xright-Xpos)/5.0; y = Ypos + (ytop-Ypos)/3.0;
+ PSlineto(x,y,outf);
+ x = Xpos + 3.0*(xright-Xpos)/5.0;
+ PSlineto(x, y, outf);
+ PSlineto (x, ytop, outf);
+ x = Xpos + 2.0*(xright-Xpos)/5.0;
+ PSlineto (x, ytop, outf);
+ PSlineto(x, y, outf);
+ x = Xpos + (xright-Xpos)/5.0;
+ PSlineto(x, y, outf);
+ PSlineto(xmid, Ypos, outf);
+}
+
+void ALDrawCircle(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSnewpath(outf);
+
+ fprintf(outf,"%.2f %.2f %.2f %d %d arc\n",xmid,ymid,(ytop - Ypos)*0.5,0,360);
+
+}
+
+/* Draw a diamond. mok 980917 */
+void ALDrawDiamond(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ PSmoveto(Xpos, ymid, outf);
+ PSlineto(xmid, ytop, outf);
+ PSlineto(xright, ymid, outf);
+ PSlineto(xmid, Ypos, outf);
+ PSlineto(Xpos, ymid, outf);
+}
+
+/* Draw a bar. mok 980917 */
+void ALDrawBar(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright;
+ float y1, y2;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+
+ y1 = Ypos + 2.0*(Ypos+Yspace)/5.0;
+ y2 = Ypos + 3.0*(Ypos+Yspace)/5.0;
+
+ PSmoveto(Xpos, y1, outf);
+ PSlineto(xright, y1, outf);
+ PSlineto(xright, y2, outf);
+ PSlineto(Xpos, y2, outf);
+ PSlineto(Xpos, y1, outf);
+}
+
+void ALDrawPseudoEllipse(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,
+ FILE *outf)
+
+{
+ /* draws a pseudo ellipse in the box bounded by Xpos,Ypos, Xpos+Xspace, Ypos+Yspace */
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+ float xefact = 0.2; /* this shifts the guide points by 0.2 towards the axis */
+ /* should not really be hard wired */
+ float yefact = 0.0;
+
+ float xbit,ybit;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+ xbit = Xspace * xefact;
+ ybit = Yspace * yefact;
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSnewpath(outf);
+
+ PSmoveto(xmid,Ypos,outf);
+
+ fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
+ Xpos+xbit,Ypos+ybit,Xpos+xbit,ytop-ybit,xmid,ytop);
+ fprintf(outf,"%.2f %.2f %.2f %.2f %.2f %.2f curveto\n",
+ xright-xbit,ytop-ybit,xright-xbit,Ypos+ybit,xmid,Ypos);
+}
+
+void ALDrawLeftSemiEnd(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSnewpath(outf);
+
+ fprintf(outf,"%.2f %.2f %.2f %d %d arc\n",xmid,ymid,(ytop - Ypos) *0.5,270,90);
+
+ PSlineto(xright,ytop,outf);
+ PSlineto(xright,Ypos,outf);
+ PSlineto(xmid,Ypos,outf);
+
+}
+void ALDrawRightSemiEnd(float Xpos,float Ypos, float Xspace, float Yspace, float width_fac,FILE *outf)
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSnewpath(outf);
+ fprintf(outf,"%f %f %f %d %d arc\n",xmid,ymid,(ytop - Ypos) *0.5,90,270);
+
+ PSlineto(Xpos,Ypos,outf);
+ PSlineto(Xpos,ytop,outf);
+ PSlineto(xmid,ytop,outf);
+}
+void ALDrawRightHalfHorizLine(
+ float Xpos, /* bottom left hand corner of character posn */
+ float Ypos, /* */
+ float Xspace, /* horizontal width of character position */
+ float Yspace, /* vertical height of character position */
+ float width_fac, FILE *outf) /* proportion of vertical height that the line will fill */
+
+/* draw line from midpoint to right of position */
+
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ /* width_fac defines the width of the line in terms of the height of the characters */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(xmid,ymid-hline_w,outf);
+ PSlineto(xmid,ymid+hline_w,outf);
+ PSlineto(xright,ymid+hline_w,outf);
+ PSlineto(xright,ymid-hline_w,outf);
+ PSlineto(xmid,ymid-hline_w,outf);
+}
+
+void ALDrawLeftHalfHorizLine(
+ float Xpos, /* bottom left hand corner of character posn */
+ float Ypos, /* */
+ float Xspace, /* horizontal width of character position */
+ float Yspace, /* vertical height of character position */
+ float width_fac, FILE *outf) /* proportion of vertical height that the line will fill */
+
+/* draw line from midpoint to left of position */
+
+{
+ float xright,ytop;
+ float ymid;
+ float hline_w;
+ float xmid;
+
+ xright = Xpos + Xspace; /* right hand edge of character (lhe of next character) */
+ ytop = Ypos + Yspace; /* top edge of character */
+ ymid = (ytop + Ypos) * 0.5; /* vertical mid point */
+ xmid = (xright + Xpos) * 0.5; /* horizontal mid point */
+
+ /* width_fac defines the width of the line in terms of the height of the characters */
+
+ hline_w = 0.5 * (width_fac * (ytop - Ypos));
+
+ PSmoveto(xmid,ymid-hline_w,outf);
+ PSlineto(xmid,ymid+hline_w,outf);
+ PSlineto(Xpos,ymid+hline_w,outf);
+ PSlineto(Xpos,ymid-hline_w,outf);
+ PSlineto(xmid,ymid-hline_w,outf);
+}
+
+void PSmoveto(float x,float y,FILE *outf)
+{
+ fprintf(outf,"%.2f %.2f moveto\n",x,y);
+}
+void PSlineto(float x,float y,FILE *outf)
+{
+ fprintf(outf,"%.2f %.2f lineto\n",x,y);
+}
+void PSPutSpecialText(float Xpos,float Ypos,float Xspace,float Yspace,char *text,
+ unsigned char current_col,
+ unsigned char background_colour,float YspaceFactor,FILE *outf)
+/* Handle the special text characters */
+{
+
+ Yspace *= YspaceFactor; /* shrink the Y axis a little to avoid clashes.*/
+
+
+ if(strcmp(text,"@horizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fhorizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@thickhorizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fthickhorizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ PSstroke(outf);
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@thinhorizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fthinhorizline") == 0){
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ PSstroke(outf);
+ ALDrawHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@rightarrow") == 0){
+ ALDrawRightArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@frightarrow") == 0){
+/* ALDrawRightArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);*/
+/* temporary change to the right arrow width 20/1/1995*/
+ ALDrawRightArrow(Xpos,Ypos,(Xspace*0.7),Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawRightArrow(Xpos,Ypos,(Xspace*0.7),Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@leftarrow") == 0){
+ ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fleftarrow") == 0){
+ ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawLeftArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@uparrow") == 0){
+ ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fuparrow") == 0){
+ ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@suparrow") == 0){
+ ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fsuparrow") == 0){
+ ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawSmallUpArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@downarrow") == 0){
+ ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fdownarrow") == 0){
+ ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@sdownarrow") == 0){
+ ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fsdownarrow") == 0){
+ ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawSmallDownArrow(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@circle") == 0){
+ ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fcircle") == 0){
+ ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawCircle(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@diamond") == 0){
+ ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fdiamond") == 0){
+ ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawDiamond(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@bar") == 0){
+ ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fbar") == 0){
+ ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawBar(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@leftsemiend") == 0){
+ ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@fleftsemiend") == 0){
+ ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawLeftSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@rightsemiend") == 0){
+ ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ }else if(strcmp(text,"@frightsemiend") == 0){
+ ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+ ALDrawRightSemiEnd(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ }else if(strcmp(text,"@lefthelixend") == 0){
+
+ ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ PSstroke(outf);
+ ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",background_colour);
+
+ ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ PSstroke(outf);
+ ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,0.5,outf);
+ PSstroke(outf);
+
+ }else if(strcmp(text,"@righthelixend") == 0){
+
+ ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ PSstroke(outf);
+ ALDrawLeftHalfHorizLine(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ PSstroke(outf);
+ ALDrawPseudoEllipse(Xpos,Ypos,Xspace,Yspace,1.0,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+ ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ PSstroke(outf);
+ ALDrawRightHalfHorizLine(Xpos,Ypos,Xspace,Yspace,0.1,outf);
+ fprintf(outf,"closepath \n C%-d \n fill \n",current_col);
+
+
+ }else{
+ fprintf(stderr,"Error: Unrecognised special character: %s\n",text);
+ error(" ",1);
+ }
+}
+
+void PSstroke(FILE *outf)
+{
+ fprintf(outf,"stroke\n");
+}
+
+void PSnewpath(FILE *outf)
+{
+ fprintf(outf,"newpath\n");
+}
+
+void ALColourBackground(FILE *outf,int colour, int *b_region)
+{
+ int x1,y1,x2,y2;
+ x1 = b_region[0];
+ x2 = b_region[2];
+ y1 = b_region[1];
+ y2 = b_region[3];
+
+ fprintf(outf,"%d %d moveto %d %d lineto %d %d lineto %d %d lineto %d %d lineto closepath\n",
+ x1,y1,x2,y1,x2,y2,x1,y2,x1,y1);
+ fprintf(outf," C%-d \n fill \n",colour);
+ /* reset the colour to white */
+ /* fprintf(outf," C99\n");*/
+}
+
+void ALCheckLegalRange(int sx,int sy, int ex, int ey, int xmin, int ymin, int xmax, int ymax)
+/* check if sx, sy, ex, ey are within the limits given by xmin, ymin, xmax, ymax */
+{
+ extern FILE *std_err;
+ if( sx >= xmin && sx <= xmax
+ && sy >= ymin && sy <= ymax
+ && ex <= xmax && ex >= xmin
+ && ey <= ymax && ey >= ymin){
+ return;
+ }else{
+ fprintf(std_err,"\n\nALSCRIPT COMMAND FILE ERROR:\n");
+ fprintf(std_err,"Maximum legal range:\n");
+ fprintf(std_err,"From position %d of sequence %d to position %d of sequence %d\n",
+ xmin,ymin,xmax,ymax);
+
+ fprintf(std_err,"Your range:\n");
+ fprintf(std_err,"From position %d of sequence %d to position %d of sequence %d\n",
+ sx,sy,ex,ey);
+
+ GJerror("Range too big for alignment - try again!");
+ exit(0);
+ }
+}
+
+void ALMakeHelixText(int sx, int sy, int ex, char ***texts)
+{
+ int i;
+ texts[sx][sy] = GJstrdup("@lefthelixend");
+ texts[ex][sy] = GJstrdup("@righthelixend");
+ for(i=sx+1;i<ex;++i){
+ texts[i][sy] = GJstrdup("@fthickhorizline");
+ }
+}
+
+void ALMakeStrandText(int sx, int sy, int ex, char ***texts)
+{
+ int i;
+ texts[ex][sy] = GJstrdup("@frightarrow");
+ for(i=sx;i<ex;++i){
+ texts[i][sy] = GJstrdup("@fhorizline");
+ }
+}
+
+void ALMakeCoilText(int sx, int sy, int ex, char ***texts)
+{
+ int i;
+ for(i=sx;i<ex+1;++i){
+ texts[i][sy] = GJstrdup("@fthinhorizline");
+ }
+}
+
+int ALrel(char *pos,int *relnum)
+/* ALrel: parses a string that defines a position in a sequence. This can
+have the form
+
+to indicate position 10 10
+to indicate three before 10 10-3
+to indicate five after 10 10+5
+
+The routine looks up the relative number in *relnum before adding or
+subtracting numbers, the end result is therefore relative to the current
+alignment position.
+
+It should be easy to extend this routine for the relative movement to
+apply to positions in another sequence rather than alignment
+coordinates. (e.g. 10+5:73 might mean 5 after the current position in sequence 73).
+*/
+
+{
+ int i;
+ int len;
+ char *token;
+ int ipos,ioff; /* position and offset */
+ extern FILE *std_in,*std_out,*std_err;
+
+ len = strlen(pos);
+ ioff = 0;
+ ipos = 0;
+
+
+ if(strchr(pos,'+') != NULL){
+ token = strtok(pos,"+");
+ if(strlen(token)== 0){
+ error("Error decoding position",1);
+ fprintf(std_err,"Offending string is: %s\n",pos);
+ }else{
+ ipos = atoi(token);
+ }
+ token = strtok(NULL,"\0");
+ if(strlen(token)== 0){
+ error("Error decoding position",1);
+ fprintf(std_err,"Offending string is: %s\n",pos);
+ }else{
+ ioff = atoi(token);
+ }
+ return (relnum[ipos] + ioff);
+ }else if(strchr(pos,'-') != NULL){
+ token = strtok(pos,"-");
+ if(strlen(token)== 0){
+ error("Error decoding position",1);
+ fprintf(std_err,"Offending string is: %s\n",pos);
+ }else{
+ ipos = atoi(token);
+ }
+ token = strtok(NULL,"\0");
+ if(strlen(token)== 0){
+ error("Error decoding position",1);
+ fprintf(std_err,"Offending string is: %s\n",pos);
+ }else{
+ ioff = atoi(token);
+ }
+ return (relnum[ipos] - ioff);
+ }else{
+ ipos = atoi(pos);
+ return relnum[ipos];
+ }
+}
+
+int *ALCalCons(struct seqdat *bloc,
+ int sx,int sy,int ex,int ey,int *ret_val,int len)
+
+/* Calculate conservation for an alignment - this can be just a segment of an alignment */
+/* bloc = the alignment bloc */
+/* sx,sy,ex,ey = the positions over which to calculate the conservation */
+/* conscut = conservation number cutoff ( an integer 0 - 10) */
+/* ret_val = a pointer to an integer array to store the results of the calculation */
+/* len = the length of the array ret_val - this must be the same as the alignment length */
+
+{
+ int i,j,tlen,k;
+ char *temp;
+ char *temp2;
+ float tval;
+ int gcount;
+
+ tlen = ey -sy + 1;
+ temp = GJstrcreate(tlen+1,NULL);
+ if(ret_val == NULL){
+ ret_val = (int *) GJmalloc(sizeof(int) * len);
+ }
+
+ for(i=sx;i<(ex+1);++i){
+ /* calculate conservation at each position */
+ k = 0;
+ for(j=sy;j<(ey+1);++j){
+ temp[k] = bloc[j].seq[i];
+ ++k;
+ }
+ temp2 = GJstoupper(temp);
+ /* check for all gap columns */
+ gcount = 0;
+ for(j=0;j<tlen;++j){
+ if(temp2[j] == ' ') ++gcount;
+ }
+ if(gcount == tlen){
+ tval = 0.0;
+ }else{
+ tval = mzcons((unsigned char *)temp2,tlen);
+ }
+/* fprintf(stderr,"In calcons: i:%d tlen:%d temp:%s tval:%f\n",i,tlen,temp,tval);*/
+ ret_val[i] = 10 * tval;
+ GJfree(temp2);
+ }
+ GJfree(temp);
+ return ret_val;
+}
+
+float mzcons(unsigned char *pos,int n)
+/* calculate conservation value according to Zvelebil et al for a set
+ of amino acids and gaps stored in string pos of length n
+ translated from the fortran mzcons.f 6/3/1995
+*/
+
+{
+ /* -- conmat contains a table like that shown in the JMB paper
+ order of amino acids is GAP,ARNDCQEGHILKMFPSTWYVBZX
+ */
+ static char *acids = " ARNDCQEGHILKMFPSTWYVBZX";
+ static int conmat[24][10] = {
+ {1,1,1,1,1,1,1,1,1,1}, /* */
+ {1,0,0,0,0,1,1,0,0,0}, /*A */
+ {0,1,0,1,1,0,0,0,0,0}, /*R */
+ {0,0,0,1,0,1,0,0,0,0}, /*N */
+ {0,0,1,1,1,1,0,0,0,0}, /*D */
+ {1,0,0,0,0,1,0,0,0,0}, /*C */
+ {0,0,0,1,0,0,0,0,0,0}, /*Q */
+ {0,0,1,1,1,0,0,0,0,0}, /*E */
+ {1,0,0,0,0,1,1,0,0,0}, /*G */
+ {1,1,0,1,1,0,0,0,1,0}, /*H */
+ {1,0,0,0,0,0,0,1,0,0}, /*I */
+ {1,0,0,0,0,0,0,1,0,0}, /*L */
+ {1,1,0,1,1,0,0,0,0,0}, /*K */
+ {1,0,0,0,0,0,0,0,0,0}, /*M */
+ {1,0,0,0,0,0,0,0,1,0}, /*F */
+ {0,0,0,0,0,1,0,0,0,1}, /*P */
+ {0,0,0,1,0,1,1,0,0,0}, /*S */
+ {1,0,0,1,0,1,0,0,0,0}, /*T */
+ {1,0,0,1,0,0,0,0,1,0}, /*W */
+ {1,0,0,1,0,0,0,0,1,0}, /*Y */
+ {1,0,0,0,0,1,0,1,0,0}, /*V */
+ {0,0,0,1,0,0,0,0,0,0}, /*B */
+ {0,0,0,1,0,0,0,0,0,0}, /*Z */
+ {1,1,1,1,1,1,1,1,1,1} /*X */
+ };
+
+ int concnt,it,i,j,k,l,tcnt,ibseq;
+ int nide;
+ float con;
+ unsigned char facid;
+
+ concnt = 0;
+ for(j=0;j<10;++j){
+ /*found: outer loop over properties
+ set IT to the value of the first amino acid*/
+ it = conmat[GJindex(acids,pos[0])][j];
+ /*loop over remaining acids, if a difference occurs then
+ set tcnt to 1*/
+ tcnt = 0;
+ for(k=1;k<n;++k){
+ if(it != conmat[GJindex(acids,pos[k])][j]){
+ tcnt = 1;
+ }
+ }
+ /*add tcnt to concnt*/
+ concnt += tcnt;
+ }
+ /* check for total identity at this position*/
+ facid = pos[0];
+ nide = 0;
+ for(k=1;k<n;++k){
+ if(facid == pos[k]){
+ ++nide;
+ }
+ }
+
+ /*calculate the conservation*/
+ if(concnt == 10){
+ con = 0.0;
+ }else if(concnt == 0){
+ if(nide == (n-1)){
+ /*total identity*/
+ con = 1.0;
+ }else{
+ /*not identity, but same properties*/
+ con = 0.9;
+ }
+ }else{
+ con = 0.9 - 0.1 * concnt;
+ }
+ return con;
+}
+
+
+int GJindex(char *str,char c)
+{
+ char *t;
+ t = strchr(str,c);
+ if(t == NULL) return -1;
+ return (int) (t - str);
+}
+