more files

This commit is contained in:
rsc 2004-05-15 23:55:53 +00:00
parent 173302913e
commit 61f5c35c94
37 changed files with 5947 additions and 1 deletions

View file

@ -0,0 +1,257 @@
/*
*
* Boundingbox code for PostScript translators. The boundingbox for each page
* is accumulated in bbox - the one for the whole document goes in docbbox. A
* call to writebbox() puts out an appropriate comment, updates docbbox, and
* resets bbox for the next page. The assumption made at the end of writebbox()
* is that we're really printing the current page only if output is now going
* to stdout - a valid assumption for all supplied translators. Needs the math
* library.
*
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <fcntl.h>
#include <math.h>
#include "comments.h" /* PostScript file structuring comments */
#include "gen.h" /* a few general purpose definitions */
#include "ext.h" /* external variable declarations */
typedef struct bbox {
int set;
double llx, lly;
double urx, ury;
} Bbox;
Bbox bbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
Bbox docbbox = {FALSE, 0.0, 0.0, 0.0, 0.0};
double ctm[6] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
double matrix1[6], matrix2[6];
/*****************************************************************************/
cover(x, y)
double x, y;
{
/*
*
* Adds point (x, y) to bbox. Coordinates are in user space - the transformation
* to default coordinates happens in writebbox().
*
*/
if ( bbox.set == FALSE ) {
bbox.llx = bbox.urx = x;
bbox.lly = bbox.ury = y;
bbox.set = TRUE;
} else {
if ( x < bbox.llx )
bbox.llx = x;
if ( y < bbox.lly )
bbox.lly = y;
if ( x > bbox.urx )
bbox.urx = x;
if ( y > bbox.ury )
bbox.ury = y;
} /* End else */
} /* End of cover */
/*****************************************************************************/
writebbox(fp, keyword, slop)
FILE *fp; /* the comment is written here */
char *keyword; /* the boundingbox comment string */
int slop; /* expand (or contract?) the box a bit */
{
Bbox ubbox; /* user space bounding box */
double x, y;
/*
*
* Transforms the numbers in the bbox[] using ctm[], adjusts the corners a bit
* (depending on slop) and then writes comment. If *keyword is BoundingBox use
* whatever's been saved in docbbox, otherwise assume the comment is just for
* the current page.
*
*/
if ( strcmp(keyword, BOUNDINGBOX) == 0 )
bbox = docbbox;
if ( bbox.set == TRUE ) {
ubbox = bbox;
bbox.set = FALSE; /* so cover() works properly */
x = ctm[0] * ubbox.llx + ctm[2] * ubbox.lly + ctm[4];
y = ctm[1] * ubbox.llx + ctm[3] * ubbox.lly + ctm[5];
cover(x, y);
x = ctm[0] * ubbox.llx + ctm[2] * ubbox.ury + ctm[4];
y = ctm[1] * ubbox.llx + ctm[3] * ubbox.ury + ctm[5];
cover(x, y);
x = ctm[0] * ubbox.urx + ctm[2] * ubbox.ury + ctm[4];
y = ctm[1] * ubbox.urx + ctm[3] * ubbox.ury + ctm[5];
cover(x, y);
x = ctm[0] * ubbox.urx + ctm[2] * ubbox.lly + ctm[4];
y = ctm[1] * ubbox.urx + ctm[3] * ubbox.lly + ctm[5];
cover(x, y);
bbox.llx -= slop + 0.5;
bbox.lly -= slop + 0.5;
bbox.urx += slop + 0.5;
bbox.ury += slop + 0.5;
fprintf(fp, "%s %d %d %d %d\n", keyword, (int)bbox.llx, (int)bbox.lly,(int)bbox.urx, (int)bbox.ury);
bbox = ubbox;
} /* End if */
resetbbox((fp == stdout) ? TRUE : FALSE);
} /* End of writebbox */
/*****************************************************************************/
resetbbox(output)
int output;
{
/*
*
* Adds bbox to docbbox and resets bbox for the next page. Only update docbbox
* if we really did output on the last page.
*
*/
if ( docbbox.set == TRUE ) {
cover(docbbox.llx, docbbox.lly);
cover(docbbox.urx, docbbox.ury);
} /* End if */
if ( output == TRUE ) {
docbbox = bbox;
docbbox.set = TRUE;
} /* End if */
bbox.set = FALSE;
} /* End of resetbbox */
/*****************************************************************************/
scale(sx, sy)
double sx, sy;
{
/*
*
* Scales the default matrix.
*
*/
matrix1[0] = sx;
matrix1[1] = 0;
matrix1[2] = 0;
matrix1[3] = sy;
matrix1[4] = 0;
matrix1[5] = 0;
concat(matrix1);
} /* End of scale */
/*****************************************************************************/
translate(tx, ty)
double tx, ty;
{
/*
*
* Translates the default matrix.
*
*/
matrix1[0] = 1.0;
matrix1[1] = 0.0;
matrix1[2] = 0.0;
matrix1[3] = 1.0;
matrix1[4] = tx;
matrix1[5] = ty;
concat(matrix1);
} /* End of translate */
/*****************************************************************************/
rotate(angle)
double angle;
{
/*
*
* Rotates by angle degrees.
*
*/
angle *= 3.1416 / 180;
matrix1[0] = matrix1[3] = cos(angle);
matrix1[1] = sin(angle);
matrix1[2] = -matrix1[1];
matrix1[4] = 0.0;
matrix1[5] = 0.0;
concat(matrix1);
} /* End of rotate */
/*****************************************************************************/
concat(m1)
double m1[];
{
double m2[6];
/*
*
* Replaces the ctm[] by the result of the matrix multiplication m1[] x ctm[].
*
*/
m2[0] = ctm[0];
m2[1] = ctm[1];
m2[2] = ctm[2];
m2[3] = ctm[3];
m2[4] = ctm[4];
m2[5] = ctm[5];
ctm[0] = m1[0] * m2[0] + m1[1] * m2[2];
ctm[1] = m1[0] * m2[1] + m1[1] * m2[3];
ctm[2] = m1[2] * m2[0] + m1[3] * m2[2];
ctm[3] = m1[2] * m2[1] + m1[3] * m2[3];
ctm[4] = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
ctm[5] = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
} /* End of concat */
/*****************************************************************************/

View file

@ -0,0 +1,127 @@
/*
*
* Currently defined file structuring comments from Adobe - plus a few others.
* Ones that end with a colon expect arguments, while those ending with a newline
* stand on their own. Truly overkill on Adobe's part and mine for including them
* all!
*
* All PostScript files should begin with a header that starts with one of the
* following comments.
*
*/
#define NONCONFORMING "%!PS\n"
#define MINCONFORMING "%!PS-Adobe-\n"
#define OLDCONFORMING "%!PS-Adobe-1.0\n"
#define CONFORMING "%!PS-Adobe-2.0\n"
#define CONFORMINGEPS "%!PS-Adobe-2.0 EPS\n"
#define CONFORMINGQUERY "%!PS-Adobe-2.0 Query\n"
#define CONFORMINGEXITSERVER "%!PS-Adobe-2.0 ExitServer\n"
/*
*
* Header comments - immediately follow the appropriate document classification
* comment.
*
*/
#define TITLE "%%Title:"
#define CREATOR "%%Creator:"
#define CREATIONDATE "%%CreationDate:"
#define FOR "%%For:"
#define ROUTING "%%Routing:"
#define BOUNDINGBOX "%%BoundingBox:"
#define PAGES "%%Pages:"
#define REQUIREMENTS "%%Requirements:"
#define DOCUMENTFONTS "%%DocumentFonts:"
#define DOCUMENTNEEDEDFONTS "%%DocumentNeededFonts:"
#define DOCUMENTSUPPLIEDFONTS "%%DocumentSuppliedFonts:"
#define DOCUMENTNEEDEDPROCSETS "%%DocumentNeededProcSets:"
#define DOCUMENTSUPPLIEDPROCSETS "%%DocumentSuppliedProcSets:"
#define DOCUMENTNEEDEDFILES "%%DocumentNeededFiles:"
#define DOCUMENTSUPPLIEDFILES "%%DocumentSuppliedFiles:"
#define DOCUMENTPAPERSIZES "%%DocumentPaperSizes:"
#define DOCUMENTPAPERFORMS "%%DocumentPaperForms:"
#define DOCUMENTPAPERCOLORS "%%DocumentPaperColors:"
#define DOCUMENTPAPERWEIGHTS "%%DocumentPaperWeights:"
#define DOCUMENTPRINTERREQUIRED "%%DocumentPrinterREquired:"
#define ENDCOMMENTS "%%EndComments\n"
#define ENDPROLOG "%%EndProlog\n"
/*
*
* Body comments - can appear anywhere in a document.
*
*/
#define BEGINSETUP "%%BeginSetup\n"
#define ENDSETUP "%%EndSetup\n"
#define BEGINDOCUMENT "%%BeginDocument:"
#define ENDDOCUMENT "%%EndDocument\n"
#define BEGINFILE "%%BeginFile:"
#define ENDFILE "%%EndFile\n"
#define BEGINPROCSET "%%BeginProcSet:"
#define ENDPROCSET "%%EndProcSet\n"
#define BEGINBINARY "%%BeginBinary:"
#define ENDBINARY "%%EndBinary\n"
#define BEGINPAPERSIZE "%%BeginePaperSize:"
#define ENDPAPERSIZE "%%EndPaperSize\n"
#define BEGINFEATURE "%%BeginFeature:"
#define ENDFEATURE "%%EndFeature\n"
#define BEGINEXITSERVER "%%BeginExitServer:"
#define ENDEXITSERVER "%%EndExitServer\n"
#define TRAILER "%%Trailer\n"
/*
*
* Page level comments - usually will occur once per page.
*
*/
#define PAGE "%%Page:"
#define PAGEFONTS "%%PageFonts:"
#define PAGEFILES "%%PageFiles:"
#define PAGEBOUNDINGBOX "%%PageBoundingBox:"
#define BEGINPAGESETUP "%%BeginPageSetup\n"
#define BEGINOBJECT "%%BeginObject:"
#define ENDOBJECT "%%EndObject\n"
/*
*
* Resource requirements - again can appear anywhere in a document.
*
*/
#define INCLUDEFONT "%%IncludeFont:"
#define INCLUDEPROCSET "%%IncludeProcSet:"
#define INCLUDEFILE "%%IncludeFile:"
#define EXECUTEFILE "%%ExecuteFile:"
#define CHANGEFONT "%%ChangeFont:"
#define PAPERFORM "%%PaparForm:"
#define PAPERCOLOR "%%PaperColor:"
#define PAPERWEIGHT "%%PaperWeight:"
#define PAPERSIZE "%%PaperSize:"
#define FEATURE "%%Feature:"
#define ENDOFFILE "%%EOF\n"
#define CONTINUECOMMENT "%%+"
#define ATEND "(atend)"
/*
*
* Some non-standard document comments. Global definitions are occasionally used
* in dpost and are marked by BEGINGLOBAL and ENDGLOBAL. The resulting document
* violates page independence, but can easily be converted to a conforming file
* using a utililty program.
*
*/
#define BEGINSCRIPT "%%BeginScript\n"
#define BEGINGLOBAL "%%BeginGlobal\n"
#define ENDGLOBAL "%%EndGlobal\n"
#define ENDPAGE "%%EndPage:"
#define FORMSPERPAGE "%%FormsPerPage:"
#define VERSION "%%Version:"

View file

@ -0,0 +1,264 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include "common.h"
#include "comments.h"
#include "path.h"
struct strtab charcode[FONTSIZE] = {
{4, "\\000"}, {4, "\\001"}, {4, "\\002"}, {4, "\\003"},
{4, "\\004"}, {4, "\\005"}, {4, "\\006"}, {4, "\\007"},
{4, "\\010"}, {4, "\\011"}, {4, "\\012"}, {4, "\\013"},
{4, "\\014"}, {4, "\\015"}, {4, "\\016"}, {4, "\\017"},
{4, "\\020"}, {4, "\\021"}, {4, "\\022"}, {4, "\\023"},
{4, "\\024"}, {4, "\\025"}, {4, "\\026"}, {4, "\\027"},
{4, "\\030"}, {4, "\\031"}, {4, "\\032"}, {4, "\\033"},
{4, "\\034"}, {4, "\\035"}, {4, "\\036"}, {4, "\\037"},
{1, " "}, {1, "!"}, {1, "\""}, {1, "#"},
{1, "$"}, {1, "%"}, {1, "&"}, {1, "'"},
{2, "\\("}, {2, "\\)"}, {1, "*"}, {1, "+"},
{1, ","}, {1, "-"}, {1, "."}, {1, "/"},
{1, "0"}, {1, "1"}, {1, "2"}, {1, "3"},
{1, "4"}, {1, "5"}, {1, "6"}, {1, "7"},
{1, "8"}, {1, "9"}, {1, ":"}, {1, ";"},
{1, "<"}, {1, "="}, {1, ">"}, {1, "?"},
{1, "@"}, {1, "A"}, {1, "B"}, {1, "C"},
{1, "D"}, {1, "E"}, {1, "F"}, {1, "G"},
{1, "H"}, {1, "I"}, {1, "J"}, {1, "K"},
{1, "L"}, {1, "M"}, {1, "N"}, {1, "O"},
{1, "P"}, {1, "Q"}, {1, "R"}, {1, "S"},
{1, "T"}, {1, "U"}, {1, "V"}, {1, "W"},
{1, "X"}, {1, "Y"}, {1, "Z"}, {1, "["},
{2, "\\\\"}, {1, "]"}, {1, "^"}, {1, "_"},
{1, "`"}, {1, "a"}, {1, "b"}, {1, "c"},
{1, "d"}, {1, "e"}, {1, "f"}, {1, "g"},
{1, "h"}, {1, "i"}, {1, "j"}, {1, "k"},
{1, "l"}, {1, "m"}, {1, "n"}, {1, "o"},
{1, "p"}, {1, "q"}, {1, "r"}, {1, "s"},
{1, "t"}, {1, "u"}, {1, "v"}, {1, "w"},
{1, "x"}, {1, "y"}, {1, "z"}, {1, "{"},
{1, "|"}, {1, "}"}, {1, "~"}, {4, "\\177"},
{4, "\\200"}, {4, "\\201"}, {4, "\\202"}, {4, "\\203"},
{4, "\\204"}, {4, "\\205"}, {4, "\\206"}, {4, "\\207"},
{4, "\\210"}, {4, "\\211"}, {4, "\\212"}, {4, "\\213"},
{4, "\\214"}, {4, "\\215"}, {4, "\\216"}, {4, "\\217"},
{4, "\\220"}, {4, "\\221"}, {4, "\\222"}, {4, "\\223"},
{4, "\\224"}, {4, "\\225"}, {4, "\\226"}, {4, "\\227"},
{4, "\\230"}, {4, "\\231"}, {4, "\\232"}, {4, "\\233"},
{4, "\\234"}, {4, "\\235"}, {4, "\\236"}, {4, "\\237"},
{4, "\\240"}, {4, "\\241"}, {4, "\\242"}, {4, "\\243"},
{4, "\\244"}, {4, "\\245"}, {4, "\\246"}, {4, "\\247"},
{4, "\\250"}, {4, "\\251"}, {4, "\\252"}, {4, "\\253"},
{4, "\\254"}, {4, "\\255"}, {4, "\\256"}, {4, "\\257"},
{4, "\\260"}, {4, "\\261"}, {4, "\\262"}, {4, "\\263"},
{4, "\\264"}, {4, "\\265"}, {4, "\\266"}, {4, "\\267"},
{4, "\\270"}, {4, "\\271"}, {4, "\\272"}, {4, "\\273"},
{4, "\\274"}, {4, "\\275"}, {4, "\\276"}, {4, "\\277"},
{4, "\\300"}, {4, "\\301"}, {4, "\\302"}, {4, "\\303"},
{4, "\\304"}, {4, "\\305"}, {4, "\\306"}, {4, "\\307"},
{4, "\\310"}, {4, "\\311"}, {4, "\\312"}, {4, "\\313"},
{4, "\\314"}, {4, "\\315"}, {4, "\\316"}, {4, "\\317"},
{4, "\\320"}, {4, "\\321"}, {4, "\\322"}, {4, "\\323"},
{4, "\\324"}, {4, "\\325"}, {4, "\\326"}, {4, "\\327"},
{4, "\\330"}, {4, "\\331"}, {4, "\\332"}, {4, "\\333"},
{4, "\\334"}, {4, "\\335"}, {4, "\\336"}, {4, "\\337"},
{4, "\\340"}, {4, "\\341"}, {4, "\\342"}, {4, "\\343"},
{4, "\\344"}, {4, "\\345"}, {4, "\\346"}, {4, "\\347"},
{4, "\\350"}, {4, "\\351"}, {4, "\\352"}, {4, "\\353"},
{4, "\\354"}, {4, "\\355"}, {4, "\\356"}, {4, "\\357"},
{4, "\\360"}, {4, "\\361"}, {4, "\\362"}, {4, "\\363"},
{4, "\\364"}, {4, "\\365"}, {4, "\\366"}, {4, "\\367"},
{4, "\\370"}, {4, "\\371"}, {4, "\\372"}, {4, "\\373"},
{4, "\\374"}, {4, "\\375"}, {4, "\\376"}, {4, "\\377"}
};
static BOOLEAN in_string = FALSE;
int char_no = 0;
int line_no = 0;
int page_no = 0; /* page number in a document */
int pages_printed = 0;
static int pplistmaxsize=0;
static unsigned char *pplist=0; /* bitmap list for storing pages to print */
void
pagelist(char *list) {
char c;
int n, m;
int state, start;
if (list == 0) return;
state = 1;
start = 0;
while ((c=*list) != '\0') {
n = 0;
while (isdigit(c)) {
n = n * 10 + c - '0';
c = *++list;
}
switch (state) {
case 1:
start = n;
case 2:
if (n/8+1 > pplistmaxsize) {
pplistmaxsize = n/8+1;
pplist = galloc(pplist, n/8+1, "page list");
}
for (m=start; m<=n; m++)
pplist[m/8] |= 1<<(m%8);
break;
}
switch (c) {
case '-':
state = 2;
list++;
break;
case ',':
state = 1;
list++;
break;
case '\0':
break;
}
}
}
BOOLEAN
pageon(void) {
extern BOOLEAN debug;
static BOOLEAN privdebug = FALSE;
if (pplist == 0 && page_no != 0) {
if (privdebug && !debug) {
privdebug = FALSE;
debug = TRUE;
}
return(TRUE); /* no page list, print all pages */
}
if (page_no/8 < pplistmaxsize && (pplist[page_no/8] & 1<<(page_no%8))) {
if (privdebug && !debug) {
privdebug = FALSE;
debug = TRUE;
}
return(TRUE);
} else {
if (!privdebug && debug) {
privdebug = TRUE;
debug = FALSE;
}
return(FALSE);
}
}
static int stringhpos, stringvpos;
void
startstring(void) {
if (!in_string) {
stringhpos = hpos;
stringvpos = vpos;
if (pageon()) Bprint(Bstdout, "(");
in_string = 1;
}
}
void
endstring(void) {
if (in_string) {
if (pageon()) Bprint(Bstdout, ") %d %d w\n", stringhpos, stringvpos);
in_string = 0;
}
}
BOOLEAN
isinstring(void) {
return(in_string);
}
void
startpage(void) {
++char_no;
++line_no;
++page_no;
if (pageon()) {
++pages_printed;
Bprint(Bstdout, "%s %d %d\n", PAGE, page_no, pages_printed);
Bprint(Bstdout, "/saveobj save def\n");
Bprint(Bstdout, "mark\n");
Bprint(Bstdout, "%d pagesetup\n", pages_printed);
}
}
void
endpage(void) {
endstring();
curpostfontid = -1;
line_no = 0;
char_no = 0;
if (pageon()) {
Bprint(Bstdout, "cleartomark\n");
Bprint(Bstdout, "showpage\n");
Bprint(Bstdout, "saveobj restore\n");
Bprint(Bstdout, "%s %d %d\n", ENDPAGE, page_no, pages_printed);
}
}
/* This was taken from postprint */
int
cat(char *filename) {
Biobuf *bfile;
Biobuf *Bfile;
int n;
static char buf[Bsize];
if ((bfile = Bopen(unsharp(filename), OREAD)) == 0) {
return(1);
}
Bfile = bfile;
while ((n=Bread(Bfile, buf, Bsize)) > 0) {
if (Bwrite(Bstdout, buf, n) != n)
break;
}
Bterm(Bfile);
if (n != 0) {
return(1);
}
return(0);
}
extern int debug;
void *
galloc(void *ptr, int size, char *perstr) {
void *x;
if ((x=realloc(ptr, size)) == 0) {
perror(perstr);
exits("malloc");
}
return(x);
}
static char *errorstrings[] = {
{""}, /* NONE */
{"WARNING"},
{"FATAL"}
};
char *programname;
char *inputfilename = "<stdin>";
int inputlineno;
void
error(int errtype, char *fmt, ...) {
va_list arg;
Bflush(Bstdout);
Bflush(Bstderr);
fprint(2, "%s: %s:%d :%s: ", programname, inputfilename, inputlineno, errorstrings[errtype]);
va_start(arg, fmt);
vfprint(2, fmt, arg);
va_end(arg);
if (errtype == FATAL)
exits("fatal error");
}

View file

@ -0,0 +1,43 @@
#define NONE 0
#define WARNING 1
#define FATAL 2
#define RUNEGETGROUP(a) ((a>>8)&0xff)
#define RUNEGETCHAR(a) (a&0xff)
typedef int BOOLEAN;
#define TRUE 1
#define FALSE 0
#define NUMOFONTS 0x100
#define FONTSIZE 0x100
extern char *programname;
extern char *inputfilename;
extern int inputlineno;
extern int page_no;
extern int pages_printed;
extern int curpostfontid;
extern int hpos, vpos;
extern Biobuf *Bstdout, *Bstderr;
struct strtab {
int size;
char *str;
int used;
};
extern struct strtab charcode[];
BOOLEAN pageon(void);
void startstring(void);
void endstring(void);
BOOLEAN isinstring(void);
void startpage(void);
void endpage(void);
int cat(char *);
int Bgetfield(Biobuf *, int, void *, int);
void *galloc(void *, int, char *);
void pagelist(char *);

View file

@ -0,0 +1,40 @@
/*
*
* External varibles - most are in glob.c.
*
*/
extern char **argv; /* global so everyone can use them */
extern int argc;
extern int x_stat; /* program exit status */
extern int debug; /* debug flag */
extern int ignore; /* what we do with FATAL errors */
extern long lineno; /* line number */
extern long position; /* byte position */
extern char *prog_name; /* and program name - for errors */
extern char *temp_file; /* temporary file - for some programs */
extern char *fontencoding; /* text font encoding scheme */
extern int dobbox; /* enable BoundingBox stuff if TRUE */
extern double pageheight; /* only for BoundingBox calculations! */
extern double pagewidth;
extern int reading; /* input */
extern int writing; /* and output encoding */
extern char *optarg; /* for getopt() */
extern int optind;
extern void interrupt();
//extern char *tempnam(char*,char*);
/*
* extern char *malloc();
* extern char *calloc();
* extern char *strtok();
* extern long ftell();
* extern double atof();
* extern double sqrt();
* extern double atan2();
*/

View file

@ -0,0 +1,65 @@
/*
*
* A few definitions that shouldn't have to change. Used by most programs in
* this package.
*
*/
#define PROGRAMVERSION "3.3.2"
#define NON_FATAL 0
#define FATAL 1
#define USER_FATAL 2
#define OFF 0
#define ON 1
#define FALSE 0
#define TRUE 1
#define BYTE 8
#define BMASK 0377
#define POINTS 72.3
#ifndef PI
#define PI 3.141592654
#endif
#define ONEBYTE 0
#define UTFENCODING 1
#define READING ONEBYTE
#define WRITING ONEBYTE
/*
*
* DOROUND controls whether some translators include file ROUNDPAGE (path.h)
* after the prologue. Used to round page dimensions obtained from the clippath
* to know paper sizes. Enabled by setting DOROUND to TRUE (or 1).
*
*/
#define DOROUND TRUE
/*
*
* Default resolution and the height and width of a page (in case we need to get
* to upper left corner) - only used in BoundingBox calculations!!
*
*/
#define DEFAULT_RES 72
#define PAGEHEIGHT 11.0 * DEFAULT_RES
#define PAGEWIDTH 8.5 * DEFAULT_RES
/*
*
* Simple macros.
*
*/
#define ABS(A) ((A) >= 0 ? (A) : -(A))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define MAX(A, B) ((A) > (B) ? (A) : (B))

View file

@ -0,0 +1,56 @@
#ifndef _POSIX_SOURCE
#include <u.h>
#include <libc.h>
#endif
#include <stdio.h>
#define ERR(str, chr) if(opterr){fprintf(stderr, "%s%s%c\n", argv[0], str, chr);}
int opterr = 1;
int optind = 1;
int optopt;
char *optarg;
char *strchr();
int
getopt (argc, argv, opts)
char **argv, *opts;
{
static int sp = 1;
register c;
register char *cp;
if (sp == 1)
if (optind >= argc ||
argv[optind][0] != '-' || argv[optind][1] == '\0')
return EOF;
else if (strcmp(argv[optind], "--") == NULL) {
optind++;
return EOF;
}
optopt = c = argv[optind][sp];
if (c == ':' || (cp=strchr(opts, c)) == NULL) {
ERR (": illegal option -- ", c);
if (argv[optind][++sp] == '\0') {
optind++;
sp = 1;
}
return '?';
}
if (*++cp == ':') {
if (argv[optind][sp+1] != '\0')
optarg = &argv[optind++][sp+1];
else if (++optind >= argc) {
ERR (": option requires an argument -- ", c);
sp = 1;
return '?';
} else
optarg = argv[optind++];
sp = 1;
} else {
if (argv[optind][++sp] == '\0') {
sp = 1;
optind++;
}
optarg = NULL;
}
return c;
}

View file

@ -0,0 +1,29 @@
/*
*
* Global varibles - for PostScript translators.
*
*/
#include <stdio.h>
#include "gen.h"
char **argv; /* global so everyone can use them */
int argc;
int x_stat = 0; /* program exit status */
int debug = OFF; /* debug flag */
int ignore = OFF; /* what we do with FATAL errors */
long lineno = 0; /* line number */
long position = 0; /* byte position */
char *prog_name = ""; /* and program name - for errors */
char *temp_file = NULL; /* temporary file - for some programs */
char *fontencoding = NULL; /* text font encoding scheme */
int dobbox = FALSE; /* enable BoundingBox stuff if TRUE */
double pageheight = PAGEHEIGHT; /* only for BoundingBox calculations! */
double pagewidth = PAGEWIDTH;
int reading = UTFENCODING; /* input */
int writing = WRITING; /* and output encoding */

View file

@ -0,0 +1,230 @@
/*
*
* General purpose routines.
*
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <fcntl.h>
#include "gen.h"
#include "ext.h"
#include "path.h"
int nolist = 0; /* number of specified ranges */
int olist[50]; /* processing range pairs */
/*****************************************************************************/
out_list(str)
char *str;
{
int start, stop;
/*
*
* Grab page ranges from str, save them in olist[], and update the nolist
* count. Range syntax matches nroff/troff syntax.
*
*/
while ( *str && nolist < sizeof(olist) - 2 ) {
start = stop = str_convert(&str, 0);
if ( *str == '-' && *str++ )
stop = str_convert(&str, 9999);
if ( start > stop )
error(FATAL, "illegal range %d-%d", start, stop);
olist[nolist++] = start;
olist[nolist++] = stop;
if ( *str != '\0' ) str++;
} /* End while */
olist[nolist] = 0;
} /* End of out_list */
/*****************************************************************************/
in_olist(num)
int num;
{
int i;
/*
*
* Return ON if num is in the current page range list. Print everything if
* there's no list.
*
*/
if ( nolist == 0 )
return(ON);
for ( i = 0; i < nolist; i += 2 )
if ( num >= olist[i] && num <= olist[i+1] )
return(ON);
return(OFF);
} /* End of in_olist */
/*****************************************************************************/
setencoding(name)
char *name;
{
char path[150];
/*
*
* Include the font encoding file selected by name. It's a full pathname if
* it begins with /, otherwise append suffix ".enc" and look for the file in
* ENCODINGDIR. Missing files are silently ignored.
*
*/
if ( name == NULL )
name = "Default";
if ( *name == '/' )
strcpy(path, name);
else sprintf(path, "%s/%s.enc", ENCODINGDIR, name);
if ( cat(path) == TRUE )
writing = strncmp(name, "UTF", 3) == 0;
} /* End of setencoding */
/*****************************************************************************/
cat(file)
char *file;
{
int fd_in;
int fd_out;
char buf[512];
int count;
/*
*
* Copy *file to stdout. Return FALSE is there was a problem.
*
*/
fflush(stdout);
if ( (fd_in = open(file, O_RDONLY)) == -1 )
return(FALSE);
fd_out = fileno(stdout);
while ( (count = read(fd_in, buf, sizeof(buf))) > 0 )
write(fd_out, buf, count);
close(fd_in);
return(TRUE);
} /* End of cat */
/*****************************************************************************/
str_convert(str, err)
char **str;
int err;
{
int i;
/*
*
* Grab the next integer from **str and return its value or err if *str
* isn't an integer. *str is modified after each digit is read.
*
*/
if ( ! isdigit(**str) )
return(err);
for ( i = 0; isdigit(**str); *str += 1 )
i = 10 * i + **str - '0';
return(i);
} /* End of str_convert */
/*****************************************************************************/
error(kind, mesg, a1, a2, a3)
int kind;
char *mesg;
unsigned a1, a2, a3;
{
/*
*
* Print an error message and quit if kind is FATAL.
*
*/
if ( mesg != NULL && *mesg != '\0' ) {
fprintf(stderr, "%s: ", prog_name);
fprintf(stderr, mesg, a1, a2, a3);
if ( lineno > 0 )
fprintf(stderr, " (line %d)", lineno);
if ( position > 0 )
fprintf(stderr, " (near byte %d)", position);
putc('\n', stderr);
} /* End if */
if ( kind == FATAL && ignore == OFF ) {
if ( temp_file != NULL )
unlink(temp_file);
exit(x_stat | 01);
} /* End if */
} /* End of error */
/*****************************************************************************/
void interrupt(sig)
int sig;
{
/*
*
* Signal handler for translators.
*
*/
if ( temp_file != NULL )
unlink(temp_file);
exit(1);
} /* End of interrupt */
/*****************************************************************************/

View file

@ -0,0 +1,23 @@
<$PLAN9/src/mkhdr
<../config
LIB=com.a
OFILES=bbox.$O\
glob.$O\
misc.$O\
request.$O\
rune.$O\
tempnam.$O\
getopt.$O\
HFILES=comments.h\
gen.h\
ext.h\
request.h\
path.h\
rune.h\
<$PLAN9/src/mklib
CFLAGS=-c -D$SYSTEM -D_POSIX_SOURCE

View file

@ -0,0 +1,32 @@
/*
*
* pathname definitions for important files and directories.
*
*/
#define DPOST "#9/sys/lib/postscript/prologues/dpost.ps"
#define POSTBGI "#9/sys/lib/postscript/prologues/postbgi.ps"
#define POSTDAISY "#9/sys/lib/postscript/prologues/postdaisy.ps"
#define POSTDMD "#9/sys/lib/postscript/prologues/postdmd.ps"
#define POSTMD "#9/sys/lib/postscript/prologues/postmd.ps"
#define POSTPLOT "#9/sys/lib/postscript/prologues/postplot.ps"
#define POSTPRINT "#9/sys/lib/postscript/prologues/postprint.ps"
#define POSTNPRINT "#9/sys/lib/postscript/prologues/postnprint.ps"
#define POSTTEK "#9/sys/lib/postscript/prologues/posttek.ps"
#define POSTGIF "#9/sys/lib/postscript/prologues/postgif.ps"
#define BASELINE "#9/sys/lib/postscript/prologues/baseline.ps"
#define COLOR "#9/sys/lib/postscript/prologues/color.ps"
#define DRAW "#9/sys/lib/postscript/prologues/draw.ps"
#define FORMFILE "#9/sys/lib/postscript/prologues/forms.ps"
#define SHADEFILE "#9/sys/lib/postscript/prologues/shade.ps"
#define KERNING "#9/sys/lib/postscript/prologues/kerning.ps"
#define REQUESTFILE "#9/sys/lib/postscript/prologues/ps.requests"
#define ROUNDPAGE "#9/sys/lib/postscript/prologues/roundpage.ps"
#define ENCODINGDIR "#9/sys/lib/postscript/prologues"
#define HOSTDIR "#9/sys/lib/postscript/font"
#define FONTDIR "#9/sys/lib/troff/font"
#define POSTLIBDIR "#9/sys/lib/postscript/prologues"
#define TEMPDIR "/tmp"

View file

@ -0,0 +1,119 @@
/*
*
* Things used to handle special requests (eg. manual feed) globally or on a per
* page basis. Requests are passed through to the translator using the -R option.
* The argument to -R can be "request", "request:page", or "request:page:file".
* If page is omitted (as in the first form) or set to 0 request will be applied
* to the global environment. In all other cases it applies only to the selected
* page. If a file is given, page must be supplied, and the lookup is in that file
* rather than *requestfile.
*
*/
#include <stdio.h>
#include "gen.h" /* general purpose definitions */
#include "request.h" /* a few special definitions */
#include "path.h" /* for the default request file */
Request request[MAXREQUEST]; /* next page or global request */
int nextreq = 0; /* goes in request[nextreq] */
char *requestfile = REQUESTFILE; /* default lookup file */
/*****************************************************************************/
saverequest(want)
char *want; /* grab code for this stuff */
{
char *page; /* and save it for this page */
char *strtok();
/*
*
* Save the request until we get to appropriate page - don't even bother with
* the lookup right now. Format of *want string is "request", "request:page", or
* "request:page:file", and we assume we can change the string here as needed.
* If page is omitted or given as 0 the request will be done globally. If *want
* includes a file, request and page must also be given, and in that case *file
* will be used for the lookup.
*
*/
if ( nextreq < MAXREQUEST ) {
request[nextreq].want = strtok(want, ": ");
if ( (page = strtok(NULL, ": ")) == NULL )
request[nextreq].page = 0;
else request[nextreq].page = atoi(page);
if ( (request[nextreq].file = strtok(NULL, ": ")) == NULL )
request[nextreq].file = requestfile;
nextreq++;
} else error(NON_FATAL, "too many requests - ignoring %s", want);
} /* End of saverequest */
/*****************************************************************************/
writerequest(page, fp_out)
int page; /* write everything for this page */
FILE *fp_out; /* to this file */
{
int i; /* loop index */
/*
*
* Writes out all the requests that have been saved for page. Page 0 refers to
* the global environment and is done during initial setup.
*
*/
for ( i = 0; i < nextreq; i++ )
if ( request[i].page == page )
dumprequest(request[i].want, request[i].file, fp_out);
} /* End of writerequest */
/*****************************************************************************/
dumprequest(want, file, fp_out)
char *want; /* look for this string */
char *file; /* in this file */
FILE *fp_out; /* and write the value out here */
{
char buf[100]; /* line buffer for reading *file */
FILE *fp_in;
/*
*
* Looks for *want in the request file and if it's found the associated value
* is copied to the output file. Keywords (ie. the *want strings) begin an @ in
* the first column of file, while the values (ie. the stuff that's copied to
* the output file) starts on the next line and extends to the next keyword or
* to the end of file.
*
*/
if ( (fp_in = fopen(file, "r")) != NULL ) {
while ( fgets(buf, sizeof(buf), fp_in) != NULL )
if ( buf[0] == '@' && strncmp(want, &buf[1], strlen(want)) == 0 )
while ( fgets(buf, sizeof(buf), fp_in) != NULL )
if ( buf[0] == '#' || buf[0] == '%' )
continue;
else if ( buf[0] != '@' )
fprintf(fp_out, "%s", buf);
else break;
fclose(fp_in);
} /* End if */
} /* End of dumprequest */
/*****************************************************************************/

View file

@ -0,0 +1,22 @@
/*
*
* Things used to handle special PostScript requests (like manual feed) globally
* or on a per page basis. All the translators I've supplied accept the -R option
* that can be used to insert special PostScript code before the global setup is
* done, or at the start of named pages. The argument to the -R option is a string
* that can be "request", "request:page", or "request:page:file". If page isn't
* given (as in the first form) or if it's 0 in the last two, the request applies
* to the global environment, otherwise request holds only for the named page.
* If a file name is given a page number must be supplied, and in that case the
* request will be looked up in that file.
*
*/
#define MAXREQUEST 30
typedef struct {
char *want;
int page;
char *file;
} Request;

View file

@ -0,0 +1,142 @@
#include "rune.h"
enum
{
Bit1 = 7,
Bitx = 6,
Bit2 = 5,
Bit3 = 4,
Bit4 = 3,
T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
Maskx = (1<<Bitx)-1, /* 0011 1111 */
Testx = Maskx ^ 0xFF, /* 1100 0000 */
Bad = Runeerror,
};
int
chartorune(Rune *rune, char *str)
{
int c, c1, c2;
long l;
/*
* one character sequence
* 00000-0007F => T1
*/
c = *(unsigned char*)str;
if(c < Tx) {
*rune = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
c1 = *(unsigned char*)(str+1) ^ Tx;
if(c1 & Testx)
goto bad;
if(c < T3) {
if(c < T2)
goto bad;
l = ((c << Bitx) | c1) & Rune2;
if(l <= Rune1)
goto bad;
*rune = l;
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
c2 = *(unsigned char*)(str+2) ^ Tx;
if(c2 & Testx)
goto bad;
if(c < T4) {
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
if(l <= Rune2)
goto bad;
*rune = l;
return 3;
}
/*
* bad decoding
*/
bad:
*rune = Bad;
return 1;
}
int
runetochar(char *str, Rune *rune)
{
long c;
/*
* one character sequence
* 00000-0007F => 00-7F
*/
c = *rune;
if(c <= Rune1) {
str[0] = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
if(c <= Rune2) {
str[0] = T2 | (c >> 1*Bitx);
str[1] = Tx | (c & Maskx);
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
str[0] = T3 | (c >> 2*Bitx);
str[1] = Tx | ((c >> 1*Bitx) & Maskx);
str[2] = Tx | (c & Maskx);
return 3;
}
int
runelen(long c)
{
Rune rune;
char str[10];
rune = c;
return runetochar(str, &rune);
}
int
fullrune(char *str, int n)
{
int c;
if(n > 0) {
c = *(unsigned char*)str;
if(c < Tx)
return 1;
if(n > 1)
if(c < T3 || n > 2)
return 1;
}
return 0;
}

View file

@ -0,0 +1,19 @@
/*
*
* Rune declarations - for supporting UTF encoding.
*
*/
#define RUNELIB 1
#ifdef RUNELIB
typedef unsigned short Rune;
enum
{
UTFmax = 3, /* maximum bytes per rune */
Runesync = 0x80, /* cannot represent part of a utf sequence (<) */
Runeself = 0x80, /* rune and utf sequences are the same (<) */
Runeerror = 0x80, /* decoding error in utf */
};
#endif

View file

@ -0,0 +1,27 @@
#include <stdio.h>
#include <errno.h>
#if defined(V9) || defined(BSD4_2) || defined(plan9)
char *tempnam(char *dir, char *pfx) {
int pid;
unsigned int len;
char *tnm, *malloc();
static int seq = 0;
pid = getpid();
len = strlen(dir) + strlen(pfx) + 10;
if ((tnm = malloc(len)) != NULL) {
sprintf(tnm, "%s", dir);
if (access(tnm, 7) == -1)
return(NULL);
do {
sprintf(tnm, "%s/%s%d%d", dir, pfx, pid, seq++);
errno = 0;
if (access(tnm, 7) == -1)
if (errno == ENOENT)
return(tnm);
} while (1);
}
return(tnm);
}
#endif