📄 dvi.cc
字号:
out1(filler);} void dvi_printer::begin_page(int i){ page_count++; int tem = byte_count; out1(bop); out4(i); for (int j = 1; j < 10; j++) out4(0); out4(last_bop); last_bop = tem; // By convention position (0,0) in a dvi file is placed at (1in, 1in). cur_h = font::res; cur_v = font::res; end_h = 0;}void dvi_printer::end_page(int){ if (pushed) end_of_line(); out1(eop); cur_font = 0;}void draw_dvi_printer::end_page(int len){ dvi_printer::end_page(len); output_pen_size = -1;}void dvi_printer::do_special(const char *s){ int len = strlen(s); if (len == 0) return; possibly_begin_line(); out_unsigned(xxx1, len); while (*s) out1(*s++);}void dvi_printer::special(char *arg, const environment *env){ moveto(env->hpos, env->vpos); do_special(arg);}void dvi_printer::moveto(int h, int v){ if (h != cur_h) { out_signed(right1, h - cur_h); cur_h = h; if (cur_h > max_h) max_h = cur_h; } if (v != cur_v) { out_signed(down1, v - cur_v); cur_v = v; if (cur_v > max_v) max_v = cur_v; } end_h = 0;}void dvi_printer::draw(int code, int *p, int np, const environment *env){ if (code == 'l') { int x, y; int height = 0, width; int thickness; if (line_thickness < 0) thickness = env->size*RES_7227*linewidth/1000; else if (line_thickness > 0) thickness = line_thickness; else thickness = 1; if (np != 2) { error("2 arguments required for line"); } else if (p[0] == 0) { // vertical rule if (p[1] > 0) { x = env->hpos - thickness/2; y = env->vpos + p[1] + thickness/2; height = p[1] + thickness; width = thickness; } else if (p[1] < 0) { x = env->hpos - thickness/2; y = env->vpos + thickness/2; height = thickness - p[1]; width = thickness; } } else if (p[1] == 0) { if (p[0] > 0) { x = env->hpos - thickness/2; y = env->vpos + thickness/2; height = thickness; width = p[0] + thickness; } else if (p[0] < 0) { x = env->hpos - p[0] - thickness/2; y = env->vpos + thickness/2; height = thickness; width = thickness - p[0]; } } if (height != 0) { moveto(x, y); out1(put_rule); out4(height); out4(width); } } else if (code == '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"); else line_thickness = p[0]; } } else if (code == 'R') { if (np != 2) error("2 arguments required for rule"); else if (p[0] != 0 || p[1] != 0) { int dh = p[0]; int dv = p[1]; int oh = env->hpos; int ov = env->vpos; if (dv > 0) { ov += dv; dv = -dv; } if (dh < 0) { oh += dh; dh = -dh; } moveto(oh, ov); out1(put_rule); out4(-dv); out4(dh); } }}// XXX Will this overflow?inline int milliinches(int n){ return (n*1000 + font::res/2)/font::res;}void draw_dvi_printer::set_line_thickness(const environment *env){ int desired_pen_size = milliinches(line_thickness < 0 // Will this overflow? ? env->size*RES_7227*linewidth/1000 : line_thickness); if (desired_pen_size != output_pen_size) { char buf[256]; sprintf(buf, "pn %d", desired_pen_size); do_special(buf); output_pen_size = desired_pen_size; }}void draw_dvi_printer::fill_next(){ char buf[256]; sprintf(buf, "sh %.3f", double(fill)/FILL_MAX); do_special(buf);}void draw_dvi_printer::draw(int code, int *p, int np, const environment *env){ char buf[1024]; int fill_flag = 0; switch (code) { case 'C': fill_flag = 1; // fall through case 'c': // troff adds an extra argument to C if (np != 1 && !(code == 'C' && np == 2)) { error("1 argument required for circle"); break; } moveto(env->hpos+p[0]/2, env->vpos); if (fill_flag) fill_next(); else set_line_thickness(env); int rad; rad = milliinches(p[0]/2); sprintf(buf, "%s 0 0 %d %d 0 6.28319", (fill_flag ? "ia" : "ar"), rad, rad); do_special(buf); break; case 'l': if (np != 2) { error("2 arguments required for line"); break; } moveto(env->hpos, env->vpos); set_line_thickness(env); do_special("pa 0 0"); sprintf(buf, "pa %d %d", milliinches(p[0]), milliinches(p[1])); do_special(buf); do_special("fp"); break; case 'E': fill_flag = 1; // fall through case 'e': if (np != 2) { error("2 arguments required for ellipse"); break; } moveto(env->hpos+p[0]/2, env->vpos); if (fill_flag) fill_next(); sprintf(buf, "%s 0 0 %d %d 0 6.28319", (fill_flag ? "ia" : "ar"), milliinches(p[0]/2), milliinches(p[1]/2)); do_special(buf); break; case 'P': fill_flag = 1; // fall through case 'p': { if (np & 1) { error("even number of arguments required for polygon"); break; } if (np == 0) { error("no arguments for polygon"); break; } moveto(env->hpos, env->vpos); if (fill_flag) fill_next(); else set_line_thickness(env); do_special("pa 0 0"); int h = 0, v = 0; for (int i = 0; i < np; i += 2) { h += p[i]; v += p[i+1]; sprintf(buf, "pa %d %d", milliinches(h), milliinches(v)); do_special(buf); } do_special("pa 0 0"); do_special(fill_flag ? "ip" : "fp"); break; } case '~': { if (np & 1) { error("even number of arguments required for spline"); break; } if (np == 0) { error("no arguments for spline"); break; } moveto(env->hpos, env->vpos); set_line_thickness(env); do_special("pa 0 0"); int h = 0, v = 0; for (int i = 0; i < np; i += 2) { h += p[i]; v += p[i+1]; sprintf(buf, "pa %d %d", milliinches(h), milliinches(v)); do_special(buf); } do_special("sp"); break; } case 'a': { if (np != 4) { error("4 arguments required for arc"); break; } set_line_thickness(env); double c[2]; if (adjust_arc_center(p, c)) { int rad = milliinches(int(sqrt(c[0]*c[0] + c[1]*c[1]) + .5)); moveto(env->hpos + int(c[0]), env->vpos + int(c[1])); sprintf(buf, "ar 0 0 %d %d %f %f", rad, rad, atan2(p[1] + p[3] - c[1], p[0] + p[2] - c[0]), atan2(-c[1], -c[0])); do_special(buf); } else { moveto(env->hpos, env->vpos); do_special("pa 0 0"); sprintf(buf, "pa %d %d", milliinches(p[0] + p[2]), milliinches(p[1] + p[3])); do_special(buf); do_special("fp"); } 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) fill = FILL_MAX; break; } case 'R': { if (np != 2) { error("2 arguments required for rule"); break; } int dh = p[0]; if (dh == 0) break; int dv = p[1]; if (dv == 0) break; int oh = env->hpos; int ov = env->vpos; if (dv > 0) { ov += dv; dv = -dv; } if (dh < 0) { oh += dh; dh = -dh; } moveto(oh, ov); out1(put_rule); out4(-dv); out4(dh); break; } default: error("unrecognised drawing command `%1'", char(code)); break; }}font *dvi_printer::make_font(const char *nm){ return dvi_font::load_dvi_font(nm);}printer *make_printer(){ if (draw_flag) return new draw_dvi_printer; else return new dvi_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:vw:d")) != EOF) switch(c) { case 'v': { extern const char *version_string; fprintf(stderr, "grodvi version %s\n", version_string); fflush(stderr); break; } case 'w': if (sscanf(optarg, "%d", &linewidth) != 1 || linewidth < 0 || linewidth > 1000) { error("bad line width"); linewidth = DEFAULT_LINEWIDTH; } break; case 'd': draw_flag = 0; break; case 'F': font::command_line_font_dir(optarg); break; case '?': usage(); break; default: assert(0); } 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 [-dv] [-F dir] [-w n] [files ...]\n", program_name); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -