void putcEX(char x) { #ifdef USE_CONSOLEDDL Dex32PutC(Dex32GetProcessDevice(),x); #else if (x=='\t') //automatically expand backspace characters { int i; for (i=0;i<3;i++) outputchar(' '); } else outputchar(x); #endif };
/* This assumes there is a font active when it starts * * Note: \overline causes it to construct the path for the chars to measure * how much space they take up. This eats printer memory - our printer * has a limit of about 30 characters. */ static char *outputobj(std::ostream &out, char *textptr, char *fontname, double fontsize, int pathonly) { int idx, length, cnt; char *newtextptr; char *endptr; char newfontname[1024]; if (*textptr == '\\') { ++textptr; endptr = textptr; while (isalpha(*endptr)) ++endptr; length = endptr - textptr; /* First, handle special control sequences - they * are picked up by the "if" and "else if" parts. * Anything that isn't handled in this part is handled in the * "else" which assumes anything in the table should be * translated into the Symbol font. Stuff not in the table is * sent "as-is". */ if (length == 5 && strncmp(textptr,"prime",length) == 0) { /* Make the prime large (like TeX) by rescaling * the font & shifting the coords. */ endfont(out,pathonly); out << "0 " << -.46*PRIMESCALE * fontsize << " RM2\n"; startfont(out,SYMBOLFONT,PRIMESCALE*fontsize); out << "\\242"; endfont(out,pathonly); out << "0 " << .46*PRIMESCALE * fontsize << " RM2\n"; startfont(out,fontname,fontsize); return endptr; } else if (length == 5 && strncmp(textptr,"minus",length) == 0) { switchfont(out,fontname,SYMBOLFONT,fontsize,pathonly); out << '-'; switchfont(out,SYMBOLFONT,fontname,fontsize,pathonly); return endptr; } else if (length == 3 && strncmp(textptr,"dag",length) == 0) { switchfont(out,fontname,"Times-Roman",fontsize,pathonly); out << "\\262"; switchfont(out,"Times-Roman",fontname,fontsize,pathonly); return endptr; } else if (length == 4 && strncmp(textptr,"font",length) == 0) { if (*endptr != '{') { std::cerr << ERRSTR << "Expect '{fontname}' after \\font, but found "; std::cerr << '\'' << endptr << "'\n"; exit(1); } ++endptr; cnt = 0; while (*endptr != '}' && *endptr != '\0') { newfontname[cnt] = *endptr; ++endptr; ++cnt; } newfontname[cnt] = '\0'; if (*endptr != '}') { std::cerr << ERRSTR << "Missing '}' in \\font{fontname}\n"; exit(1); } switchfont(out,fontname,newfontname,fontsize,pathonly); endptr = outputobj(out,endptr+1,newfontname,fontsize,pathonly); switchfont(out,newfontname,fontname,fontsize,pathonly); return endptr; } else if (length == 8 && strncmp(textptr,"overline",length) == 0) { /* Do the overline by first constructing path for the text * we are going to overline, then get bounding box and use * to position the line. Then re-create the text (yes, * all text is generated twice - once for sizing, once * for output). * * WARNING: If already have pathonly==true, just don't output * anything - this is done because if we put the overbar in * the path, using "PBX" will pick up info about earlier * parts of the path & will screw things up. The upshot of this * is that if you overline an object which contains an overline, * the contained overline is not included when the position of * the overline is calculated - this is a bug which probably * won't hurt much... */ if (!pathonly) { get_overline_coords(out, endptr, fontname, fontsize , pathonly); out << "NP M2 " ; out << OVERLINE_THICKNESS * fontsize << " SLW\n"; out << "L2 ST\n"; out << "M2\n"; // Now move back & draw the text under the overline startfont(out,fontname,fontsize); return outputobj(out,endptr,fontname,fontsize,pathonly); } return endptr; } else if (length == 9 && strncmp(textptr,"widetilde",length) == 0) { /* The above comments for overline apply here too. */ if (!pathonly) { get_overline_coords(out, endptr, fontname, fontsize , pathonly); out << TILDE_HEIGHT * fontsize << " tilde fill\n"; out << "M2\n"; // Now move back & draw the text under the overline startfont(out,fontname,fontsize); return outputobj(out,endptr,fontname,fontsize,pathonly); } return endptr; } else if (length == 14 && strncmp(textptr,"overrightarrow",length) == 0) { /* The above comments for overline apply here too. */ if (!pathonly) { get_overline_coords(out, endptr, fontname, fontsize , pathonly); // Draw the arrow head out << "2 copy 2 copy 4 -1 roll " << -ARROW_LENGTH*fontsize << " add\n"; out << "4 1 roll " << ARROW_ANGLE << " arrow fill\n"; // Draw the stem of the arrow out << "2 1 roll " << -ARROW_LENGTH*fontsize << " add 2 1 roll\n"; out << "NP M2 " ; out << OVERLINE_THICKNESS * fontsize << " SLW\n"; out << "L2 ST\n"; out << "M2\n"; // Now move back & draw the text under the overline startfont(out,fontname,fontsize); return outputobj(out,endptr,fontname,fontsize,pathonly); } return endptr; } else if (length == 8 && strncmp(textptr,"tildebar",length) == 0) { /* The above comments for overline apply here too. */ if (!pathonly) { get_overline_coords(out, endptr, fontname, fontsize , pathonly); out << "4 copy\n"; // Copy coords for the tilde // Make the overline out << "NP M2 " ; out << OVERLINE_THICKNESS * fontsize << " SLW\n"; out << "L2 ST\n"; // Make the tilde out << OVERLINE_SHIFT * fontsize << " add\n"; out << "3 -1 roll " << OVERLINE_SHIFT * fontsize << " add 3 1 roll\n"; out << TILDE_HEIGHT * fontsize << " tilde fill\n"; out << "M2\n"; // Now move back & draw the text under the overline startfont(out,fontname,fontsize); return outputobj(out,endptr,fontname,fontsize,pathonly); } return endptr; } else { for (idx = sizeof(text2PS_syms) /sizeof(struct text2PS_symbol_translation) - 1 ; idx >= 0 ; --idx) { if (strncmp(textptr,text2PS_syms[idx].insym,length) == 0 && (strlen(text2PS_syms[idx].insym) == length)) break; } if (idx >= 0) // have a match - map to something in Symbol font { endfont(out,pathonly); startfont(out,SYMBOLFONT,fontsize); out << text2PS_syms[idx].outsym; endfont(out,pathonly); startfont(out,fontname,fontsize); return endptr; } else // no match (not in table) - send "as is" { outputchar(out,*textptr); return textptr + 1; } } } else if (*textptr == '{') { ++textptr; while (*textptr != '}' && *textptr != '\0') textptr = outputobj(out,textptr,fontname,fontsize,pathonly); return textptr + 1; } else if (*textptr == '_') { endfont(out,pathonly); out << "CPT\n"; newtextptr = outputsubscript(out,textptr+1,fontname,fontsize,pathonly); if (*newtextptr == '^') { out << "CPT pop\n"; // save x value out << "3 1 roll\n"; // push the x value to the bottom out << "M2\n"; out << "CPT exch pop exch\n"; // save the y value & put before x newtextptr = outputsuperscript(out,newtextptr+1,fontname,fontsize,pathonly); // move to start of normal text - compare x's & fetch y, then move out << "CPT pop max exch M2\n"; // now stack is empty } else // use old y & new x value out << "exch pop CPT pop exch M2\n"; // now stack is empty startfont(out,fontname,fontsize); return newtextptr; } else if (*textptr == '^') { endfont(out,pathonly); out << "CPT\n"; newtextptr = outputsuperscript(out,textptr+1,fontname,fontsize,pathonly); if (*newtextptr == '_') { out << "CPT pop\n"; // save x value out << "3 1 roll\n"; // push the x value to the bottom out << "M2\n"; out << "CPT exch pop exch\n"; // save the y value & put before x newtextptr = outputsubscript(out,newtextptr+1,fontname,fontsize,pathonly); // move to start of normal text - compare x's & fetch y, then move out << "CPT pop max exch M2\n"; // now stack is empty } else // use old y & new x value out << "exch pop CPT pop exch M2\n"; // now stack is empty startfont(out,fontname,fontsize); return newtextptr; } else { outputchar(out,*textptr); return textptr + 1; } }
void compact( void ) { int ch, newline = TRUE; // Read input one character at a time while ((ch = fgetc(fin)) != EOF) { if (ch == ' ' || ch == TAB) { // Treat TAB as space outputchar(' '); newline = FALSE; } else if (ch == CR || ch == LF) { // Treat CR and LF as space outputchar(' '); newline = TRUE; } else if (ch == '%') { int dsc = FALSE; // If the % is the first character of an input line // and either % or ! is the second character, then // assume the line is a DSC comment line and copy // it to output unmodified. // // Otherwise, % start a comment and we'll skip the // rest of the input line. if (newline) { if ((ch = fgetc(fin)) == EOF) break; if (ch == '%' || ch == '!') { flushoutput(FALSE); appendeol(); fputc('%', fout); dsc = TRUE; } } while (ch != EOF && ch != CR && ch != LF) { if (dsc) fputc(ch, fout); ch = fgetc(fin); } if (dsc) appendeol(); newline = TRUE; } else if (ch == '(') { // Open-parenthesis starts a PostScript string. // Copy everything unmodified until the closing // parenthesis is encountered. outputchar(ch); flushoutput(FALSE); while ((ch = fgetc(fin)) != ')') { if (ch == EOF) error("string syntax error"); fputc(ch, fout); if (ch == '\\') { if ((ch = fgetc(fin)) == EOF) error("string syntax error"); fputc(ch, fout); } } fputc(ch, fout); newline = FALSE; } else { outputchar(ch); newline = FALSE; } } flushoutput(TRUE); }