diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvitops/special.c |
Initial commit
Diffstat (limited to 'dviware/dvitops/special.c')
-rw-r--r-- | dviware/dvitops/special.c | 1050 |
1 files changed, 1050 insertions, 0 deletions
diff --git a/dviware/dvitops/special.c b/dviware/dvitops/special.c new file mode 100644 index 0000000000..bad23d8882 --- /dev/null +++ b/dviware/dvitops/special.c @@ -0,0 +1,1050 @@ +static char rcsid[] = "$Header: /usr/jjc/dvitops/RCS/special.c,v 1.9 90/08/14 13:56:04 jjc Rel $"; + +#include "dvitops.h" + +struct bounding_box { double llx, lly, urx, ury; }; + +#ifdef PROTO +static void do_import(char *arg, integer x, integer y, + int region, struct page_info *page, FILE *psfp); +int strprefix(char *prefix, char *s); +static void read_import_file(char *filename); +#else +static void do_import(); +int strprefix(); +static void read_import_file(); +#endif + +/* this holds the list of files to be imported on the current page */ +static struct import { + integer x, y; + int region; + struct import *next; + char arg[1]; +} *import_list; + + +static struct import_file { + struct bounding_box bb; + struct depend_list *font; + struct import_file *next; + char file[1]; +} *doc_import_list; + +/* this routine is used to include a PostScript file +it will be enhanced later to be quicker and possibly to support +%%IncludeFont and %%IncludeFile comments +return 0 on success, -1 on error +*/ + +int include_file(filename, psfp) +char *filename; +FILE *psfp; +{ + char buf[256]; + FILE *infp; + if ((infp = xfopen(filename, FALSE, texinputs, (char *)NULL)) == NULL) + return EOF; +#ifdef HAVE_SETVBUF + setvbuf(infp, (char *)NULL, _IOFBF, 16384); +#endif + while (fgets(buf, sizeof(buf), infp) != NULL) + if (buf[0] != '%') + fputs(buf, psfp); + fclose(infp); + return 0; +} + +/* return 0 on error */ + +int bigpoint(str, ptr, val) +char *str, **ptr; +double *val; +{ + double x; + int n; + while (isspace(*str)) + ++str; + if (sscanf(str, "%lf", &x) != 1) + goto bad; + while (isdigit(*str) || *str == '.') + str++; + while (isspace(*str)) + str++; + n = isupper(str[0]) ? tolower(str[0]) : str[0]; + n <<= 8; + n |= isupper(str[1]) ? tolower(str[1]) : str[1]; + switch (n) { + case ('b' << 8) + 'p' : + break; + case ('i' << 8) + 'n' : + x *= 72.0; + break; + case ('c' << 8) + 'm' : + x *= 72.0/2.54; + break; + case ('m' << 8) + 'm' : + x *= 72.0/25.4; + break; + case ('s' << 8) + 'p' : + x *= 72.0/(72.27*65536.0); + break; + case ('c' << 8) + 'c' : + x *= 12.0*1238.0*72.0/(1157.0*72.27); + break; + case ('d' << 8) + 'd' : + x *= 1238.0*72.0/(1157.0*72.27); + break; + case ('p' << 8) + 't' : + x *= 72.0/72.27; + break; + case ('p' << 8) + 'c' : + x *= 12.0*72.0/72.27; + break; + default: + goto bad; + } + str += 2; + if (ptr != NULL) + *ptr = str; + *val = x; + return 1; +bad: + if (ptr != NULL) + *ptr = str; + return 0; +} + +static void do_import(arg, x, y, region, page, psfp) +char *arg; +integer x, y; +int region; +struct page_info *page; +FILE *psfp; +{ + double xscale, yscale; + integer gap; + double h, w; + integer width, height; + char *filename; + struct import_file *p; + struct depend_list *q; + struct bounding_box bb; + integer llx, lly, urx, ury; + double sf = (double)page->den*254000.0/((double)page->num*72.0); + char *ptr = arg; + typedef enum { CENTER, LEFT, RIGHT, TOP, BOTTOM, FILL } adjust_t; + adjust_t hadj = CENTER, vadj = CENTER; + while (isspace(*ptr)) + ptr++; + filename = ptr; + while (!isspace(*ptr) && *ptr != '\0') + ptr++; + if (*ptr == '\0') { + message(ERROR, "import \\special syntax error: abandoning import"); + return; + } + *ptr++ = '\0'; + if (bigpoint(ptr, &ptr, &w) == 0 + || bigpoint(ptr, &ptr, &h) == 0) { + message(ERROR, "special import syntax error: abandoning import"); + return; + } + ptr = strtok(ptr, "\r\n\t "); + while (ptr != NULL) { + int i; + for (i = 0; ptr[i] != '\0'; i++) + ptr[i] = isupper(ptr[i]) ? tolower(ptr[i]) : ptr[i]; + if (strcmp(ptr, "top") == 0) + vadj = TOP; + else if (strcmp(ptr, "bottom") == 0) + vadj = BOTTOM; + else if (strcmp(ptr, "fill") == 0) + hadj = vadj = FILL; + else if (strcmp(ptr, "left") == 0) + hadj = LEFT; + else if (strcmp(ptr, "right") == 0) + hadj = RIGHT; + else + message(ERROR, "bad option in import \\special: %s: ignored",ptr); + ptr = strtok((char *)NULL, " \r\n\t"); + } + /* convert to dvi units */ + width = (integer)(w*sf); + height = (integer)(h*sf); + for (p = doc_import_list; p != NULL; p = p->next) + if (strcmp(p->file, filename) == 0) + break; + if (p == NULL) { + message(ERROR, "can't import %s", filename); + return; + } + fputs("BO /showpage {} def\n", psfp); + for (q = p->font; q != NULL; q = q->next) + if (!q->f->in_prolog) + emit_ps_font(q->f->s, psfp); + if (region != NO_REGION) { + integer ox = 0, oy = 0; + do_transform(region, &ox, &oy, psfp); + x -= ox; + y -= oy; + } + bb = p->bb; + if (bb.urx == bb.llx) { + message(ERROR, "bad bounding box: no width"); + return; + } + if (bb.ury == bb.lly) { + message(ERROR, "bad bounding box: no height"); + return; + } + xscale = width/(bb.urx - bb.llx); + yscale = height/(bb.ury - bb.lly); + if (xscale > yscale) { + lly = y; + ury = y - height; + gap = (integer)(width - yscale*(bb.urx - bb.llx)); + switch(hadj) { + case CENTER : + llx = x + gap/2; + urx = x + width - gap/2; + break; + case LEFT : + llx = x; + urx = x + width - gap; + break; + case RIGHT : + llx = x + gap; + urx = x + width; + break; + case FILL : + llx = x; + urx = x + width; + break; + default : + cant_happen(); + } + } + else { + llx = x; + urx = x + width; + gap = (integer)(height - xscale*(bb.ury - bb.lly)); + switch(vadj) { + case CENTER : + lly = y - gap/2; + ury = y - height + gap/2; + break; + case TOP : + lly = y - gap; + ury = y - height; + break; + case BOTTOM : + lly = y; + ury = y - height + gap; + break; + case FILL : + lly = y; + ury = y - height; + break; + default : + cant_happen(); + } + } + fprintf(psfp, "%lg %lg %lg %lg ", bb.llx, bb.lly, bb.urx, bb.ury); + + put_dim((long)llx, psfp); + putc(' ', psfp); + put_dim((long)lly, psfp); + putc(' ', psfp); + put_dim((long)urx, psfp); + putc(' ', psfp); + put_dim((long)ury, psfp); + fputs(" Locate\n", psfp); + fprintf(psfp, "%%%%BeginDocument: %s\n", filename); + if (include_file(filename, psfp) == EOF) + message(ERROR, "can't find import file %s: abandoning import", + filename); + fputs("\n%%EndDocument\nEO\n", psfp); +} + +/* this is called at the end of each page by eop to deal with +any import specials on the current page; it calls do_import to do +the real work */ + +void p_import_list(psfp, page) +FILE *psfp; +struct page_info *page; +{ + if (import_list == NULL) + return; + while (import_list != NULL) { + struct import *q = import_list; + do_import(import_list->arg, import_list->x, import_list->y, + import_list->region, page, psfp); + import_list = import_list->next; + free((char *)q); + } +} + + + +/* this holds a list of all the pieces of inline code for the current page */ + +static struct inline_code { + int region; + integer h, v; + struct inline_code *next; + char s[1]; +} *inline_list = NULL; + +/* this is called by eop at the end of every page to emit any inline +specials */ + +void p_inline_list(psfp) +FILE *psfp; +{ + struct inline_code *p = NULL; + integer ox = 0, oy = 0; + int r = NO_REGION; + /* reverse the list */ + if (inline_list == NULL) + return; + fputs("BO\n", psfp); + while (inline_list != NULL) { + struct inline_code *q = inline_list; + inline_list = inline_list->next; + q->next = p; + p = q; + } + while (p != NULL) { + struct inline_code *q = p; + if (p->region != r) { + fprintf(psfp, "%% region %d\n", p->region); + if (r != NO_REGION) + fputs("grestore\n", psfp); + if (p->region != NO_REGION) { + fputs("gsave\n", psfp); + do_transform(p->region, &ox, &oy, psfp); + } + else + ox = oy = 0; + r = p->region; + } + put_dim((long)(p->h-ox), psfp); + putc(' ', psfp); + put_dim((long)(p->v-oy), psfp); + fputs(" M\n", psfp); + fputs("gsave\n", psfp); + put_dim(1L, psfp); + fputs(" dup scale\n", psfp); + fputs(p->s, psfp); + putc('\n', psfp); + fputs("grestore\n", psfp); + p = p->next; + free((char *)q); + } + inline_list = NULL; + if (r != NO_REGION) + fputs("grestore\n", psfp); + fputs("EO\n", psfp); +} +/* this list is used during pass 1 to hold a list of all prologue files */ + +struct string_list { + struct string_list *next; + char s[1]; +}; + +static struct string_list *prologue_list; + +/* this is called by special during pass 1 to add a prologue file to +prologue_list */ + + +/* this is called while the prologue is being written to include all the +prologue files that have been specified in the document */ + +void p_special_prologues(psfp) +FILE *psfp; +{ + while (prologue_list != NULL) { + struct string_list *temp = prologue_list; + if (include_file(prologue_list->s, psfp) == EOF) + message(ERROR, "can't open prologue file %s: ignoring it", + prologue_list->s); + prologue_list = prologue_list->next; + free((char *)temp); + } +} + +#ifdef PROTO +typedef void special_t(int pass, char *arg, integer x, integer y); +static special_t landscape_special; +static special_t magnification_special; +static special_t prolog_special; +static special_t inline_special; +static special_t import_special; +static special_t rotate_special; +static special_t transform_special; +static special_t origin_special; +static special_t begin_special; +static special_t end_special; +static special_t form_special; +static special_t hsbcolor_special; +static special_t rgbcolor_special; +static special_t gray_special; +#else +static void landscape_special(); +static void magnification_special(); +static void prolog_special(); +static void inline_special(); +static void import_special(); +static void rotate_special(); +static void transform_special(); +static void origin_special(); +static void begin_special(); +static void end_special(); +static void form_special(); +static void hsbcolor_special(); +static void rgbcolor_special(); +static void gray_special(); +#endif + + +static struct { + char *name; +#ifdef PROTO + special_t *proc; +#else + void (*proc)(); +#endif +} special_table[] = { + "landscape", landscape_special, + "magnification", magnification_special, + "prolog", prolog_special, + "inline", inline_special, + "import", import_special, + "rotate", rotate_special, + "transform", transform_special, + "origin", origin_special, + "begin", begin_special, + "end", end_special, + "form", form_special, + "rgbcolor", rgbcolor_special, + "hsbcolor", hsbcolor_special, + "gray", gray_special, + NULL +}; + +static void landscape_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + if (pass == PASS2) + landscape = TRUE; +} + +static void magnification_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + if (pass == PASS2) { + int n; + n = atoi(arg); + if (n <= 0) + message(ERROR, "bad magnification"); + else + magnification = n; + } +} + + +static void prolog_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + char *p = arg; + struct string_list *ptr; + if (pass != PASS1) + return; + while (!isspace(*p) && *p != '\0') + p++; + *p = '\0'; + for (ptr = prologue_list; ptr != NULL; ptr = ptr->next) + if (strcmp(arg, ptr->s) == 0) + return; + if ((ptr = (struct string_list *) + malloc(sizeof(struct string_list) + strlen(arg))) == NULL) + out_of_memory(); + strcpy(ptr->s, arg); + ptr->next = prologue_list; + prologue_list = ptr; +} + + +static void inline_special(pass, arg, x, y) +int pass; +char *arg; +integer x; +integer y; +{ + struct inline_code *p; + if (pass != PASS2) + return; + p = (struct inline_code *) + malloc(sizeof(struct inline_code) + strlen(arg)); + if (p == NULL) + out_of_memory(); + p->h = x; + p->v = y; + p->region = current_region; + strcpy(p->s, arg); + p->next = inline_list; + inline_list = p; +} + + + +static void import_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + if (pass == PASS2) { + struct import *p; + if ((p = (struct import *) + malloc(sizeof(struct import)+strlen(arg))) == NULL) + out_of_memory(); + p->x = x; + p->y = y; + p->region = current_region; + strcpy(p->arg, arg); + p->next = import_list; + import_list = p; + } + else + read_import_file(strtok(arg, " \n\t\r")); +} + +/* x and y are 0 on PASS1 */ + +void special(pass, s, x, y) +int pass; +char *s; +integer x, y; +{ + char *q; + int i; + char *p = s; + if (pass != PASS1 && pass != PASS2) + cant_happen(); +#ifdef TPIC_SUPPORT + if (tpic_special(pass, s, x, y)) + return; +#endif + while (isspace(*p)) + p++; + q = p; + while (*q != '\0' && *q != ':') { + *q = isupper(*q) ? tolower(*q) : *q; + q++; + } + if (*q == '\0') { + if (pass == PASS2) + message(WARNING, + "a \\special without the `dvitops:' tag was ignored"); + return; + } + *q++ = '\0'; + if (strcmp(p, "dvitops") != 0) { + if (pass == PASS2) + message(WARNING, + "a \\special without the `dvitops:' tag was ignored"); + return; + } + while (isspace(*q)) + q++; + p = q; + while (*q != '\0' && !isspace(*q)) { + *q = isupper(*q) ? tolower(*q) : *q; + q++; + } + if (*q != '\0') + *q++ = '\0'; + for (i = 0; special_table[i].name != NULL; i++) + if (strcmp(p, special_table[i].name) == 0) { + (*special_table[i].proc)(pass, q, x, y); + return; + } + if (pass == PASS2) + message(ERROR, "\\special keyword not recognised: %s", p); +} + + +#ifndef M_PI +#define M_PI 3.14159265358979324 +#endif + +#define REGION_MAX 256 +#define RNAME_MAX 128 +static char *WS = " \n\r\t"; +/* we represent a two-dimensional transformation with the `matrix' +structure; it represents the matrix +|a b | +|c d | +*/ + +typedef struct { + double a, b, c, d; +} matrix_t; + + +enum color_type { NO_COLOR, RGB_COLOR, HSB_COLOR, GRAY_COLOR }; + +typedef struct { + char name[RNAME_MAX]; + integer origin_x; + integer origin_y; + matrix_t matrix; + enum color_type color_type; + double color[3]; +} region_t; + +static region_t *region[REGION_MAX]; +#ifdef PROTO +static int lookup_region(char *name); +static void multiply(matrix_t *m, matrix_t *n, matrix_t *mn); +#else +static int lookup_region(); +static void multiply(); +#endif + +/* m, n and mn must all be distinct */ + +static void multiply(m, n, mn) +matrix_t *m, *n, *mn; +{ + mn->a = m->a*n->a + m->b*n->c; + mn->b = m->a*n->b + m->b*n->d; + mn->c = m->c*n->a + m->d*n->c; + mn->d = m->c*n->b + m->d*n->d; +} + + +static int lookup_region(name) +char *name; +{ + int i; + for (i = 0; i < nregions; i++) { + if (region[i] == NULL) + cant_happen(); + if (strncmp(region[i]->name, name, RNAME_MAX) == 0) + return i; + } + if (nregions >= REGION_MAX) + message(FATAL_ERROR, "too many regions"); + if (region[nregions] == NULL + && (region[nregions] = (region_t *) + malloc(sizeof(region_t))) == NULL) + out_of_memory(); + strncpy(region[nregions]->name, name, RNAME_MAX); + region[nregions]->origin_x = 0; + region[nregions]->origin_y = 0; + region[nregions]->matrix.a = 1.0; + region[nregions]->matrix.b = 0.0; + region[nregions]->matrix.c = 0.0; + region[nregions]->matrix.d = 1.0; + region[nregions]->color_type = NO_COLOR; + return nregions++; +} + + +static void rotate_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + char name[128]; + int n; + double theta; + matrix_t m; + matrix_t temp; + if (pass != PASS2) + return; + if (sscanf(arg, "%127s %lf", name, &theta) != 2) { + message(ERROR, "rotate \\special syntax error"); + return; + } + n = lookup_region(name); + theta *= M_PI/180.0; + m.a = cos(theta); + m.b = sin(theta); + m.c = -sin(theta); + m.d = cos(theta); + multiply(&(region[n]->matrix), &m, &temp); + memcpy((char *)&(region[n]->matrix), (char *)&temp, sizeof(matrix_t)); +} + + +static void transform_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + char name[128]; + int n; + matrix_t m, temp; + if (pass != PASS2) + return; + if (sscanf(arg, " %127s %lf %lf %lf %lf", name, + &m.a, &m.b, &m.c, &m.d) != 5) { + message(ERROR, "transform \\special syntax error"); + return; + } + n = lookup_region(name); + multiply(&(region[n]->matrix), &m, &temp); + memcpy((char *)&(region[n]->matrix), (char *)&temp, sizeof(matrix_t)); +} + +static void rgbcolor_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + double color[3]; + char name[128]; + int i, n; + int bad = FALSE; + if (pass != PASS2) + return; + if (sscanf(arg, "%127s %lf %lf %lf", name, color, color + 1, color + 2) + != 4) { + message(ERROR, "rgbcolor \\special syntax error"); + return; + } + n = lookup_region(name); + for (i = 0; i < 3 && !bad; i++) + if (color[i] < 0.0 || color[i] > 1.0) { + bad = TRUE; + message(ERROR, "color parameter must be between 0.0 and 1.0"); + } + else + region[n]->color[i] = color[i]; + region[n]->color_type = bad ? NO_COLOR : RGB_COLOR; +} + +static void hsbcolor_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + double color[3]; + char name[128]; + int i, n; + int bad = FALSE; + if (pass != PASS2) + return; + if (sscanf(arg, "%127s %lf %lf %lf", name, color, color + 1, color + 2) + != 4) { + message(ERROR, "rgbcolor \\special syntax error"); + return; + } + n = lookup_region(name); + for (i = 0; i < 3 && !bad; i++) + if (color[i] < 0.0 || color[i] > 1.0) { + bad = TRUE; + message(ERROR, "color parameter must be between 0.0 and 1.0"); + } + else + region[n]->color[i] = color[i]; + region[n]->color_type = bad ? NO_COLOR : RGB_COLOR; +} + +static void gray_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + double gray; + char name[128]; + int n; + if (pass != PASS2) + return; + if (sscanf(arg, "%127s %lf", name, &gray) != 2) { + message(ERROR, "gray \\special syntax error"); + return; + } + n = lookup_region(name); + if (gray < 0.0 || gray > 1.0) { + message(ERROR, "gray parameter must be between 0.0 and 1.0"); + region[n]->color_type = NO_COLOR; + } + else { + region[n]->color[0] = gray; + region[n]->color_type = GRAY_COLOR; + } +} + + +static void origin_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + int n; + if (pass != PASS2) + return; + arg = strtok(arg, WS); + if (arg == NULL) + message(ERROR, "origin \\special syntax error"); + n = lookup_region(arg); + if (region[n]->origin_x != 0 || region[n]->origin_y != 0) + message(WARNING, "multiple origins for object %s", arg); + region[n]->origin_x = x; + region[n]->origin_y = y; +} + + + +static void begin_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + if (pass != PASS2) + return; + arg = strtok(arg, WS); + if (current_region != NO_REGION) + message(ERROR, "can't have nested begin \\special"); + current_region = lookup_region(arg); +} + +static void end_special(pass, arg, x, y) +int pass; +char *arg; +integer x, y; +{ + if (pass != PASS2) + return; + if (current_region == NO_REGION) + message(ERROR, "end with no begin"); + else + current_region = NO_REGION; +} + +void do_transform(n, origin_x, origin_y, psfp) +int n; +integer *origin_x, *origin_y; +FILE *psfp; +{ + if (n >= nregions) + message(FATAL_ERROR, "too many regions"); + *origin_x = region[n]->origin_x; + *origin_y = region[n]->origin_y; + if (*origin_x != 0 || *origin_y != 0) { + put_dim((long)*origin_x, psfp); + putc(' ', psfp); + put_dim((long)*origin_y, psfp); + fputs(" translate\n", psfp); + } + fprintf(psfp, "[%g %g %g %g 0 0] concat\n", + region[n]->matrix.a, region[n]->matrix.b, + region[n]->matrix.c, region[n]->matrix.d); + switch(region[n]->color_type) { + case GRAY_COLOR: + fprintf(psfp, "%g setgray\n", region[n]->color[0]); + break; + case RGB_COLOR: + fprintf(psfp, "%g %g %g setrgbcolor\n", region[n]->color[0], + region[n]->color[1], region[n]->color[2]); + break; + case HSB_COLOR: + fprintf(psfp, "%g %g %g sethsbcolor\n", region[n]->color[0], + region[n]->color[1], region[n]->color[2]); + break; + case NO_COLOR: + break; + default: + cant_happen(); + } +} + +int strprefix(prefix, s) +char *prefix, *s; +{ + while (*prefix != '\0') + if (*prefix++ != *s++) + return FALSE; + return TRUE; +} + +/* this needs rewriting */ + +static void read_import_file(filename) +char *filename; +{ + FILE *fp; + char buf[256]; + struct import_file *p; + struct depend_list *q; + int atend = FALSE, had_bb = FALSE, in_body = FALSE; + int in_trailer = FALSE; + p = (struct import_file *) + malloc(sizeof(struct import_file) + strlen(filename)); + if (p == NULL) + out_of_memory(); + strcpy(p->file, filename); + p->font = NULL; + p->next = doc_import_list; + if ((fp = xfopen(filename, FALSE, texinputs, (char *)NULL)) == NULL) { + message(ERROR, "can't open %s", filename); + return; + } + if (fgets(buf, sizeof(buf), fp) == NULL) { + message(WARNING, "empty import file %s", filename); + fclose(fp); + return; + } + if (!strprefix("%!", buf)) { + message(ERROR, "%s not PostScript: doesn't start with %%!", filename); + fclose(fp); + return; + } + if (fgets(buf, sizeof(buf), fp) == NULL) { + message(WARNING, "empty import file %s", filename); + fclose(fp); + return; + } + for (;;) { + char *k; + k = strtok(buf + 2, ": \t\r\n"); + if (k == NULL || !strprefix("%%", buf) + || strcmp(k, "EndComments") == 0) { + if (atend) { + in_body = TRUE; + } + else + break; + } + else if (in_body && !in_trailer) { + if (strcmp(k, "Trailer") == 0) + in_trailer = TRUE; + } + else if (strcmp(k, "DocumentFonts") == 0) { + for (;;) { + struct postscript_f_list *f; + char *ptr = strtok((char *)NULL, " \t\r\n"); + if (ptr != NULL && strcmp(ptr, "(atend)") == 0) { + atend = TRUE; + break; + } + while (ptr == NULL) { + if (fgets(buf, sizeof(buf), fp) == NULL) { + buf[0] = '\0'; + goto out; + } + if (memcmp(buf, "%%+", 3) != 0) + goto out; + ptr = strtok(buf+3, "\n\r\t "); + } + f = add_postscript_font(ptr); + q = (struct depend_list *)malloc(sizeof(struct depend_list)); + q->f = f; + q->next = p->font; + p->font = q; + } + out: continue; /* don't read a line */ + } + else if (strcmp(k, "BoundingBox") == 0) { + int i; + for (i = 0; i < 4; i++) { + char *ptr = strtok((char *)NULL, "\r\t\n "); + double x; + if (ptr == NULL) { + message(ERROR, "BoundingBox comment empty"); + fclose(fp); + return; + } + if (i == 0 && strcmp(ptr, "(atend)") == 0) { + atend = TRUE; + break; + } + had_bb = TRUE; + x = atof(ptr); + switch(i) { + case 0: + p->bb.llx = x; + break; + case 1: + p->bb.lly = x; + break; + case 2: + p->bb.urx = x; + break; + case 3: + p->bb.ury = x; + break; + default: + cant_happen(); + } + } + } + if (fgets(buf, sizeof(buf), fp) == NULL) + break; + } + if (!had_bb) { + message(ERROR, "%s: no BoundingBox comment", filename); + fclose(fp); + return; + } + doc_import_list = p; + fclose(fp); +} + +static struct string_list *form_list; + +static void form_special(pass, arg, x, y) +int pass; +char *arg; +integer x; +integer y; +{ + struct string_list *s; + if (pass != PASS2) + return; + if ((s = (struct string_list *)malloc(sizeof(struct string_list) + strlen(arg))) == NULL) + out_of_memory(); + s->next = form_list; + form_list = s; + strcpy(s->s, arg); +} + +void p_form_list(psfp) +FILE *psfp; +{ + while (form_list != NULL) { + struct string_list *s = form_list; + fputs("/showpage {} def\n", psfp); + fprintf(psfp, "/--save-- save def\n%%%%BeginDocument: %s\n", s->s); + if (include_file(s->s, psfp) == EOF) + message(ERROR, "can't find %s", s->s); + fputs("\n%%EndDocument\n--save-- restore\n", psfp); + form_list = s->next; + free((char *)s); + } +} + +/* +Local Variables: +c-indent-level: 4 +c-continued-statement-offset: 4 +c-brace-offset: -4 +c-argdecl-indent: 0 +c-label-offset: -4 +tab-width: 4 +End: +*/ + |