1 /*****************************************************************
2 * HMMER - Biological sequence analysis with profile HMMs
3 * Copyright (C) 1992-1999 Washington University School of Medicine
6 * This source code is distributed under the terms of the
7 * GNU General Public License. See the files COPYING and LICENSE
9 *****************************************************************/
12 * SRE, Thu Jun 21 18:02:31 2001 [St. Louis]
14 * Some crude support for Encapsulated PostScript (EPS) output,
17 * CVS $Id: eps.c,v 1.1.1.1 2005/03/22 08:34:17 cmzmasek Exp $
26 /* Function: EPSWriteSmallMSA()
27 * Date: SRE, Thu Jun 21 18:15:21 2001 [St. Louis]
29 * Purpose: Write an alignment in singleblock, Stockholm/SELEX like
30 * format to an open file. Very crude.
31 * Currently fails if the alignment is >50 columns long, because
32 * it doesn't think it will fit on a single page.
34 * Args: fp - open file for writing
35 * msa - alignment to write
40 EPSWriteSmallMSA(FILE *fp, MSA *msa)
42 int namewidth; /* namewidth in PostScript units */
43 int fontwidth; /* width of a character in this font */
44 int hspace; /* horizontal space between aligned chars */
45 int vspace; /* vertical space between sequences */
46 char *font; /* font name, e.g. "Courier" */
47 int fontsize; /* font size in pts */
48 int i,j; /* counter over sequences, columns */
49 int len; /* tmp var holding length of something */
50 int width, height; /* width and height of bounding box */
51 int xpos, ypos; /* x,y position */
53 /* Set some font characteristics; done here, so it'll
54 * be easy to change. Magic numbers for Courier 12 determined
60 font = sre_strdup("Courier", -1);
63 /* Find the width of the longest sequence name in characters.
66 for (i = 0; i < msa->nseq; i++)
67 if ((len = (int) strlen(msa->sqname[i])) > namewidth)
69 namewidth += 1; /* add a space to separate name & aligned seq */
70 namewidth *= fontwidth;
72 /* Determine bounding box
74 if (msa->alen > 50) Die("No EPS fmt if alignment is >50 columns");
75 width = namewidth + hspace*msa->alen;
76 if (width > 612) Die("Alignment too wide to write in EPS");
77 height = vspace*msa->nseq;
78 if (height > 792) Die("Too many seqs to write in EPS");
80 /* Magic EPS header, bare-bones DSC-compliant.
82 fprintf(fp, "%%!PS-Adobe-3.0 EPSF-3.0\n");
83 fprintf(fp, "%%%%BoundingBox: %d %d %d %d\n", 0, 0, width, height);
84 fprintf(fp, "%%%%Pages: 1\n");
85 fprintf(fp, "%%%%EndComments\n");
87 /* More postscript magic before we start the alignment
89 fprintf(fp, "/%s findfont\n", font);
90 fprintf(fp, "%d scalefont\n", fontsize);
91 fprintf(fp, "setfont\n");
92 fprintf(fp, "newpath\n");
94 /* Write the alignment in PostScript in a single block
96 for (i = 0; i < msa->nseq; i++)
98 ypos = (msa->nseq-i-1)*vspace;
100 fprintf(fp, "%d %d moveto\n", 0, ypos);
101 fprintf(fp, "(%s) show\n", msa->sqname[i]);
104 for (j = 0; j < msa->alen; j++)
106 fprintf(fp, "%d %d moveto\n", xpos, ypos);
107 fprintf(fp, "(%c) show\n", msa->aseq[i][j]);