⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postbgi.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
	    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 + -