⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvi.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "driver.h"#define DEFAULT_LINEWIDTH 40static int linewidth = DEFAULT_LINEWIDTH;static int draw_flag = 1;/* These values were chosen because:(MULTIPLIER*SIZESCALE)/(RES*UNITWIDTH) == 1/(2^20 * 72.27)and 57816 is an exact multiple of both 72.27*SIZESCALE and 72.The width in the groff font file is the product of MULTIPLIER and thewidth in the tfm file. */#define RES 57816#define RES_7227 (RES/7227)#define UNITWIDTH 131072#define SIZESCALE 100#define MULTIPLIER 1#define FILL_MAX 1000class dvi_font : public font {  dvi_font(const char *);public:  int checksum;  int design_size;  ~dvi_font();  void handle_unknown_font_command(const char *command, const char *arg,				   const char *filename, int lineno);  static dvi_font *load_dvi_font(const char *);};dvi_font *dvi_font::load_dvi_font(const char *s){  dvi_font *f = new dvi_font(s);  if (!f->load()) {    delete f;    return 0;  }  return f;}dvi_font::dvi_font(const char *nm): font(nm), checksum(0), design_size(0){}dvi_font::~dvi_font(){}void dvi_font::handle_unknown_font_command(const char *command,					   const char *arg,					   const char *filename, int lineno){  char *ptr;  if (strcmp(command, "checksum") == 0) {    if (arg == 0)      fatal_with_file_and_line(filename, lineno,			       "`checksum' command requires an argument");    checksum = int(strtol(arg, &ptr, 10));    if (checksum == 0 && ptr == arg) {      fatal_with_file_and_line(filename, lineno, "bad checksum");    }  }  else if (strcmp(command, "designsize") == 0) {    if (arg == 0)      fatal_with_file_and_line(filename, lineno,			       "`designsize' command requires an argument");    design_size = int(strtol(arg, &ptr, 10));    if (design_size == 0 && ptr == arg) {      fatal_with_file_and_line(filename, lineno, "bad design size");    }  }}#define FONTS_MAX 256struct output_font {  dvi_font *f;  int point_size;  output_font() : f(0) { }};class dvi_printer : public printer {  FILE *fp;  int max_drift;  int byte_count;  int last_bop;  int page_count;  int cur_h;  int cur_v;  int end_h;  int max_h;  int max_v;  output_font output_font_table[FONTS_MAX];  font *cur_font;  int cur_point_size;  int pushed;  int pushed_h;  int pushed_v;  int have_pushed;  void preamble();  void postamble();  void define_font(int);  void set_font(int);  void possibly_begin_line();protected:  enum {    id_byte = 2,    set1 = 128,    put1 = 133,    put_rule = 137,    bop = 139,    eop = 140,    push = 141,    pop = 142,    right1 = 143,    down1 = 157,    fnt_num_0 = 171,    fnt1 = 235,    xxx1 = 239,    fnt_def1 = 243,    pre = 247,    post = 248,    post_post = 249,    filler = 223  };  int line_thickness;  void out1(int);  void out2(int);  void out3(int);  void out4(int);  void moveto(int, int);  void out_string(const char *);  void out_signed(unsigned char, int);  void out_unsigned(unsigned char, int);  void do_special(const char *);public:  dvi_printer();  ~dvi_printer();  font *make_font(const char *);  void begin_page(int);  void end_page(int);  void set_char(int, font *, const environment *, int w);  void special(char *arg, const environment *env);  void end_of_line();  void draw(int code, int *p, int np, const environment *env);};class draw_dvi_printer : public dvi_printer {  int output_pen_size;  int fill;  void set_line_thickness(const environment *);  void fill_next();public:  draw_dvi_printer();  ~draw_dvi_printer();  void draw(int code, int *p, int np, const environment *env);  void end_page(int);};dvi_printer::dvi_printer(): byte_count(0), last_bop(-1), page_count(0), cur_font(0), fp(stdout),  max_h(0), max_v(0), pushed(0), line_thickness(-1), cur_point_size(-1){  if (font::res != RES)    fatal("resolution must be %1", RES);  if (font::unitwidth != UNITWIDTH)    fatal("unitwidth must be %1", UNITWIDTH);  if (font::hor != 1)    fatal("hor must be equal to 1");  if (font::vert != 1)    fatal("vert must be equal to 1");  if (font::sizescale != SIZESCALE)    fatal("sizescale must be equal to %1", SIZESCALE);  max_drift = font::res/1000;	// this is fairly arbitrary  preamble();}dvi_printer::~dvi_printer(){  postamble();}draw_dvi_printer::draw_dvi_printer(): output_pen_size(-1), fill(FILL_MAX){}draw_dvi_printer::~draw_dvi_printer(){}void dvi_printer::out1(int n){  byte_count += 1;  putc(n & 0xff, fp);}void dvi_printer::out2(int n){  byte_count += 2;  putc((n >> 8) & 0xff, fp);  putc(n & 0xff, fp);}void dvi_printer::out3(int n){  byte_count += 3;  putc((n >> 16) & 0xff, fp);  putc((n >> 8) & 0xff, fp);  putc(n & 0xff, fp);}void dvi_printer::out4(int n){  byte_count += 4;  putc((n >> 24) & 0xff, fp);  putc((n >> 16) & 0xff, fp);  putc((n >> 8) & 0xff, fp);  putc(n & 0xff, fp);}void dvi_printer::out_string(const char *s){  out1(strlen(s));  while (*s != 0)    out1(*s++);}void dvi_printer::end_of_line(){  if (pushed) {    out1(pop);    pushed = 0;    cur_h = pushed_h;    cur_v = pushed_v;  }}void dvi_printer::possibly_begin_line(){  if (!pushed) {    have_pushed = pushed = 1;    pushed_h = cur_h;    pushed_v = cur_v;    out1(push);  }}int scale(int x, int z){  int sw;  int a, b, c, d;  int alpha, beta;  alpha = 16*z; beta = 16;  while (z >= 040000000L) {    z /= 2; beta /= 2;  }  d = x & 255;  c = (x >> 8) & 255;  b = (x >> 16) & 255;  a = (x >> 24) & 255;  sw = (((((d * z) / 0400) + (c * z)) / 0400) + (b * z)) / beta;  if (a == 255)    sw -= alpha;  else    assert(a == 0);  return sw;}void dvi_printer::set_char(int index, font *f, const environment *env, int w){  int code = f->get_code(index);  if (env->size != cur_point_size || f != cur_font) {    cur_font = f;    cur_point_size = env->size;    for (int i = 0;; i++) {      if (i >= FONTS_MAX) {	fatal("too many output fonts required");      }      if (output_font_table[i].f == 0) {	output_font_table[i].f = (dvi_font *)cur_font;	output_font_table[i].point_size = cur_point_size;	define_font(i);      }      if (output_font_table[i].f == cur_font	  && output_font_table[i].point_size == cur_point_size)	break;    }    set_font(i);  }  int distance = env->hpos - cur_h;  if (env->hpos != end_h && distance != 0) {    out_signed(right1, distance);    cur_h = env->hpos;  }  else if (distance > max_drift) {    out_signed(right1, distance - max_drift);    cur_h = env->hpos - max_drift;  }  else if (distance < -max_drift) {    out_signed(right1, distance + max_drift);    cur_h = env->hpos + max_drift;  }  if (env->vpos != cur_v) {    out_signed(down1, env->vpos - cur_v);    cur_v = env->vpos;  }  possibly_begin_line();  end_h = env->hpos + w;  cur_h += scale(f->get_width(index, UNITWIDTH)/MULTIPLIER,		cur_point_size*RES_7227);  if (cur_h > max_h)    max_h = cur_h;  if (cur_v > max_v)    max_v = cur_v;  if (code >= 0 && code <= 127)    out1(code);  else    out_unsigned(set1, code);}void dvi_printer::define_font(int i){  out_unsigned(fnt_def1, i);  dvi_font *f = output_font_table[i].f;  out4(f->checksum);  out4(output_font_table[i].point_size*RES_7227);  out4(int((double(f->design_size)/(1<<20))*RES_7227*100 + .5));  const char *nm = f->get_internal_name();  out1(0);  out_string(nm);}void dvi_printer::set_font(int i){  if (i >= 0 && i <= 63)    out1(fnt_num_0 + i);  else    out_unsigned(fnt1, i);}void dvi_printer::out_signed(unsigned char base, int param){  if (-128 <= param && param < 128) {    out1(base);    out1(param);  }  else if (-32768 <= param && param < 32768) {    out1(base+1);    out2(param);  }  else if (-(1 << 23) <= param && param < (1 << 23)) {    out1(base+2);    out3(param);  }  else {    out1(base+3);    out4(param);  }}void dvi_printer::out_unsigned(unsigned char base, int param){  if (param >= 0) {    if (param < 256) {      out1(base);      out1(param);    }    else if (param < 65536) {      out1(base+1);      out2(param);    }    else if (param < (1 << 24)) {      out1(base+2);      out3(param);    }    else {      out1(base+3);      out4(param);    }  }  else {    out1(base+3);    out4(param);  }}void dvi_printer::preamble(){  out1(pre);  out1(id_byte);  out4(254000);  out4(font::res);  out4(1000);  out1(0);}void dvi_printer::postamble(){  int tem = byte_count;  out1(post);  out4(last_bop);  out4(254000);  out4(font::res);  out4(1000);  out4(max_v);  out4(max_h);  out2(have_pushed); // stack depth  out2(page_count);  int i;  for (i = 0; i < FONTS_MAX && output_font_table[i].f != 0; i++)    define_font(i);  out1(post_post);  out4(tem);  out1(id_byte);  for (i = 0; i < 4 || byte_count % 4 != 0; i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -