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

📄 ps.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
  output_hpos(-1),  output_vpos(-1),  out(0, 79),  ndefined_styles(0),  next_encoding_index(0),  line_thickness(-1),  fill(FILL_MAX + 1),  ndefs(0),  invis_count(0){  tempfp = xtmpfile();  out.set_file(tempfp);  if (linewidth < 0)    linewidth = DEFAULT_LINEWIDTH;  if (font::hor != 1)    fatal("horizontal resolution must be 1");  if (font::vert != 1)    fatal("vertical resolution must be 1");  if (font::res % (font::sizescale*72) != 0)    fatal("res must be a multiple of 72*sizescale");  int r = font::res;  int point = 0;  while (r % 10 == 0) {    r /= 10;    point++;  }  res = r;  out.set_fixed_point(point);  space_char_index = font::name_to_index("space");  paper_length = font::paperlength;  if (paper_length == 0)    paper_length = 11*font::res;  equalise_spaces = font::res >= 72000;}int ps_printer::set_encoding_index(ps_font *f){  if (f->encoding_index >= 0)    return f->encoding_index;  for (font_pointer_list *p = font_list; p; p = p->next)    if (p->p != f) {      char *encoding = ((ps_font *)p->p)->encoding;      int encoding_index = ((ps_font *)p->p)->encoding_index;      if (encoding != 0 && encoding_index >= 0 	  && strcmp(f->encoding, encoding) == 0) {	return f->encoding_index = encoding_index;      }    }  return f->encoding_index = next_encoding_index++;}void ps_printer::set_char(int i, font *f, const environment *env, int w){  if (i == space_char_index || invis_count > 0)    return;  unsigned char code = f->get_code(i);  style sty(f, env->size, env->height, env->slant);  if (sty.slant != 0) {    if (sty.slant > 80 || sty.slant < -80) {      error("silly slant `%1' degrees", sty.slant);      sty.slant = 0;    }  }  if (sbuf_len > 0) {    if (sbuf_len < SBUF_SIZE	&& sty == sbuf_style	&& sbuf_vpos == env->vpos) {      if (sbuf_end_hpos == env->hpos) {	sbuf[sbuf_len++] = code;	sbuf_end_hpos += w + sbuf_kern;	return;      }      if (sbuf_len == 1 && sbuf_kern == 0) {	sbuf_kern = env->hpos - sbuf_end_hpos;	sbuf_end_hpos = env->hpos + sbuf_kern + w;	sbuf[sbuf_len++] = code;	return;      }      /* If sbuf_end_hpos - sbuf_kern == env->hpos, we are better off	 starting a new string. */      if (sbuf_len < SBUF_SIZE - 1 && env->hpos >= sbuf_end_hpos	  && (sbuf_kern == 0 || sbuf_end_hpos - sbuf_kern != env->hpos)) {	if (sbuf_space_code < 0) {	  if (f->contains(space_char_index)) {	    sbuf_space_code = f->get_code(space_char_index);	    sbuf_space_width = env->hpos - sbuf_end_hpos;	    sbuf_end_hpos = env->hpos + w + sbuf_kern;	    sbuf[sbuf_len++] = sbuf_space_code;	    sbuf[sbuf_len++] = code;	    sbuf_space_count++;	    return;	  }	}	else {	  int diff = env->hpos - sbuf_end_hpos - sbuf_space_width;	  if (diff == 0 || (equalise_spaces && (diff == 1 || diff == -1))) {	    sbuf_end_hpos = env->hpos + w + sbuf_kern;	    sbuf[sbuf_len++] = sbuf_space_code;	    sbuf[sbuf_len++] = code;	    sbuf_space_count++;	    if (diff == 1)	      sbuf_space_diff_count++;	    else if (diff == -1)	      sbuf_space_diff_count--;	    return;	  }	}      }    }    flush_sbuf();  }  sbuf_len = 1;  sbuf[0] = code;  sbuf_end_hpos = env->hpos + w;  sbuf_start_hpos = env->hpos;  sbuf_vpos = env->vpos;  sbuf_style = sty;  sbuf_space_code = -1;  sbuf_space_width = 0;  sbuf_space_count = sbuf_space_diff_count = 0;  sbuf_kern = 0;}int is_small_h(int n){  return n < (font::res*2)/72 && n > -(font::res*10)/72;}int is_small_v(int n){  return n < (font::res*4)/72 && n > -(font::res*4)/72;}static char *make_encoding_name(int encoding_index){  static char buf[3 + INT_DIGITS + 1];  sprintf(buf, "ENC%d", encoding_index);  return buf;}const char *const WS = " \t\n\r";void ps_printer::define_encoding(const char *encoding, int encoding_index){  char *vec[256];  for (int i = 0; i < 256; i++)    vec[i] = 0;  char *path;  FILE *fp = font::open_file(encoding, &path);  if (fp == 0)    fatal("can't open encoding file `%1'", encoding);  int lineno = 1;  char buf[256];  while (fgets(buf, 512, fp) != 0) {    char *p = buf;    while (isascii(*p) && isspace(*p))      p++;    if (*p != '#' && *p != '\0' && (p = strtok(buf, WS)) != 0) {      char *q = strtok(0, WS);      int n;      if (q == 0 || sscanf(q, "%d", &n) != 1 || n < 0 || n >= 256)	fatal_with_file_and_line(path, lineno, "bad second field");      vec[n] = new char[strlen(p) + 1];      strcpy(vec[n], p);    }    lineno++;  }  a_delete path;  out.put_literal_symbol(make_encoding_name(encoding_index));  out.put_delimiter('[');  for (i = 0; i < 256; i++) {    if (vec[i] == 0)      out.put_literal_symbol(".notdef");    else {      out.put_literal_symbol(vec[i]);      a_delete vec[i];    }  }  out.put_delimiter(']').put_symbol("def");}void ps_printer::reencode_font(ps_font *f){  out.put_literal_symbol(f->reencoded_name)     .put_symbol(make_encoding_name(f->encoding_index))     .put_literal_symbol(f->get_internal_name())     .put_symbol("RE");}void ps_printer::encode_fonts(){  if (next_encoding_index == 0)    return;  char *done_encoding = new char[next_encoding_index];  for (int i = 0; i < next_encoding_index; i++)    done_encoding[i] = 0;  for (font_pointer_list *f = font_list; f; f = f->next) {    int encoding_index = ((ps_font *)f->p)->encoding_index;    if (encoding_index >= 0) {      assert(encoding_index < next_encoding_index);      if (!done_encoding[encoding_index]) {	done_encoding[encoding_index] = 1;	define_encoding(((ps_font *)f->p)->encoding, encoding_index);      }      reencode_font((ps_font *)f->p);    }  }  a_delete done_encoding;}void ps_printer::set_style(const style &sty){  char buf[1 + INT_DIGITS + 1];  for (int i = 0; i < ndefined_styles; i++)    if (sty == defined_styles[i]) {      sprintf(buf, "F%d", i);      out.put_symbol(buf);      return;    }  if (ndefined_styles >= MAX_DEFINED_STYLES)    ndefined_styles = 0;  sprintf(buf, "F%d", ndefined_styles);  out.put_literal_symbol(buf);  const char *psname = sty.f->get_internal_name();  if (psname == 0)    fatal("no internalname specified for font `%1'", sty.f->get_name());  char *encoding = ((ps_font *)sty.f)->encoding;  if (encoding != 0) {    char *s = ((ps_font *)sty.f)->reencoded_name;    if (s == 0) {      int ei = set_encoding_index((ps_font *)sty.f);      char *tem = new char[strlen(psname) + 1 + INT_DIGITS + 1];      sprintf(tem, "%s@%d", psname, ei);      psname = tem;      ((ps_font *)sty.f)->reencoded_name = tem;    }    else      psname = s;  }  out.put_fix_number((font::res/(72*font::sizescale))*sty.point_size);  if (sty.height != 0 || sty.slant != 0) {    int h = sty.height == 0 ? sty.point_size : sty.height;    h *= font::res/(72*font::sizescale);    int c = int(h*tan(radians(sty.slant)) + .5);    out.put_fix_number(c).put_fix_number(h).put_literal_symbol(psname)       .put_symbol("MF");  }  else {    out.put_literal_symbol(psname).put_symbol("SF");  }  defined_styles[ndefined_styles++] = sty;}void ps_printer::set_space_code(unsigned char c){  out.put_literal_symbol("SC").put_number(c).put_symbol("def");}void ps_printer::end_of_line(){  flush_sbuf();  // this ensures that we do an absolute motion to the beginning of a line  output_vpos = output_hpos = -1;}void ps_printer::flush_sbuf(){  enum {    NONE,    RELATIVE_H,    RELATIVE_V,    RELATIVE_HV,    ABSOLUTE    } motion = NONE;  int space_flag = 0;  if (sbuf_len == 0)    return;  if (output_style != sbuf_style) {    set_style(sbuf_style);    output_style = sbuf_style;  }  int extra_space = 0;  if (output_hpos < 0 || output_vpos < 0      || !is_small_h(output_hpos - sbuf_start_hpos)      || !is_small_v(output_vpos - sbuf_vpos))    motion = ABSOLUTE;  else {    if (output_hpos != sbuf_start_hpos)      motion = RELATIVE_H;    if (output_vpos != sbuf_vpos) {      if  (motion != NONE)	motion = RELATIVE_HV;      else	motion = RELATIVE_V;    }  }  if (sbuf_space_code >= 0) {    int w = sbuf_style.f->get_width(space_char_index, sbuf_style.point_size);    if (w + sbuf_kern != sbuf_space_width) {      if (sbuf_space_code != output_space_code) {	set_space_code(sbuf_space_code);	output_space_code = sbuf_space_code;      }      space_flag = 1;      extra_space = sbuf_space_width - w - sbuf_kern;      if (sbuf_space_diff_count > sbuf_space_count/2)	extra_space++;      else if (sbuf_space_diff_count < -(sbuf_space_count/2))	extra_space--;    }  }  if (space_flag)    out.put_fix_number(extra_space);  if (sbuf_kern != 0)    out.put_fix_number(sbuf_kern);  out.put_string(sbuf, sbuf_len);  char sym[2];  sym[0] = 'A' + motion*4 + space_flag + 2*(sbuf_kern != 0);  sym[1] = '\0';  switch (motion) {  case NONE:    break;  case ABSOLUTE:    out.put_fix_number(sbuf_start_hpos)       .put_fix_number(sbuf_vpos);    break;  case RELATIVE_H:    out.put_fix_number(sbuf_start_hpos - output_hpos);    break;  case RELATIVE_V:    out.put_fix_number(sbuf_vpos - output_vpos);    break;  case RELATIVE_HV:    out.put_fix_number(sbuf_start_hpos - output_hpos)       .put_fix_number(sbuf_vpos - output_vpos);    break;  default:    assert(0);  }  out.put_symbol(sym);  output_hpos = sbuf_end_hpos;  output_vpos = sbuf_vpos;  sbuf_len = 0;}void ps_printer::set_line_thickness(const environment *env){  if (line_thickness < 0) {    if (output_draw_point_size != env->size) {      // we ought to check for overflow here      int lw = ((font::res/(72*font::sizescale))*linewidth*env->size)/1000;      out.put_fix_number(lw).put_symbol("LW");      output_draw_point_size = env->size;      output_line_thickness = -1;    }  }  else {    if (output_line_thickness != line_thickness) {      out.put_fix_number(line_thickness).put_symbol("LW");      output_line_thickness = line_thickness;      output_draw_point_size = -1;    }  }}void ps_printer::fill_path(){  if (fill > FILL_MAX)    out.put_symbol("BL");  else    out.put_float(transform_fill(fill)).put_symbol("FL");}void ps_printer::draw(int code, int *p, int np, const environment *env){  if (invis_count > 0)    return;  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;    }    out.put_fix_number(env->hpos + p[0]/2)       .put_fix_number(env->vpos)       .put_fix_number(p[0]/2)       .put_symbol("DC");    if (fill_flag) {      fill_path();    }    else {      set_line_thickness(env);      out.put_symbol("ST");    }    break;  case 'l':    if (np != 2) {      error("2 arguments required for line");      break;    }    set_line_thickness(env);    out.put_fix_number(p[0] + env->hpos)       .put_fix_number(p[1] + env->vpos)       .put_fix_number(env->hpos)       .put_fix_number(env->vpos)       .put_symbol("DL");    break;  case 'E':    fill_flag = 1;    // fall through  case 'e':    if (np != 2) {      error("2 arguments required for ellipse");      break;    }    out.put_fix_number(p[0])       .put_fix_number(p[1])       .put_fix_number(env->hpos + p[0]/2)       .put_fix_number(env->vpos)       .put_symbol("DE");    if (fill_flag) {      fill_path();    }    else {      set_line_thickness(env);      out.put_symbol("ST");    }    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;      }      out.put_fix_number(env->hpos)	 .put_fix_number(env->vpos)	 .put_symbol("MT");      for (int i = 0; i < np; i += 2)	out.put_fix_number(p[i])	   .put_fix_number(p[i+1])	   .put_symbol("RL");      out.put_symbol("CL");      if (fill_flag) {	fill_path();      }      else {	set_line_thickness(env);	out.put_symbol("ST");      }      break;    }  case '~':    {      if (np & 1) {	error("even number of arguments required for spline");	break;      }      if (np == 0) {	error("no arguments for spline");	break;      }      out.put_fix_number(env->hpos)	 .put_fix_number(env->vpos)	 .put_symbol("MT");      out.put_fix_number(p[0]/2)	 .put_fix_number(p[1]/2)	 .put_symbol("RL");      /* tnum/tden should be between 0 and 1; the closer it is to 1	 the tighter the curve will be to the guiding lines; 2/3	 is the standard value */      const int tnum = 2;      const int tden = 3;      for (int i = 0; i < np - 2; i += 2) {	out.put_fix_number((p[i]*tnum)/(2*tden))	   .put_fix_number((p[i + 1]*tnum)/(2*tden))	   .put_fix_number(p[i]/2 + (p[i + 2]*(tden - tnum))/(2*tden))	   .put_fix_number(p[i + 1]/2 + (p[i + 3]*(tden - tnum))/(2*tden))	   .put_fix_number((p[i] - p[i]/2) + p[i + 2]/2)	   .put_fix_number((p[i + 1] - p[i + 1]/2) + p[i + 3]/2)	   .put_symbol("RC");      }      out.put_fix_number(p[np - 2] - p[np - 2]/2)	 .put_fix_number(p[np - 1] - p[np - 1]/2)	 .put_symbol("RL");      set_line_thickness(env);      out.put_symbol("ST");    }    break;  case 'a':    {

⌨️ 快捷键说明

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