📄 postbgi.c
字号:
if ( strcmp(*argv, "-") == 0 ) fp_in = stdin; else if ( (fp_in = fopen(*argv, "r")) == NULL ) error(FATAL, "can't open %s", *argv); conv(); if ( fp_in != stdin ) fclose(fp_in); argc--; argv++; } /* End while */} /* End of arguments *//*****************************************************************************/done(){/* * * Finished with the last input file, so mark the end of the pages, make sure the * last page is printed, and restore the initial environment. * */ fprintf(stdout, "%s", TRAILER); fprintf(stdout, "done\n"); fprintf(stdout, "%s %s\n", DOCUMENTFONTS, fontname); fprintf(stdout, "%s %d\n", PAGES, printed);} /* End of done *//*****************************************************************************/account(){/* * * Writes an accounting record to *fp_acct, provided it's not NULL. * */ if ( fp_acct != NULL ) fprintf(fp_acct, " print %d\n copies %d\n", printed, copies);} /* End of account *//*****************************************************************************/conv(){ int ch; /* next input character *//* * * Controls the conversion of BGI files into PostScript. Not everything has been * implemented, but what's been done should be good enough for our purposes. * */ redirect(-1); /* get ready for the first page */ bgimode = 0; formfeed(); while ( (ch = get_char()) != EOF ) { switch ( ch ) { case BRCHAR: /* rotated character mode */ bgimode = ch; text(90); break; case BCHAR: /* graphical character mode */ bgimode = ch; text(0); break; case BGRAPH: /* graphical master mode */ bgimode = ch; break; case BSUB: /* subroutine definition */ subr_def(); break; case BRET: /* end of subroutine */ subr_end(); break; case BCALL: /* subroutine call */ subr_call(); break; case BEND: /* end display - page */ formfeed(); break; case BERASE: /* erase - shouldn't be used */ error(FATAL, "BGI erase opcode obsolete"); break; case BREP: /* repeat */ error(FATAL, "Repeat not implemented"); repeat(); break; case BSETX: /* new x coordinate */ hgoto(get_int(0)); break; case BSETY: /* new y coordinate */ vgoto(get_int(0)); break; case BSETXY: /* new x and y coordinates */ hgoto(get_int(0)); vgoto(get_int(0)); break; case BINTEN: /* mark the current point */ fprintf(fp_out, "%d %d p\n", hpos, vpos); break; case BVISX: /* visible x */ vector(X_COORD, VISIBLE); break; case BINVISX: /* invisible x */ vector(X_COORD, INVISIBLE); break; case BVISY: /* visible y */ vector(Y_COORD, VISIBLE); break; case BINVISY: /* invisible y */ vector(Y_COORD, INVISIBLE); break; case BVEC: /* arbitrary vector */ vector(LONGVECTOR, VISIBLE); break; case BSVEC: /* short vector */ vector(SHORTVECTOR, VISIBLE); break; case BRECT: /* draw rectangle */ rectangle(OUTLINE); break; case BPOINT1: /* point plot 1 */ case BPOINT: /* point plot 2 */ point_plot(ch, get_char()); break; case BLINE: /* line plot */ line_plot(); break; case BLTY: /* line type */ fprintf(fp_out, "%s l\n", styles[get_data()]); break; case BARC: /* circular arc */ arc(OUTLINE); break; case BFARC: /* filled circle */ arc(FILL); break; case BFRECT: /* filled rectangle */ rectangle(FILL); break; case BRASRECT: /* raster rectangle */ error(FATAL, "Raster Rectangle not implemented"); break; case BCOL: /* select color */ set_color(get_data()); break; case BFTRAPH: /* filled trapezoid */ trapezoid(); break; case BPAT: /* pattern for area filling */ pattern(); break; case BCSZ: /* change BGI character 'size' */ setsize(get_data()); break; case BNOISE: /* from bad file format */ break; default: /* don't recognize the code */ error(FATAL, "bad BGI command %d (0%o)", ch, ch); break; } /* End switch */ if ( debug == ON ) fprintf(stderr, "\n"); } /* End while */ formfeed(); /* in case BEND was missing */} /* End of conv *//*****************************************************************************/hgoto(n) int n; /* new horizontal position */{/* * * Sets the current BGI horizontal position to n. * */ hpos = n;} /* End of hgoto *//*****************************************************************************/vgoto(n) int n; /* move to this vertical position */{/* * * Sets the absolute vertical position to n. * */ vpos = n;} /* End of vgoto *//*****************************************************************************/setsize(n) int n; /* BGI size - just a grid separation */{/* * * Called when we're supposed to change the BGI character size to n. The BGI * size is the grid separation in a 5 by 7 array in which characters are assumed * to be built. * */ bgisize = n; linespace = LINESPACE(bgisize); fprintf(fp_out, "%d f\n", bgisize); if ( debug == ON ) fprintf(stderr, "BGI size = %d\n", n);} /* End of setsize *//*****************************************************************************/repeat(){ int count; /* repeat this many times */ int ch; /* next input character *//* * * Haven't implemented repeats, although it wouldn't be difficult. Apparently it's * not used by any graphics packages that generate BGI. * */ count = get_int(); /* get the repeat count */ while ( (ch = get_char()) != EOF && ch != BENDR ) ;} /* End of repeat *//*****************************************************************************/text(angle) int angle; /* either 0 or 90 degrees */{ int ch; /* next character from file *fp_in *//* * * Called from conv() after we've entered one of the graphical character modes. * Characters are read from the input file and printed until the next mode change * opcode is found (or until EOF). angle will be 90 for rotated character mode * and 0 otherwise. * * */ fprintf(fp_out, "%d %d %d(", angle, hpos, vpos); while ( (ch = get_char()) != EOF ) { if ( ch == BGRAPH || ch == BCHAR || ch == BRCHAR ) { ungetc(ch, fp_in); position--; break; } /* End if */ switch ( ch ) { case '\012': vgoto(vpos - linespace); case '\015': hgoto(0); fprintf(fp_out, ")t\n%d %d %d(", angle, hpos, vpos); break; case '(': case ')': case '\\': putc('\\', fp_out); default: if ( isascii(ch) && isprint(ch) ) putc(ch, fp_out); else fprintf(fp_out, "\\%.3o", ch & 0377); break; } /* End switch */ } /* End while */ fprintf(fp_out, ") t\n");} /* End of text *//*****************************************************************************/formfeed(){ int ch; /* repeat count for this page *//* * * Does whatever is needed to print the last page and get ready for the next one. * It's called, from conv(), after a BEND code is processed. I'm ignoring the * copy count that's expected to follow each page. * */ if ( bgimode == BGRAPH && (ch = get_char()) != EOF && ! (ch & MSB) ) { ungetc(ch, fp_in); position--; } /* End if */ if ( fp_out == stdout ) /* count the last page */ printed++; fprintf(fp_out, "cleartomark\n"); fprintf(fp_out, "showpage\n"); fprintf(fp_out, "saveobj restore\n"); fprintf(fp_out, "%s %d %d\n", ENDPAGE, page, printed); while ( (ch = get_char()) == 0 ) ; /* skip any NULL characters */ ungetc(ch, fp_in); position--; if ( ungetc(getc(fp_in), fp_in) == EOF ) redirect(-1); else redirect(++page); fprintf(fp_out, "%s %d %d\n", PAGE, page, printed+1); fprintf(fp_out, "/saveobj save def\n"); fprintf(fp_out, "mark\n"); writerequest(printed+1, fp_out); fprintf(fp_out, "%d pagesetup\n", printed+1); setsize(bgisize); hpos = vpos = 0;} /* End of formfeed *//*****************************************************************************/subr_def(){/* * * Starts a subroutine definition. All subroutines are defined as PostScript * procedures that begin with the character S and end with the subroutine's id * (a number between 0 and 63 - I guess). The primary, and perhaps only use of * subroutines is in special color plots produced by several graphics libraries, * and even there it's not all that common. I've also chosen not to worry about * nested subroutine definitions - that would certainly be overkill! * * All subroutines set up their own (translated) coordinate system, do their work * in that system, and restore things when they exit. To make everything work * properly we save the current point (in shpos and svpos), set our position to * (0, 0), and restore things at the end of the subroutine definition. That means * hpos and vpos measure the relative displacement after a subroutine returns, and * we save those values in the displacement[] array. The displacements are used * (in subr_call()) to properly adjust our position after each subroutine call, * and all subroutines are called with the current x and y coordinates on top of * the stack. * */ if ( in_subr == TRUE ) /* a nested subroutine definition?? */ error(FATAL, "can't handle nested subroutine definitions"); if ( (subr_id = get_data()) == EOF ) error(FATAL, "missing subroutine identifier"); if ( in_global == FALSE ) { /* just used to reduce file size some */ fprintf(fp_out, "cleartomark\n"); fprintf(fp_out, "saveobj restore\n"); fprintf(fp_out, "%s", BEGINGLOBAL); in_global = TRUE; } /* End if */ fprintf(fp_out, "/S%d {\n", subr_id); fprintf(fp_out, "gsave translate\n"); shpos = hpos; /* save our current position */ svpos = vpos; hgoto(0); /* start at the origin */ vgoto(0); in_subr = TRUE; /* in a subroutine definition */} /* End of subr_def *//*****************************************************************************/subr_end(){ int ch; /* for looking at next opcode *//* * * Handles stuff needed at the end of each subroutine. Want to remember the change * in horizontal and vertical positions for each subroutine so we can adjust our * position after each call - just in case. The current position was set to (0, 0) * before we started the subroutine definition, so when we get here hpos and vpos * are the relative displacements after the subroutine is called. They're saved in * the displacement[] array and used to adjust the current position when we return * from a subroutine. * */ if ( in_subr == FALSE ) /* not in a subroutine definition?? */ error(FATAL, "subroutine end without corresponding start"); fprintf(fp_out, "grestore\n"); fprintf(fp_out, "} def\n"); if ( in_global == TRUE && (ch = get_char()) != BSUB ) { fprintf(fp_out, "%s", ENDGLOBAL); fprintf(fp_out, "/saveobj save def\n"); fprintf(fp_out, "mark\n"); in_global = FALSE; } /* End if */ ungetc(ch, fp_in); /* put back the next opcode */ displacement[subr_id].dx = hpos; displacement[subr_id].dy = vpos; hgoto(shpos); /* back to where we started */ vgoto(svpos); in_subr = FALSE; /* done with the definition */} /* End of subr_end *//*****************************************************************************/subr_call(){ int ch; /* next byte from *fp_in */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -