📄 ipress.c
字号:
/*----------------------------------------------------------------------------- * Copyright (c) 1984, 1985, 1986 Xerox Corp. * * ipress - most of the code directly dependent on interpress used by dipress * to produce an interpress file from device independent troff * intermediate code. * * William LeFebvre * * * HISTORY * 12-Aug-86 Lee Moore (lee) at Xerox Webster Research Center * Added positioning option to the RES command. * * * 07-Jul-86 Lee Moore (lee) at Xerox Webster Research Center * Updated IPDeviceType for services 10.0 . * * 24-Feb-86 Lee Moore (lee) at Xerox Webster Research Center * Added a subroutine to emit the SequenceInsertFile command. * * John Mellor-Crummey 28-aug-1985 * restructuring and minor modifications * * ed flint 10-may-1985 * coerce device.num_char_wid to unsigned char, change * ch argument in outputChar to unsigned int * since we now have > 128 special characters *---------------------------------------------------------------------------*/#include <stdio.h>#include <ctype.h>#include <signal.h>#include <math.h>#include <sys/types.h>#include <sys/file.h>#include <sys/stat.h>#include "deviceinfo.h" /* typesetter characteristics */#include "iptokens.h" /* \ */#include "literal.h" /* > interface levels for interpress */#include "operator.h" /* / */#include "defs.h" /* constant and macro definitions */#include "externs.h" /* declarations for global variables *//* initialize device */initDevice() { int lines = 0; int timapf; int ret; register char *ptr; register char **ipp; register char **trp; char temp[60]; struct stat stbuf; if (dbg) printf("initDevice called\n"); /* start the preamble */ ip_select(outputfile); /* special master instructions go here... */ AppendOp(OP_beginBlock); AppendOp(OP_beginBody); /* save scaling transform that uses a mica co-ordinate system */ AppendRational(1L, 100000); AppendOp(OP_scale); AppendInteger((long) F_transform); AppendOp(OP_fset); /* select file that holds page bodies */ ip_select(pagebodyfile); /* open file that maps troff names to interpress names */ (void) sprintf(temp, "%s/dev%s/interpress-fonts", fontdirectory, devicename); if ((timapf = open(temp, O_RDONLY,0)) == -1) reportError(QUIT, "can't open %s (%s)", temp, sys_errlist[errno]); /* read in the whole thing */ ret = fstat(timapf, &stbuf); if (dbg) printf("stat returned %d, errno %d\n", ret, errno); timap = malloc((unsigned)(stbuf.st_size + 1)); if (dbg) printf("reading %d bytes from timapf\n", stbuf.st_size); ret = read(timapf, timap, (int)stbuf.st_size); if (dbg) printf("read returned %d, errno %d, timapf %d\n", ret, errno, timapf); timap[(int)stbuf.st_size] = '\0'; (void) close(timapf); /* count the newlines */ if (dbg) printf("pointer starts at %08x ... ", timap); for (ptr = timap; *ptr != '\0'; ptr++) if (*ptr == '\n') lines++; if (dbg) printf("ends at %08x\n", ptr); if (dbg) printf("found %d lines\n", lines); /* allocate the mapping arrays */ trp = trname = (char **)malloc((unsigned)(lines * 2 * sizeof(char *))); ipp = ipname = trname + lines; /* break out the strings and store pointers in the arrays */ ptr = timap; mapcnt = 0; while (*ptr) { if (dbg) printf("loop: ptr = %08x, *ptr = %c\n", ptr, *ptr); *trp++ = ptr; while (!white(*ptr)) ptr++; *ptr++ = '\0'; while (white(*ptr)) ptr++; *ipp++ = ptr; while (*++ptr != '\n') /* nothing */; *ptr++ = '\0'; mapcnt++; } if (dbg) { int i; for (i = 0; i < lines; i++) printf("%s\t%s\n", trname[i], ipname[i]); } /* reset vertical and horizontal positions */ hor_pos = ver_pos = old_hor = old_ver = 0; /* reset the font information */ bzero((char *) currfonts, sizeof(currfonts));}setScale(spi) /* set resolution */int spi;{ /* set the scaling variable used in all x and y calculations */ scale = floor(2540.0 / (double)spi + 0.5); if (dbg) printf("setScale(%d) sets scale to %e\n", spi, scale); /* * Set the drawing scale based on the scale. This factor is applied to * all points drawn in the bitmap for graphical objects. It is scaled * down from micas to 508 dpi so that the bitmaps aren't of unwieldy * size, but still retain enough information to look decent on a good * device. 508/2540 == 0.2 */ drawscale = scale * .2; if (dbg) printf("setScale(%d) sets drawscale to %e\n", spi, drawscale);}pushCurrentEnv() /* begin a new block */{ statep->ssize = size; statep->sfont = font; statep->shorig = hor_orig; statep->svorig = ver_orig; statep->shpos = hor_pos; statep->svpos = ver_pos; hor_orig = hor_pos; ver_orig = ver_pos; hor_pos = ver_pos = 0; if (statep++ >= state + MAXSTATE) { reportError(QUIT, "{ nested too deep"); } hor_pos = ver_pos = 0;}popSavedEnv() /* pop to previous state */{ if (--statep < state) { reportError(QUIT, "extra }"); } size = statep->ssize; font = statep->sfont; hor_pos = statep->shpos; ver_pos = statep->svpos; hor_orig = statep->shorig; ver_orig = statep->svorig;}newpage(n) /* new page */int n;{ int i; char buff[15]; /* print any pending bitmap */ /* terminate previous page if outputting */ if (outputflag) { print_bitmap(); AppendOp(OP_endBody); } else flush_bitmap(); /* reset vertical positions */ ver_pos = old_ver = 0; /* check new page number against those found in the nPageRanges */ if (nPageRanges == 0) { /* no -o specified -- do all pages */ outputflag = 1; } else { /* see if new page has been selected for output */ outputflag = 0; for (i = 0; i < nPageRanges; i++) { if ((n >= pagerange[i][0]) && (n <= pagerange[i][1])) { outputflag = 1; break; } } } /* start new page */ if (outputflag) { AppendOp(OP_beginBody); (void) sprintf(buff, "Page %d", n); AppendComment(buff); Fget(F_transform); AppendOp(OP_concatt); AppendInteger(2L); AppendInteger((long) I_strokeEnd); AppendOp(OP_iset); } /* font/size no longer valid -- force a new assignment */ oldftsz = -1;}newLine() /* new line (no vertical motion implied) */{ if (dbg == 3) putchar('\n'); flushbuff(); endcorrect(); hor_pos = 0; virgin_line = 1;}internalSize(number) /* convert integer to internal size number */int number;{ int index; if (number >= pointsizeTab[device.num_sizes - 1]) { /* larger than largest -- use largest */ return(device.num_sizes-1); } else if (number <= pointsizeTab[0]) { /* smaller than smallest -- use smallest */ return(0); } /* else find the size in pointsizeTab and return index */ for (index = 0; number > pointsizeTab[index]; index++); return(index);}/* handle device stop command */resetDevice() { int amt; static int is_reset = 0; char bigbuff[1024]; if (is_reset) return; /* ignore multiple resets */ print_bitmap(); /* this is the absolute last thing that we do */ /* wrap up the preamble and the body */ ip_select(outputfile); AppendOp(OP_endBody); ip_select(pagebodyfile); AppendOp(OP_endBody); AppendOp(OP_endBlock); ip_close(); /* close the body */ /* * Reopen the body and copy it onto the end of the real file (which is * where we have been building the preamble). We don't need to ip_flush * the preamble since that is done everytime we ip_select the body. * Conveniently enough, "tempfilename" still holds the name of the body * temporary. */ pagebodyfile = open(tempfilename, O_RDONLY,0); while ((amt = read(pagebodyfile, bigbuff, sizeof(bigbuff))) != 0) { (void) write(outputfile, bigbuff, amt); } /* close and unlink the body temporary file */ (void) close(pagebodyfile); (void) unlink(tempfilename); /* send the file off to the printer */ tempfilename[strlen(tempfilename) - 1] = '\0'; if (outputfile != 1) { IPprint(tempfilename); } /* we are now reset */ is_reset = 1;}outputString(character) /* print a "funny" character */char *character;{ int i; if (!outputflag) return; if (dbg > 2) printf("\\(%s", character); if (dbg > 3) putchar(' '); for (i = 0; i < device.spec_char_num; i++) if (strcmp(&specCharStrTab[specCharTab[i]], character) == 0) break; if (i < device.spec_char_num) { /* printf(" i = %d so i+128 = %d\n", i, i+128); */ outputChar((unsigned int) i + 128); } else { if (dbg > 3) printf("-- character not found"); } if (dbg > 2) putchar('\n');}outputChar(character) /* put a character */unsigned int character;{ unsigned char *widp; /* pointer to appropriate width table */ register char *codep; /* pointer to appropriate table of codes */ register int i, old_font, fnt_index; int j, value; if (!outputflag) return; if (character <= 32) { if (dbg) printf("non-existent character 0%o\n", character); charw = charWidthTab[font][0] * pointsizeTab[size-1] / device.width_units; return; } character -= 32; old_font= font; i = fontIndexTab[font][character] & 255; if (i != 0) /* it's on this font */ { codep = charCodeTab[font]; widp = charWidthTab[font]; } else if (specFontPos > 0) /* on special (we hope) */ { /* assertion: i == 0 */ fnt_index= specFontPos; for (j=0; j <= device.num_fonts; j++) { struct font_entry *fb; fnt_index= (fnt_index+1) % (device.num_fonts+1); if ((fb = fontPtr[fnt_index]) != NULL) { if (fb->special_flag && (i = fontIndexTab[fnt_index][character] & 255) != 0) { codep = charCodeTab[fnt_index]; widp = charWidthTab[fnt_index]; setFont(fnt_index); break; } } } /* assertion: if j > device.num_fonts then i == 0 and character was not found */ } value= codep[i] & 255; if (i == 0 || value == 0) { if (dbg) printf("character not found 0%o\n", character+32); return; } /* remember this character's width */ /* This MUST be done before calling showchar */ charw = (widp[i] * pointsizeTab[size-1] + device.width_units/2) / device.width_units; if (dbg == 3) { if (isprint(character+32)) putchar(character+32); } if (dbg > 3) { if (isprint(character+32)) printf("character %c %d\n", character+32, value); else printf("character %03o %d\n", character+32, value); } if (value == 0377) { /* special escape to an extended code */ value = getexcode(i); } if (dbg < 6) showchar(value); if (font != old_font) { setFont(old_font); }}/* * set point size to n */setPointSize(n)int n; /* internal value: index into pointsizeTab */{ size = n; ftsz = ((long)font << 16) | ((long)size);}/* * set the current font to number */setFont(n)int n; /* internal index */{ font = n; ftsz = ((long)font << 16) | ((long)size);}/* * reportError an error reporting hack that uses dummy parameters * as place holders for arguments that may or may not * exist, fprintf will sort out how many should be there *//*VARARGS 2*/reportError(f, s, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) char *s, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8;{ fprintf(stderr, "dipress: "); fprintf(stderr, s, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); fprintf(stderr, "\nerror encountered near line %d\n", linenumber); if (f == QUIT) goodbye();}/* * Graphics drawing primitives. These use the vector drawing capabilities of * interpress to draw straight lines. All other primitive objects (circle, * ellipse, etc.) are built in a bitmap and printed with a pixel vector. */drawline(dh, dv)int dh,dv;{ if(!outputflag) return; AppendInteger((long) curr_strokewidth); AppendInteger((long) I_strokeWidth); AppendOp(OP_iset); Moveto(xloc(hor_pos), yloc(ver_pos)); hor_pos += dh; ver_pos += dv; Lineto(xloc(hor_pos), yloc(ver_pos)); AppendOp(OP_maskstroke);}/* routines used by interpress dependent routines */char showbuff[Showbuff_size + 1];char *showp = showbuff;int showcnt = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -