#include "dv_all.h" #include /*----------------------------------------*/ /* HPGL specific section */ /*----------------------------------------*/ typedef struct hpglrecord { char *hatch; int bgnd, fgnd; } hpglrecord; static hpglrecord hpglrec[5]; /* HPGL-specifics*/ static double hpglcell; /* character cell size */ static int actcol; /* actual color No. */ static int hpglpen; /* actual pen No. (1-8/0) */ static char *hpglhatch; /* actual hatch type */ #define HATCHES 4 static char *hatches[HATCHES] = { "", "3,0.8,45", "4,0.8,0", "1" }; /* -------------- VERY simple output optimizer */ typedef struct { char c; byte col; float px, py; } STORE; #define MAX_STORE 256 static STORE store[MAX_STORE]; static int store_idx = 0; static int print_len = 0; static char buf[100]; static void print(char *fmt, ...) { va_list argptr; int len; va_start(argptr, fmt); len = vsprintf(buf, fmt, argptr); va_end(argptr); if (print_len+len > 78) { uwriteln(&outfile, ""); print_len = 0; } fprintf(outfile.f, "%s", buf); print_len += len; } /* select a new pen */ static int select_pen(int pen) { if (pen != hpglpen) { hpglpen = pen; print("SP%d;", hpglpen); return TRUE; } return FALSE; } /* write out all stored characters */ static void flush_fg(int pen) { int idx; for (idx = 0; idx < store_idx; ++idx) { if ( store[idx].c != ' ' && hpglrec[store[idx].col].fgnd == pen ) { select_pen(pen); print("PU%1.2f,%1.2f;", store[idx].px, store[idx].py); print("LB%c\003;", store[idx].c); } } } /* draw all saved background shadings */ static void flush_bg(int pen) { int idx, h; if (pen <= 0) return; for (idx = 0; idx < store_idx; ++idx) { if (hpglrec[store[idx].col].bgnd != pen) continue; for (h = 0; h < HATCHES; ++h) { if (hpglrec[store[idx].col].hatch == hatches[h]) { double act_x = store[idx].px - dev_xsize/8; double act_y = store[idx].py - dev_ysize/4; select_pen(pen); print("PU%1.2f,%1.2f;", act_x, act_y); if (hatches[h] != hpglhatch) { hpglhatch = hatches[h]; print("FT%s;", hpglhatch); } print("RR%1.2f,%1.2f;", dev_xsize, dev_ysize); } } } } /* save stored character cells */ static void store_flush(void) { int p, sp; /* first background */ sp = hpglpen; flush_bg(sp); /* actual pen first */ for (p=1; p < 10; ++p) if (p!=sp) flush_bg(p); /* then foreground */ sp = hpglpen; flush_fg(sp); /* actual pen first */ for (p=0; p < 10; ++p) if (p!=sp) flush_fg(p); store_idx = 0; } /* save a character for optimizing HPGL output */ static void store_char(char c, int col, double px, double py) { store[store_idx].c = c; store[store_idx].px = (float) px; store[store_idx].py = (float) py; store[store_idx].col= (byte) col; ++store_idx; if (store_idx == MAX_STORE) store_flush(); } /* - - - - - - - - - - - - - - */ static void menu_hpgl(hpglrecord *hpglrec, BOOL *lc, char *txt, char *parstring) { char code1, code2; char instring[41]; if (interactflag) { printf("\n-------------------------------------------------------------\n" "Enter the text attributes for printing of **>%s<** residues:\n", txt); printf("First choose color and hatching type of the letter **>background<**\n" "NUMBERS specify plotter Pens,\n" "LETTERS specify hatching types.\n" "input has to be composed of a number and a letter\n" "1-9, 0 : PEN No. (0 means no background)\n" "(N) : no hatching (S) : slash\n" "(C) : crosshatch (F) : fill\n\n" "choose a number and a letter ( * %c%c * ) : ", parstring[0], parstring[1]); Fgets(instring, 41, stdin); } else *instring = '\0'; if (*instring == '\0') { code1 = parstring[0]; code2 = parstring[1]; } else { code1 = instring[0]; code2 = instring[1]; } code1 = toupper(code1); code2 = toupper(code2); if (strchr("NSCF", code2) == NULL) code2 = 'N'; switch (code2) { case 'N': hpglrec->hatch = hatches[0]; break; case 'S': hpglrec->hatch = hatches[1]; break; case 'C': hpglrec->hatch = hatches[2]; break; case 'F': hpglrec->hatch = hatches[3]; break; } hpglrec->bgnd = code1-'0'; if (interactflag) { printf("\n\nEnter the text attributes for printing of **>%s<** residues:\n", txt); printf("Now choose color and case of the letter **>foreground<**\n" "NUMBERS specify plotter Pens,\n" "A letter \"n\" behind the number means \"normal printing\"\n" "A letter \"l\" behind the number means \"lowercase printing\"\n" "1-9, 0 : PEN No. (0 means no printing)\n" "e.g. \"1n\" means : PEN #1 is to be used\n" "e.g. \"2l\" means : PEN #2 and lowercase types are to be used\n\n" "choose a number and a letter ( * %c%c * ) : ", parstring[2], parstring[3]); Fgets(instring, 41, stdin); } else *instring = '\0'; if (*instring == '\0') { code1 = parstring[2]; code2 = parstring[3]; } else { code1 = instring[0]; code2 = instring[1]; } if (code2 == 'L' || code2 == 'l') *lc = TRUE; else *lc = FALSE; hpglrec->fgnd = code1 - '0'; } static void ask_hpgl(void) { char parstring[6]; char instring[41]; term_par("HPGL"); if (interactflag) printf( "-----------------------------------------------------------------------\n"); Fgets(parstring, 6, parfile); parstring[4] = '\0'; menu_hpgl(hpglrec, lc, "different", parstring); Fgets(parstring, 6, parfile); parstring[4] = '\0'; menu_hpgl(&hpglrec[1], &lc[1], "identical", parstring); Fgets(parstring, 6, parfile); parstring[4] = '\0'; if (simflag) menu_hpgl(&hpglrec[2], &lc[2], "similar", parstring); else { hpglrec[2] = hpglrec[0]; lc[2] = lc[0]; } Fgets(parstring, 6, parfile); parstring[4] = '\0'; if (globalflag) menu_hpgl(&hpglrec[3], &lc[3], "conserved", parstring); else { hpglrec[3] = hpglrec[1]; lc[3] = lc[1]; } hpglrec[4].bgnd = 0; hpglrec[4].hatch = hatches[0]; hpglrec[4].fgnd = hpglrec[0].fgnd; lc[4] = FALSE; fscanf(parfile, "%lg%*[^\n]", &hpglcell); getc(parfile); Fgets(parstring, 6, parfile); if (parstring[0] == 'Y' || parstring[0] == 'y') landscapeflag = TRUE; else landscapeflag = FALSE; if (interactflag) { do { printf("Character size in Points ( * %4.1f * ) : ", hpglcell); Fgets(instring, 41, stdin); if (*instring != '\0') hpglcell = str2int((void *)instring); } while (hpglcell < 1 || hpglcell > 100); printf("Rotate plot ( * %c * ) : ", YESNO(landscapeflag)); Fgets(instring, 41, stdin); if (*instring != '\0') { if (instring[0] == 'Y' || instring[0] == 'y') landscapeflag = TRUE; else landscapeflag = FALSE; } } if (!cloutflag) { printf("filename for HPGL-output : "); Gets(outname,sizeof(outname)-1); } } static void HPGLinit(double *xpos, double *ypos) { double xd, yd; if (landscapeflag) { dev_minx = 10.75; /* borders of a A4 page in mm */ dev_miny = 5.0; dev_maxx = 260.75; dev_maxy = 185.0; } else { dev_minx = 5.0; /* borders of a A4 page in mm */ dev_miny = 10.75; dev_maxx = 185.0; dev_maxy = 260.75; } dev_xsize = hpglcell * 0.351; dev_ysize = hpglcell * 0.351 * 2.0 / 1.5; hpglpen = 0; hpglhatch = hatches[0]; *xpos = dev_minx; *ypos = dev_maxy; /* 0,0 is lower left corner */ assert(outopen(&outfile, outname) != NULL); xd = dev_xsize * 100 / 1.5 / (dev_maxx - dev_minx); yd = dev_ysize * 100 / 2.0 / (dev_maxy - dev_miny); print("IN;%sIP;SI%5.3f;", (landscapeflag?"RO 90;":""), hpglcell*0.351); print("SC%1.2f,%1.2f,%1.2f,%1.2f;", dev_minx,dev_maxx, dev_miny,dev_maxy); print("SR%1.4f,%1.4f;", xd, yd); uwriteln(&outfile, "PU;"); print_len = 0; } static void HPGLsetcolor(int colno) { actcol = colno; } static void HPGLcharout(char c, double *xpos, double *ypos) { store_char(c, actcol, *xpos, *ypos); *xpos += dev_xsize; } static void HPGLnewline(double *xpos, double *ypos) { *xpos = dev_minx; *ypos -= dev_ysize; } static void HPGLnewpage(double *xpos, double *ypos) { store_flush(); uwriteln(&outfile, "PG"); print_len = 0; *xpos = dev_minx; *ypos = dev_maxy; print("PU;"); } static void HPGLexit(void) { store_flush(); uwriteln(&outfile, "PG"); print_len = 0; if (outfile.f != NULL) fclose(outfile.f); outfile.f = NULL; } GraphicsDevice Hpgl = { "HPGL", ask_hpgl, HPGLinit, HPGLsetcolor, HPGLcharout, GenericStringOut, HPGLnewline, HPGLnewpage, HPGLexit };