📄 ps.cc
字号:
if (np != 4) { error("4 arguments required for arc"); break; } set_line_thickness(env); double c[2]; if (adjust_arc_center(p, c)) out.put_fix_number(env->hpos + int(c[0])) .put_fix_number(env->vpos + int(c[1])) .put_fix_number(int(sqrt(c[0]*c[0] + c[1]*c[1]))) .put_float(degrees(atan2(-c[1], -c[0]))) .put_float(degrees(atan2(p[1] + p[3] - c[1], p[0] + p[2] - c[0]))) .put_symbol("DA"); else out.put_fix_number(p[0] + p[2] + env->hpos) .put_fix_number(p[1] + p[3] + env->vpos) .put_fix_number(env->hpos) .put_fix_number(env->vpos) .put_symbol("DL"); } break; case 't': { if (np == 0) { line_thickness = -1; } else { // troff gratuitously adds an extra 0 if (np != 1 && np != 2) { error("0 or 1 argument required for thickness"); break; } line_thickness = p[0]; } break; } case 'f': { if (np != 1 && np != 2) { error("1 argument required for fill"); break; } fill = p[0]; if (fill < 0 || fill > FILL_MAX) { // This means fill with the current color. fill = FILL_MAX + 1; } break; } default: error("unrecognised drawing command `%1'", char(code)); break; } output_hpos = output_vpos = -1;}void ps_printer::begin_page(int n){ out.begin_comment("Page:").comment_arg(itoa(n)); out.comment_arg(itoa(++pages_output)).end_comment(); output_style.f = 0; output_space_code = 32; output_draw_point_size = -1; output_line_thickness = -1; output_hpos = output_vpos = -1; ndefined_styles = 0; out.simple_comment("BeginPageSetup"); out.put_symbol("BP"); out.simple_comment("EndPageSetup");}void ps_printer::end_page(int){ flush_sbuf(); out.put_symbol("EP"); if (invis_count != 0) { error("missing `endinvis' command"); invis_count = 0; }}font *ps_printer::make_font(const char *nm){ return ps_font::load_ps_font(nm);}ps_printer::~ps_printer(){ out.simple_comment("Trailer"); out.put_symbol("end"); out.simple_comment("EOF"); if (fseek(tempfp, 0L, 0) < 0) fatal("fseek on temporary file failed"); fputs("%!PS-Adobe-", stdout); fputs((broken_flags & USE_PS_ADOBE_2_0) ? "2.0" : "3.0", stdout); putchar('\n'); out.set_file(stdout); { extern const char *version_string; out.begin_comment("Creator:") .comment_arg("groff") .comment_arg("version") .comment_arg(version_string) .end_comment(); } for (font_pointer_list *f = font_list; f; f = f->next) { ps_font *psf = (ps_font *)(f->p); rm.need_font(psf->get_internal_name()); } rm.print_header_comments(out); out.begin_comment("Pages:").comment_arg(itoa(pages_output)).end_comment(); out.begin_comment("PageOrder:").comment_arg("Ascend").end_comment();#if 0 fprintf(out.get_file(), "%%%%DocumentMedia: () %g %g 0 () ()\n", font::paperwidth*72.0/font::res, paper_length*72.0/font::res);#endif out.begin_comment("Orientation:") .comment_arg(landscape_flag ? "Landscape" : "Portrait") .end_comment(); if (ncopies != 1) { out.end_line(); fprintf(out.get_file(), "%%%%Requirements: numcopies(%d)\n", ncopies); } out.simple_comment("EndComments"); out.simple_comment("BeginProlog"); rm.output_prolog(out); if (!(broken_flags & NO_SETUP_SECTION)) { out.simple_comment("EndProlog"); out.simple_comment("BeginSetup"); } rm.document_setup(out); out.put_symbol(dict_name).put_symbol("begin"); if (ndefs > 0) ndefs += DEFS_DICT_SPARE; out.put_literal_symbol(defs_dict_name) .put_number(ndefs + 1) .put_symbol("dict") .put_symbol("def"); out.put_symbol(defs_dict_name) .put_symbol("begin"); out.put_literal_symbol("u") .put_delimiter('{') .put_fix_number(1) .put_symbol("mul") .put_delimiter('}') .put_symbol("bind") .put_symbol("def"); defs += '\0'; out.special(defs.contents()); out.put_symbol("end"); if (ncopies != 1) out.put_literal_symbol("#copies").put_number(ncopies).put_symbol("def"); out.put_literal_symbol("RES").put_number(res).put_symbol("def"); out.put_literal_symbol("PL"); if (guess_flag) out.put_symbol("PLG"); else out.put_fix_number(paper_length); out.put_symbol("def"); out.put_literal_symbol("LS") .put_symbol(landscape_flag ? "true" : "false") .put_symbol("def"); encode_fonts(); out.simple_comment((broken_flags & NO_SETUP_SECTION) ? "EndProlog" : "EndSetup"); out.end_line(); out.copy_file(tempfp); fclose(tempfp);}void ps_printer::special(char *arg, const environment *env){ typedef void (ps_printer::*SPECIAL_PROCP)(char *, const environment *); static struct { const char *name; SPECIAL_PROCP proc; } proc_table[] = { "exec", &ps_printer::do_exec, "def", &ps_printer::do_def, "mdef", &ps_printer::do_mdef, "import", &ps_printer::do_import, "file", &ps_printer::do_file, "invis", &ps_printer::do_invis, "endinvis", &ps_printer::do_endinvis, }; for (char *p = arg; *p == ' ' || *p == '\n'; p++) ; char *tag = p; for (; *p != '\0' && *p != ':' && *p != ' ' && *p != '\n'; p++) ; if (*p == '\0' || strncmp(tag, "ps", p - tag) != 0) { error("X command without `ps:' tag ignored"); return; } p++; for (; *p == ' ' || *p == '\n'; p++) ; char *command = p; for (; *p != '\0' && *p != ' ' && *p != '\n'; p++) ; if (*command == '\0') { error("X command without `ps:' tag ignored"); return; } for (int i = 0; i < sizeof(proc_table)/sizeof(proc_table[0]); i++) if (strncmp(command, proc_table[i].name, p - command) == 0) { (this->*(proc_table[i].proc))(p, env); return; } error("X command `%1' not recognised", command);}// A conforming PostScript document must not have lines longer// than 255 characters (excluding line termination characters).static int check_line_lengths(const char *p){ for (;;) { const char *end = strchr(p, '\n'); if (end == 0) end = strchr(p, '\0'); if (end - p > 255) return 0; if (*end == '\0') break; p = end + 1; } return 1;}void ps_printer::do_exec(char *arg, const environment *env){ flush_sbuf(); while (csspace(*arg)) arg++; if (*arg == '\0') { error("missing argument to X exec command"); return; } if (!check_line_lengths(arg)) { error("lines in X exec command must not be more than 255 characters long"); return; } out.put_fix_number(env->hpos) .put_fix_number(env->vpos) .put_symbol("EBEGIN") .special(arg) .put_symbol("EEND"); output_hpos = output_vpos = -1; output_style.f = 0; output_draw_point_size = -1; output_line_thickness = -1; ndefined_styles = 0; if (!ndefs) ndefs = 1;}void ps_printer::do_file(char *arg, const environment *env){ flush_sbuf(); while (csspace(*arg)) arg++; if (*arg == '\0') { error("missing argument to X file command"); return; } const char *filename = arg; do { ++arg; } while (*arg != '\0' && *arg != ' ' && *arg != '\n'); out.put_fix_number(env->hpos) .put_fix_number(env->vpos) .put_symbol("EBEGIN"); rm.import_file(filename, out); out.put_symbol("EEND"); output_hpos = output_vpos = -1; output_style.f = 0; output_draw_point_size = -1; output_line_thickness = -1; ndefined_styles = 0; if (!ndefs) ndefs = 1;}void ps_printer::do_def(char *arg, const environment *){ flush_sbuf(); while (csspace(*arg)) arg++; if (!check_line_lengths(arg)) { error("lines in X def command must not be more than 255 characters long"); return; } defs += arg; if (*arg != '\0' && strchr(arg, '\0')[-1] != '\n') defs += '\n'; ndefs++;}// Like def, but the first argument says how many definitions it contains.void ps_printer::do_mdef(char *arg, const environment *){ flush_sbuf(); char *p; int n = (int)strtol(arg, &p, 10); if (n == 0 && p == arg) { error("first argument to X mdef must be an integer"); return; } if (n < 0) { error("out of range argument `%1' to X mdef command", int(n)); return; } arg = p; while (csspace(*arg)) arg++; if (!check_line_lengths(arg)) { error("lines in X mdef command must not be more than 255 characters long"); return; } defs += arg; if (*arg != '\0' && strchr(arg, '\0')[-1] != '\n') defs += '\n'; ndefs += n;}void ps_printer::do_import(char *arg, const environment *env){ flush_sbuf(); while (*arg == ' ' || *arg == '\n') arg++; for (char *p = arg; *p != '\0' && *p != ' ' && *p != '\n'; p++) ; if (*p != '\0') *p++ = '\0'; int parms[6]; int nparms = 0; while (nparms < 6) { char *end; long n = strtol(p, &end, 10); if (n == 0 && end == p) break; parms[nparms++] = int(n); p = end; } if (csalpha(*p) && (p[1] == '\0' || p[1] == ' ' || p[1] == '\n')) { error("scaling indicators not allowed in arguments for X import command"); return; } while (*p == ' ' || *p == '\n') p++; if (nparms < 5) { if (*p == '\0') error("too few arguments for X import command"); else error("invalid argument `%1' for X import command", p); return; } if (*p != '\0') { error("superflous argument `%1' for X import command", p); return; } int llx = parms[0]; int lly = parms[1]; int urx = parms[2]; int ury = parms[3]; int desired_width = parms[4]; int desired_height = parms[5]; if (desired_width <= 0) { error("bad width argument `%1' for X import command: must be > 0", desired_width); return; } if (nparms == 6 && desired_height <= 0) { error("bad height argument `%1' for X import command: must be > 0", desired_height); return; } if (llx == urx) { error("llx and urx arguments for X import command must not be equal"); return; } if (lly == ury) { error("lly and ury arguments for X import command must not be equal"); return; } if (nparms == 5) { int old_wid = urx - llx; int old_ht = ury - lly; if (old_wid < 0) old_wid = -old_wid; if (old_ht < 0) old_ht = -old_ht; desired_height = int(desired_width*(double(old_ht)/double(old_wid)) + .5); } if (env->vpos - desired_height < 0) warning("top of imported graphic is above the top of the page"); out.put_number(llx) .put_number(lly) .put_fix_number(desired_width) .put_number(urx - llx) .put_fix_number(-desired_height) .put_number(ury - lly) .put_fix_number(env->hpos) .put_fix_number(env->vpos) .put_symbol("PBEGIN"); rm.import_file(arg, out); // do this here just in case application defines PEND out.put_symbol("end"); out.put_symbol("PEND");}void ps_printer::do_invis(char *, const environment *){ invis_count++;}void ps_printer::do_endinvis(char *, const environment *){ if (invis_count == 0) error("unbalanced `endinvis' command"); else --invis_count;}printer *make_printer(){ return new ps_printer;}static void usage();int main(int argc, char **argv){ program_name = argv[0]; static char stderr_buf[BUFSIZ]; setbuf(stderr, stderr_buf); int c; while ((c = getopt(argc, argv, "F:glc:w:vb:")) != EOF) switch(c) { case 'v': { extern const char *version_string; fprintf(stderr, "grops version %s\n", version_string); fflush(stderr); break; } case 'c': if (sscanf(optarg, "%d", &ncopies) != 1 || ncopies <= 0) { error("bad number of copies `%s'", optarg); ncopies = 1; } break; case 'g': guess_flag = 1; break; case 'l': landscape_flag = 1; break; case 'F': font::command_line_font_dir(optarg); break; case 'w': if (sscanf(optarg, "%d", &linewidth) != 1 || linewidth < 0) { error("bad linewidth `%s'", optarg); linewidth = -1; } break; case 'b': // XXX check this broken_flags = atoi(optarg); bflag = 1; break; case '?': usage(); break; default: assert(0); } font::set_unknown_desc_command_handler(handle_unknown_desc_command); if (optind >= argc) do_file("-"); else { for (int i = optind; i < argc; i++) do_file(argv[i]); } delete pr; exit(0);}static void usage(){ fprintf(stderr, "usage: %s [-glv] [-b n] [-c n] [-w n] [-F dir] [files ...]\n", program_name); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -