X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fpostscript.c;h=fd738ababba65e1e344a053d53466f1722eb0b6c;hb=3417680e253b1bfc4519347ef06536378026be2a;hp=8a11935aa6029e4b3a822995a517a6a940dd7e79;hpb=7b98b3a4f58f6dc5a8e9cbc188b627966d5e652d;p=pspp diff --git a/src/postscript.c b/src/postscript.c index 8a11935aa6..fd738ababb 100644 --- a/src/postscript.c +++ b/src/postscript.c @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include @@ -23,39 +23,34 @@ #if !NO_POSTSCRIPT #include -#include +#include "error.h" #include #include #include +#include #if HAVE_UNISTD_H #include #endif -#if TIME_WITH_SYS_TIME -#include -#include -#else -#if HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - #include "alloc.h" #include "bitvector.h" #include "error.h" #include "filename.h" #include "font.h" +#include "getl.h" #include "getline.h" #include "hash.h" #include "main.h" #include "misc.h" #include "misc.h" #include "output.h" +#include "som.h" #include "version.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* FIXMEs: optimize-text-size not implemented. @@ -267,6 +262,7 @@ static unsigned hash_font_entry (const void *, void *param); static void free_font_entry (void *, void *foo); static struct font_entry *load_font (struct outp_driver *, const char *dit); static void init_fonts (void); +static void done_fonts (void); static void dump_lines (struct outp_driver *this); @@ -297,6 +293,8 @@ ps_open_global (struct outp_class *this UNUSED) static int ps_close_global (struct outp_class *this UNUSED) { + groff_done (); + done_fonts (); return 1; } @@ -567,7 +565,7 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val) { struct ps_driver_ext *x = this->ext; int cat, subcat; - char *value = ds_value (val); + char *value = ds_c_str (val); cat = outp_match_keyword (key, option_tab, &option_info, &subcat); @@ -661,6 +659,7 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val) break; default: assert (0); + abort (); } if (setting) x->output_options |= mask; @@ -762,6 +761,7 @@ ps_option (struct outp_driver *this, const char *key, const struct string *val) break; default: assert (0); + abort (); } if (*dest) free (*dest); @@ -896,8 +896,8 @@ output_encodings (struct outp_driver *this) struct string line, buf; - ds_init (NULL, &line, 128); - ds_init (NULL, &buf, 128); + ds_init (&line, 128); + ds_init (&buf, 128); for (pe = hsh_first (x->encodings, &iter); pe != NULL; pe = hsh_next (x->encodings, &iter)) { @@ -944,7 +944,7 @@ output_encodings (struct outp_driver *this) if (buf.length == 0) continue; - pschar = strtok_r (ds_value (&buf), " \t\r\n", &sp); + pschar = strtok_r (ds_c_str (&buf), " \t\r\n", &sp); code = strtok_r (NULL, " \t\r\n", &sp); if (*pschar == 0 || *code == 0) continue; @@ -982,14 +982,14 @@ output_encodings (struct outp_driver *this) if (ds_length (&line) + strlen (temp) > 70) { - ds_concat (&line, x->eol); - fputs (ds_value (&line), x->file.file); + ds_puts (&line, x->eol); + fputs (ds_c_str (&line), x->file.file); ds_clear (&line); } - ds_concat (&line, temp); + ds_puts (&line, temp); } - ds_concat (&line, x->eol); - fputs (ds_value (&line), x->file.file); + ds_puts (&line, x->eol); + fputs (ds_c_str (&line), x->file.file); if (fclose (f) == EOF) msg (MW, _("PostScript driver: Error closing encoding file `%s'."), @@ -1102,12 +1102,10 @@ read_ps_encodings (struct outp_driver *this) where.line_number = 0; err_push_file_locator (&where); - ds_init (NULL, &line, 128); + ds_init (&line, 128); for (;;) { - char *bp; - if (!ds_get_config_line (f, &line, &where)) { if (ferror (f)) @@ -1115,7 +1113,7 @@ read_ps_encodings (struct outp_driver *this) break; } - add_encoding (this, bp); + add_encoding (this, line.string); } ds_destroy (&line); @@ -1448,7 +1446,7 @@ postopen (struct file_ext *f) char *beg; beg = buf2 = fn_interp_vars (buf, ps_get_var); len = strlen (buf2); - while (isspace (*beg)) + while (isspace ((unsigned char) *beg)) beg++, len--; if (beg[len - 1] == '\n') len--; @@ -1490,7 +1488,7 @@ quote_ps_name (char *dest, const char *string) const char *sp; for (sp = string; *sp; sp++) - switch (*(unsigned char *) sp) + switch (*sp) { case 'a': case 'f': @@ -1565,7 +1563,7 @@ quote_ps_name (char *dest, const char *string) *dp++ = '<'; for (sp = string; *sp && dp < &dest[256]; sp++) { - sprintf (dp, "%02x", *(unsigned char *) sp); + sprintf (dp, "%02x", (unsigned char) *sp); dp += 2; } return stpcpy (dp, ">cvn"); @@ -1590,7 +1588,7 @@ quote_ps_string (char *dest, const char *string) dp = stpcpy (dp, "\\("); else if (*sp == ')') dp = stpcpy (dp, "\\)"); - else if (*sp < 32 || *((unsigned char *) sp) > 127) + else if (*sp < 32 || (unsigned char) *sp > 127) dp = spprintf (dp, "\\%3o", *sp); else *dp++ = *sp; @@ -1690,6 +1688,8 @@ ps_open_page (struct outp_driver *this) draw_headers (this); } + this->cp_y = 0; + return !ferror (x->file.file); } @@ -1711,6 +1711,19 @@ ps_close_page (struct outp_driver *this) this->page_open = 0; return !ferror (x->file.file); } + +static void +ps_submit (struct outp_driver *this UNUSED, struct som_entity *s) +{ + switch (s->type) + { + case SOM_CHART: + break; + default: + assert(0); + break; + } +} /* Lines. */ @@ -2410,6 +2423,9 @@ write_text (struct outp_driver *this, case OUTP_T_JUST_CENTER: ofs = width_left / 2; break; + default: + assert (0); + abort (); } lp = line; @@ -2450,7 +2466,7 @@ write_text (struct outp_driver *this, if (TEST_BIT (literal_chars[ext->data], cp->ch)) *lp++ = cp->ch; else - switch (cp->ch) + switch ((char) cp->ch) { case '(': lp = stpcpy (lp, "\\("); @@ -2540,18 +2556,23 @@ text (struct outp_driver *this, struct outp_text *t, int draw) buf_loc = buf; assert (!ls_null_p (&t->s)); - cp = ls_value (&t->s); + cp = ls_c_str (&t->s); end = ls_end (&t->s); if (draw) { x = t->x; y = t->y; } + else + x = y = 0; width = width_left = (t->options & OUTP_T_HORZ) ? t->h : INT_MAX; height_left = (t->options & OUTP_T_VERT) ? t->v : INT_MAX; max_height = 0; prev_char = -1; space_char = NULL; + space_buf_loc = NULL; + space_width_left = 0; + if (!width || !height_left) goto exit; @@ -2566,9 +2587,12 @@ text (struct outp_driver *this, struct outp_text *t, int draw) /* Set char_name to the name of the character or ligature at *cp. */ + local_char_name[0] = *cp; + char_name = local_char_name; if (ext->current->font->ligatures && *cp == 'f') { int lig = 0; + char_name = NULL; if (cp < end - 1) switch (cp[1]) @@ -2596,11 +2620,9 @@ text (struct outp_driver *this, struct outp_text *t, int draw) } if ((lig & ext->current->font->ligatures) == 0) { - local_char_name[0] = *cp++; /* 'f' */ + local_char_name[0] = *cp; /* 'f' */ char_name = local_char_name; } - else - cp += strlen (char_name); } else if (*cp == '\n') { @@ -2623,11 +2645,7 @@ text (struct outp_driver *this, struct outp_text *t, int draw) set separate to 1. */ continue; } - else - { - local_char_name[0] = *cp++; - char_name = local_char_name; - } + cp += strlen (char_name); /* Figure out what size this character is, and what kern adjustment we need. */ @@ -2810,6 +2828,12 @@ init_fonts (void) NULL, NULL); } +static void +done_fonts (void) +{ + hsh_destroy (ps_fonts); +} + /* Loads the font having Groff name DIT into THIS driver instance. Specifically, adds it into the THIS driver's `loaded' hash table. */ @@ -2857,6 +2881,86 @@ load_font (struct outp_driver *this, const char *dit) return fe; } +static void +ps_chart_initialise (struct outp_driver *this UNUSED, struct chart *ch) +{ +#ifdef NO_CHARTS + ch->lp = NULL; +#else + struct ps_driver_ext *x = this->ext; + char page_size[128]; + int size; + int x_origin, y_origin; + + ch->file = tmpfile (); + if (ch->file == NULL) + { + ch->lp = NULL; + return; + } + + size = this->width < this->length ? this->width : this->length; + x_origin = x->left_margin + (size - this->width) / 2; + y_origin = x->bottom_margin + (size - this->length) / 2; + + snprintf (page_size, sizeof page_size, + "a,xsize=%.3f,ysize=%.3f,xorigin=%.3f,yorigin=%.3f", + (double) size / PSUS, (double) size / PSUS, + (double) x_origin / PSUS, (double) y_origin / PSUS); + + ch->pl_params = pl_newplparams (); + pl_setplparam (ch->pl_params, "PAGESIZE", page_size); + ch->lp = pl_newpl_r ("ps", NULL, ch->file, stderr, ch->pl_params); +#endif +} + +static void +ps_chart_finalise (struct outp_driver *this UNUSED, struct chart *ch UNUSED) +{ +#ifndef NO_CHARTS + struct ps_driver_ext *x = this->ext; + char buf[BUFSIZ]; + static int doc_num = 0; + + if (this->page_open) + { + this->class->close_page (this); + this->page_open = 0; + } + this->class->open_page (this); + fprintf (x->file.file, + "/sp save def%s" + "%d %d translate 1000 dup scale%s" + "userdict begin%s" + "/showpage { } def%s" + "0 setgray 0 setlinecap 1 setlinewidth%s" + "0 setlinejoin 10 setmiterlimit [ ] 0 setdash newpath clear%s" + "%%%%BeginDocument: %d%s", + x->eol, + -x->left_margin, -x->bottom_margin, x->eol, + x->eol, + x->eol, + x->eol, + x->eol, + doc_num++, x->eol); + + rewind (ch->file); + while (fwrite (buf, 1, fread (buf, 1, sizeof buf, ch->file), x->file.file)) + continue; + fclose (ch->file); + + fprintf (x->file.file, + "%%%%EndDocument%s" + "end%s" + "sp restore%s", + x->eol, + x->eol, + x->eol); + this->class->close_page (this); + this->page_open = 0; +#endif +} + /* PostScript driver class. */ struct outp_class postscript_class = { @@ -2876,7 +2980,7 @@ struct outp_class postscript_class = ps_open_page, ps_close_page, - NULL, + ps_submit, ps_line_horz, ps_line_vert, @@ -2896,6 +3000,9 @@ struct outp_class postscript_class = ps_text_get_size, ps_text_metrics, ps_text_draw, + + ps_chart_initialise, + ps_chart_finalise }; /* EPSF driver class. FIXME: Probably doesn't work right. */ @@ -2917,7 +3024,7 @@ struct outp_class epsf_class = ps_open_page, ps_close_page, - NULL, + ps_submit, ps_line_horz, ps_line_vert, @@ -2937,6 +3044,10 @@ struct outp_class epsf_class = ps_text_get_size, ps_text_metrics, ps_text_draw, + + ps_chart_initialise, + ps_chart_finalise + }; #endif /* NO_POSTSCRIPT */