|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 15350 (0x3bf6) Types: TextFile Names: »special.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/dvitps/src/special.c«
/* Copyright 1988 Stephan v. Bechtolsheim */ /* This file is part of the TeXPS Software Package. The TeXPS Software Package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the TeXPS Software Package General Public License for full details. Everyone is granted permission to copy, modify and redistribute the TeXPS Software Package, but only under the conditions described in the TeXPS Software Package General Public License. A copy of this license is supposed to have been given to you along with TeXPS Software Package so you can know your rights and responsibilities. It should be in a file named CopyrightLong. Among other things, the copyright notice and this notice must be preserved on all copies. */ /* * Handle \special commands. * * \special handling is done in both passes, pass 0 and 1. * The structure of the \special string is as follows: * If it's a tpic command then no leading "dvitps:" string is expected. * Otherwise the presence of a leading "dvitps:" is required for the driver * to recognize a \special string. Other \specials are dropped. * * The string "dvitps:" is defined by DVITPS_SPECIAL. */ /* * Compile time switches * ********************* * TPIC: recognize tpic commands; set (or not) through "local-defs." */ #include <stdio.h> #if SYS_V == 1 #include <string.h> #else #include <strings.h> #endif #include "defs.h" #include "units.h" #include "dvitps.h" #include "dvi-com.h" #include "special-tokenlex.h" #include "emit.h" #include "extfil.h" extern void PssSendCommand(); extern void PsSendFile(); extern void PssFlushStringAndPos(); extern void PsDownLoad(); extern int Verbose; extern EX_FILES ExDvi; extern EX_FILES Ex_PsOutput; extern double ConvertPosPoints(); extern int PssColumn; extern int ResetPageNum; extern int Resolution; extern char yytext[]; extern DVIU h, v; extern DVIU hh, vv; extern char * SpecialStringReturn; extern int UsualOrientation; extern int ThisPagesOrientation; extern int IgnoreSpecials; /* Forward declarations. */ int IntFromLex(); double LexDouble; double DoubleFromLex(); int DoSpecialOfPass0(); void DoSpecialOfPass1(); double DimensionFromLex(); #define READ_HEX_STRING_LENGTH 256 int NoEject = FALSE; /* Store the special command here. */ char SpecialBuffer[SPECIAL_LENGTH]; /* This is the index into this buffer from where reading starts. */ int SpecialBufferIndex; int SpecialToken; int UnputCharacter; int LexInt; int LexDebug; #if TPIC == 1 extern HConv, VConv; int hhh, vvv; /* Current device coords in pxls. */ /* Shading colors */ extern void Tpic_set_pen_size(); extern void Tpic_add_path(); extern void Tpic_flush_path_fp(); extern void Tpic_flush_path_ip(); extern void Tpic_flush_dashed(); extern void Tpic_flush_spline(); extern void TpicArcBusiness(); extern void TpicShadeCommandGeneral(); extern void TpicShadeCommandWhite(); extern void TpicShadeCommandBlack(); #endif TPIC /* * DoSpecial * ********* * Handling of a special string (XXX.) in a dvi file. * * command: the XXX? command code in the dvi file. * pass: which pass are we currently executing (0 or 1). * output: TRUE if the current page is output and therefore the * special too, FALSE: the current page should be skipped. * RET: pass0 special: always -1. * pass1 special: return code from DoSpecial. */ int DoSpecial (command, pass, output) int command; int pass; int output; { int le; #ifdef DEBUG LexDebug = TRUE; #else LexDebug = FALSE; #endif /* Load the "special string" buffer with the \special's string. */ le = ReadIntoBuffer(EX_FP(ExDvi), &SpecialBuffer[0], command - DVI_XXX1+1, SPECIAL_LENGTH); /* Return immediately if specials are being ignored. */ if (IgnoreSpecials || !output) { switch (pass) { case 0: return(DOSPECIAL_RETURN_REGULAR); case 1: return(-1); default: Fatal ("DoSpecial(): illegal pass."); } } /* * This is our first attempt to read the \special string. Must * either start with the DVITPS_SPECIAL string or be a "tpic" command; other * specials are ignored. */ if (strncmp(SpecialBuffer, DVITPS_SPECIAL, Strlen(DVITPS_SPECIAL)) == 0) { /* Remove the DVITPS_SPECIAL stuff */ RemoveInLine(SpecialBuffer, Strlen(DVITPS_SPECIAL)); RemoveLeadingWhiteSpace(SpecialBuffer); #ifdef DEBUG fprintf (stderr, "\n%% PS-special (Pass = %d): \"%s\"\n", pass, SpecialBuffer); #endif } else { /* No DVITPS_SPECIAL. If it is not a tpic command, then we will assume that this \special command is not to be interpreted by this driver. */ SpecialBufferIndex = 0; UnputCharacter = -1; SpecialToken = yylex(); switch (SpecialToken) { #if TPIC == 1 case K_pn: case K_pa: case K_fp: case K_ip: case K_da: case K_dt: case K_sh: case K_wh: case K_bk: case K_tx: case K_sp: case K_ar: case K_ia: #ifdef DEBUG fprintf (stderr, "\n%% DoSpecial(tpic token): token: "); PrintToken (stderr, SpecialToken); fprintf (stderr, "\n"); #endif break; #endif TPIC default: fprintf (stderr, "\n\\special string \"%s\" ignored\n", SpecialBuffer); return(DOSPECIAL_RETURN_REGULAR); } } /* * From here on we know that it's either a tpic instruction or an instruction * which started with DVITPS_SPECIAL (already removed). So the instruction must belong * to the `vocabulary' of the driver now. Otherwise the first string, returned * from the special command is a regular string, and not a keyword, causing * an error further down the road. */ /* * The following two instructions initialize the lexical analyser used * to read from the special string. */ SpecialBufferIndex = 0; UnputCharacter = -1; SpecialToken = yylex(); #ifdef DEBUG fprintf (stderr, "\n%% DoSpecial(tpic token): token: "); PrintToken (stderr, SpecialToken); fprintf (stderr, "\n"); #endif #if TPIC == 1 hhh = PixRound(h, HConv); /* An akward way to do this. */ vvv = PixRound(v, VConv); /* Should we use the UnMagnified conversion? */ #endif /* Actions in general differ between the two passes! */ switch (pass) { case 0: return(DoSpecialOfPass0()); case 1: PssFlushStringAndPos(); DoSpecialOfPass1(); return(-1); default: Fatal ("DoSpecial(): illegal pass number"); } return(0); /* To make lint happy. */ } /* * DoSpecialOfPass0 * **************** * Any handling of a special occuring in pass 0 goes here. * * RET: DOSPECIAL_RETURN_... */ int DoSpecialOfPass0() { #ifdef DEBUG fprintf (stderr, "%% DoSpecialOfPass0():"); PrintToken (stderr, SpecialToken); fprintf (stderr, "\n"); #endif switch (SpecialToken) { /* Two orientation commands, which change the orientation of the current page only: landscape_page and portrait_page. */ case K_LandscapePage: ThisPagesOrientation = LANDSCAPE_MODE; if (UsualOrientation == LANDSCAPE_MODE) Fatal ("DoSpecialOfPass0(): LandscapePage: whole document already in landscape mode."); return(DOSPECIAL_RETURN_REGULAR); case K_PortraitPage: ThisPagesOrientation = PORTRAIT_MODE; if (UsualOrientation == PORTRAIT_MODE) Fatal ("DoSpecialOfPass0(): LandscapePage: whole document already in landscape mode."); return(DOSPECIAL_RETURN_REGULAR); /* "Position" silently ignored in pass 0. */ case K_Position: return(DOSPECIAL_RETURN_REGULAR); case K_Gray: PsDownLoad ("gray.pro", 0); return(DOSPECIAL_RETURN_REGULAR); case K_PrintString: RemoveLeadingWhiteSpace(SpecialBuffer); RemoveInLine(SpecialBuffer, Strlen("PrintString")); RemoveLeadingWhiteSpace(SpecialBuffer); fprintf (stderr, "[PrintString]: \"%s\"\n", SpecialBuffer); return(DOSPECIAL_RETURN_REGULAR); case K_Literal: return(DOSPECIAL_RETURN_REGULAR); case K_Include0: /* Get file name of file to be included. */ if (yylex() != T_STRING_QUOTED) Fatal ("DoSpecialOfPass0(): Quoted string expected (Include0)"); if (Verbose > V_QUIET) fprintf (stderr, "[%s: Include0 \"%s\"", DVITPS_SPECIAL, SpecialStringReturn); EMIT_NEW_LINE; PsDownLoad (SpecialStringReturn, 0); if (Verbose > V_QUIET) fprintf (stderr, "]\n"); return(DOSPECIAL_RETURN_REGULAR); case K_Include1: return(DOSPECIAL_RETURN_REGULAR); #if TPIC == 1 case K_pn: case K_pa: case K_fp: case K_ip: case K_da: case K_dt: case K_sh: case K_wh: case K_bk: case K_tx: return(DOSPECIAL_RETURN_REGULAR); case K_sp: PsDownLoad("spline.pro", 0); /* Insert PS spline function */ return(DOSPECIAL_RETURN_REGULAR); case K_ar: PsDownLoad("ellipse.pro", 0);/* Insert PS ellipse function */ return(DOSPECIAL_RETURN_REGULAR); case K_ia: PsDownLoad("ellipse.pro", 0);/* Insert PS ellipse function */ return(DOSPECIAL_RETURN_REGULAR); #endif TPIC default: Fatal3("DoSpecialOfPass0(): illegal command (token %d, special string = \"%s\")", SpecialToken, SpecialBuffer); return (NULL); /* lint */ } } /* * DoSpecialOfPass1 * **************** * Processing of \specials occuring in pass 1 is initiated here. */ void DoSpecialOfPass1() { double dyminus, dyplus, dx; /* See "gray.pro" for definitions. */ char buffer[256]; #ifdef DEBUG fprintf (stderr, "%% DoSpecialOfPass1():"); PrintToken (stderr, SpecialToken); fprintf (stderr, "\n"); #endif switch (SpecialToken) { /* Two orientation commands */ case K_LandscapePage: case K_PortraitPage: break; /* Print current position on stderr. */ case K_Position: fprintf (stderr, "\\special(Position): (%5.2lfpt, %5.2lfpt)\n", ConvertPosPoints(h), ConvertPosPoints(v)); break; case K_Gray: EMIT_NEW_LINE; RemoveLeadingWhiteSpace(SpecialBuffer); RemoveInLine(SpecialBuffer, Strlen("Gray")); RemoveLeadingWhiteSpace(SpecialBuffer); SpecialBufferIndex = 0; dx = DimensionFromLex(); dyplus = DimensionFromLex(); dyminus = DimensionFromLex(); sprintf (buffer, "%d %d %d Gray ", (int)(dx / 72.27 * Resolution + 0.5), (int)(dyplus / 72.27 * Resolution + 0.5), (int)(dyminus / 72.27 * Resolution + 0.5)); PSS_CHECK_FULL_LINE(Strlen(buffer)); PssSendCommand(buffer); break; case K_PrintString: break; case K_Include1: /* Get file name of file to be included. */ if (yylex() != T_STRING_QUOTED) Fatal ("DoSpecialOfPass1(): Quoted string expected (Include1)"); if (Verbose > V_QUIET) fprintf (stderr, "[%s: Include1 \"%s\"", DVITPS_SPECIAL, SpecialStringReturn); EMIT_NEW_LINE; PsSendFile (1, SpecialStringReturn, 0); if (Verbose > V_QUIET) fprintf (stderr, "]\n"); break; case K_Literal: if (yylex() != T_STRING_QUOTED) Fatal ("DoSpecialOfPass1(): Literal: quoted string expected."); if (Verbose > V_SOME) fprintf (stderr, "[%s Literal \"%s\"", DVITPS_SPECIAL, SpecialStringReturn); EMIT_NEW_LINE; fprintf (EX_FP(Ex_PsOutput), SpecialStringReturn); EMIT_NEW_LINE; break; /* Includes for pass0 are ignored. */ case K_Include0: break; #if TPIC == 1 /* tpic stuff now. */ case K_pn: Tpic_set_pen_size(); break; case K_pa: Tpic_add_path(); break; case K_fp: Tpic_flush_path_fp(); break; case K_ip: Tpic_flush_path_ip(); break; case K_da: Tpic_flush_dashed(0); break; case K_dt: Tpic_flush_dashed(1); break; case K_sp: Tpic_flush_spline(); break; case K_ar: TpicArcBusiness(TRUE); break; case K_ia: TpicArcBusiness(FALSE); break; case K_sh: TpicShadeCommandGeneral(); break; case K_wh: TpicShadeCommandWhite(); break; case K_bk: /* my tpic doesn't generate this \special ... */ TpicShadeCommandBlack(); break; case K_tx: Warning("DoSpecialOfPass1(): tpic: textures aren't supported"); break; #endif TPIC /* Should never come here because illegal tokens were already discovered in Pass0 of this page. */ default: Fatal2("DoSpecialOfPass1(): illegal token %d", SpecialToken); } } /* * input * ***** * Function to read in a character, needed by the lexical analyzer * which will read in the keywords and potentially some parameters * of the keyword. * * RET: character code */ int input () { int ret; if (UnputCharacter != -1) { ret = UnputCharacter; UnputCharacter = -1; return (ret); } if (SpecialBuffer[SpecialBufferIndex] == '\0') return (0); else return (SpecialBuffer[SpecialBufferIndex++]); } /* * unput * ***** * Function to unget a character, needed by lex. */ unput (c) char c; { if (UnputCharacter != -1) Fatal ("unput(): unput within unput"); UnputCharacter = c; return; } yywrap() { return (1); } /* * IntFromLex * ********** * Next token must be an integer, of which the value is returned. * Otherwise generate a fatal error. * * RET: integer read in. */ int IntFromLex() { if (yylex() != T_INT) Fatal ("IntFromLex(): integer expected"); return (LexInt); } /* * DoubleFromLex * ************* * Next token must be a floating point number. Return its value. * Otherwise generate a fatal error. * * RET: floating point number read in. */ double DoubleFromLex() { if (yylex() != T_DOUBLE) Fatal ("DoubleFromLex(): double expected"); return (LexDouble); } /* * DoubleOrIntFromLex * ****************** * Next token must be a floating point or an integer number. Return its value. * Always return as floating point number. * * RET: number read in. */ double DoubleOrIntFromLex() { int c; switch (c=yylex()) { case T_DOUBLE: return (LexDouble); case T_INT: return ((double) LexInt); default: fflush(stdout); fflush(stderr); fprintf (stderr, "DoubleOrIntFromLex(): token ="); PrintToken(stderr, c); Fatal("DoubleOrIntFromLex(): token neither double nor int."); } return (0.0); /* To make lint happy. */ } /* * DimensionFromLex * **************** * Next token must be a dimension, i.e. a number followed * by a dimension unit. Return it as points, i.e. the conversion * of dimension units takes place in this procedure. * * RET: floating point number read in. */ double DimensionFromLex() { int tok; double dist; switch (tok = yylex()) { case T_DOUBLE: dist = LexDouble; break; case T_INT: dist = LexInt; break; default: Fatal ("DimensionFromLex(): no integer or floating point number seen."); } if ((tok = yylex()) != T_ID) Fatal ("DimensionFromLex(): no dimension unit seen"); if (Strcmp(yytext, "pt") == 0) return(dist); if (Strcmp(yytext, "in") == 0) return(dist*72.27); Fatal2 ("DimensionFromLex(): illegal dimension unit %s", yytext); return (0); /* To make lint happy. */ }