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

📄 env.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
  case TAB_NONE:    return;  case TAB_LEFT:    add_node(make_tab_node(d));    return;  case TAB_RIGHT:  case TAB_CENTER:    tab_width = 0;    tab_distance = d;    tab_contents = 0;    current_tab = t;    tab_field_spaces = 0;    return;  default:    assert(0);  }}void environment::start_field(){  assert(!current_field);  hunits d;  if (distance_to_next_tab(&d) != TAB_NONE) {    pre_field_width = get_text_length();    field_distance = d;    current_field = 1;    field_spaces = 0;    tab_field_spaces = 0;    for (node *p = line; p; p = p->next)      if (p->nspaces()) {	p->freeze_space();	space_total--;      }    tab_precedes_field = current_tab != TAB_NONE;  }  else    error("zero field width");}void environment::wrap_up_field(){  if (!current_tab && field_spaces == 0)    add_padding();  hunits padding = field_distance - (get_text_length() - pre_field_width);  if (current_tab && tab_field_spaces != 0) {    hunits tab_padding = scale(padding, 			       tab_field_spaces, 			       field_spaces + tab_field_spaces);    padding -= tab_padding;    distribute_space(tab_contents, tab_field_spaces, tab_padding, 1);    tab_field_spaces = 0;    tab_width += tab_padding;  }  if (field_spaces != 0) {    distribute_space(line, field_spaces, padding, 1);    width_total += padding;    if (current_tab) {      // the start of the tab has been moved to the right by padding, so      tab_distance -= padding;      if (tab_distance <= H0) {	// use the next tab stop instead	current_tab = tabs.distance_to_next_tab(get_input_line_position()						- tab_width,						&tab_distance);	if (current_tab == TAB_NONE || current_tab == TAB_LEFT) {	  width_total += tab_width;	  if (current_tab == TAB_LEFT) {	    line = make_tab_node(tab_distance, line);	    width_total += tab_distance;	    current_tab = TAB_NONE;	  }	  if (tab_contents != 0) {	    for (node *tem = tab_contents; tem->next != 0; tem = tem->next)	      ;	    tem->next = line;	    line = tab_contents;	    tab_contents = 0;	  }	  tab_width = H0;	  tab_distance = H0;	}      }    }  }  current_field = 0;}void environment::add_padding(){  if (current_tab) {    tab_contents = new space_node(H0, tab_contents);    tab_field_spaces++;  }  else {    if (line == 0)      start_line();    line = new space_node(H0, line);    field_spaces++;  }}typedef int (environment::*INT_FUNCP)();typedef vunits (environment::*VUNITS_FUNCP)();typedef hunits (environment::*HUNITS_FUNCP)();typedef const char *(environment::*STRING_FUNCP)();class int_env_reg : public reg {  INT_FUNCP func; public:  int_env_reg(INT_FUNCP);  const char *get_string();  int get_value(units *val);};class vunits_env_reg : public reg {  VUNITS_FUNCP func; public:  vunits_env_reg(VUNITS_FUNCP f);  const char *get_string();  int get_value(units *val);};class hunits_env_reg : public reg {  HUNITS_FUNCP func; public:  hunits_env_reg(HUNITS_FUNCP f);  const char *get_string();  int get_value(units *val);};class string_env_reg : public reg {  STRING_FUNCP func;public:  string_env_reg(STRING_FUNCP);  const char *get_string();};int_env_reg::int_env_reg(INT_FUNCP f) : func(f){}int int_env_reg::get_value(units *val){  *val = (curenv->*func)();  return 1;}const char *int_env_reg::get_string(){  return itoa((curenv->*func)());} vunits_env_reg::vunits_env_reg(VUNITS_FUNCP f) : func(f){}int vunits_env_reg::get_value(units *val){  *val = (curenv->*func)().to_units();  return 1;}const char *vunits_env_reg::get_string(){  return itoa((curenv->*func)().to_units());}hunits_env_reg::hunits_env_reg(HUNITS_FUNCP f) : func(f){}int hunits_env_reg::get_value(units *val){  *val = (curenv->*func)().to_units();  return 1;}const char *hunits_env_reg::get_string(){  return itoa((curenv->*func)().to_units());}string_env_reg::string_env_reg(STRING_FUNCP f) : func(f){}const char *string_env_reg::get_string(){  return (curenv->*func)();}class horizontal_place_reg : public general_reg {public:  horizontal_place_reg();  int get_value(units *);  void set_value(units);};horizontal_place_reg::horizontal_place_reg(){}int horizontal_place_reg::get_value(units *res){  *res = curenv->get_input_line_position().to_units();  return 1;}void horizontal_place_reg::set_value(units n){  curenv->set_input_line_position(hunits(n));}const char *environment::get_font_family_string(){  return family->nm.contents();}const char *environment::get_name_string(){  return name.contents();}// Convert a quantity in scaled points to ascii decimal fraction.const char *sptoa(int sp){  assert(sp > 0);  assert(sizescale > 0);  if (sizescale == 1)    return itoa(sp);  if (sp % sizescale == 0)    return itoa(sp/sizescale);  // See if 1/sizescale is exactly representable as a decimal fraction,  // ie its only prime factors are 2 and 5.  int n = sizescale;  int power2 = 0;  while ((n & 1) == 0) {    n >>= 1;    power2++;  }  int power5 = 0;  while ((n % 5) == 0) {    n /= 5;    power5++;  }  if (n == 1) {    int decimal_point = power5 > power2 ? power5 : power2;    if (decimal_point <= 10) {      int factor = 1;      int t;      for (t = decimal_point - power2; --t >= 0;)	factor *= 2;      for (t = decimal_point - power5; --t >= 0;)	factor *= 5;      if (factor == 1 || sp <= INT_MAX/factor)	return iftoa(sp*factor, decimal_point);    }  }  double s = double(sp)/double(sizescale);  double factor = 10.0;  double val = s;  int decimal_point = 0;  do  {    double v = ceil(s*factor);    if (v > INT_MAX)      break;    val = v;    factor *= 10.0;  } while (++decimal_point < 10);  return iftoa(int(val), decimal_point);}const char *environment::get_point_size_string(){  return sptoa(curenv->get_point_size());}const char *environment::get_requested_point_size_string(){  return sptoa(curenv->get_requested_point_size());}#define init_int_env_reg(name, func) \  number_reg_dictionary.define(name, new int_env_reg(&environment::func))#define init_vunits_env_reg(name, func) \  number_reg_dictionary.define(name, new vunits_env_reg(&environment::func))#define init_hunits_env_reg(name, func) \  number_reg_dictionary.define(name, new hunits_env_reg(&environment::func))#define init_string_env_reg(name, func) \  number_reg_dictionary.define(name, new string_env_reg(&environment::func))void init_env_requests(){  init_request("it", input_trap);  init_request("ad", adjust);  init_request("na", no_adjust);  init_request("ev", environment_switch);  init_request("lt", title_length);  init_request("ps", point_size);  init_request("ft", font_change);  init_request("fam", family_change);  init_request("ss", space_size);  init_request("fi", fill);  init_request("nf", no_fill);  init_request("ce", center);  init_request("rj", right_justify);  init_request("vs", vertical_spacing);  init_request("ls", line_spacing);  init_request("ll", line_length);  init_request("in", indent);  init_request("ti", temporary_indent);  init_request("ul", underline);  init_request("cu", underline);  init_request("cc", control_char);  init_request("c2", no_break_control_char);  init_request("br", break_request);  init_request("tl", title);  init_request("ta", set_tabs);  init_request("fc", field_characters);  init_request("mc", margin_character);  init_request("nn", no_number);  init_request("nm", number_lines);  init_request("tc", tab_character);  init_request("lc", leader_character);  init_request("hy", hyphenate_request);  init_request("hc", hyphen_char);  init_request("nh", no_hyphenate);  init_request("hlm", hyphen_line_max_request);#ifdef WIDOW_CONTROL  init_request("wdc", widow_control_request);#endif /* WIDOW_CONTROL */#if 0  init_request("tas", tabs_save);  init_request("tar", tabs_restore);#endif    init_request("hys", hyphenation_space_request);  init_request("hym", hyphenation_margin_request);  init_int_env_reg(".f", get_font);  init_int_env_reg(".b", get_bold);  init_hunits_env_reg(".i", get_indent);  init_hunits_env_reg(".in", get_saved_indent);  init_int_env_reg(".j", get_adjust_mode);  init_hunits_env_reg(".k", get_text_length);  init_hunits_env_reg(".l", get_line_length);  init_hunits_env_reg(".ll", get_saved_line_length);  init_int_env_reg(".L", get_line_spacing);  init_hunits_env_reg(".n", get_prev_text_length);  init_string_env_reg(".s", get_point_size_string);  init_string_env_reg(".sr", get_requested_point_size_string);  init_int_env_reg(".ps", get_point_size);  init_int_env_reg(".psr", get_requested_point_size);  init_int_env_reg(".u", get_fill);  init_vunits_env_reg(".v", get_vertical_spacing);  init_hunits_env_reg(".w", get_prev_char_width);  init_int_env_reg(".ss", get_space_size);  init_int_env_reg(".sss", get_sentence_space_size);  init_string_env_reg(".fam", get_font_family_string);  init_string_env_reg(".ev", get_name_string);  init_int_env_reg(".hy", get_hyphenation_flags);  init_int_env_reg(".hlm", get_hyphen_line_max);  init_int_env_reg(".hlc", get_hyphen_line_count);  init_hunits_env_reg(".lt", get_title_length);  init_string_env_reg(".tabs", get_tabs);  init_hunits_env_reg(".csk", get_prev_char_skew);  init_vunits_env_reg(".cht", get_prev_char_height);  init_vunits_env_reg(".cdp", get_prev_char_depth);  init_int_env_reg(".ce", get_center_lines);  init_int_env_reg(".rj", get_right_justify_lines);  init_hunits_env_reg(".hys", get_hyphenation_space);  init_hunits_env_reg(".hym", get_hyphenation_margin);  number_reg_dictionary.define("ln", new variable_reg(&next_line_number));  number_reg_dictionary.define("ct", new variable_reg(&ct_reg_contents));  number_reg_dictionary.define("sb", new variable_reg(&sb_reg_contents));  number_reg_dictionary.define("st", new variable_reg(&st_reg_contents));  number_reg_dictionary.define("rsb", new variable_reg(&rsb_reg_contents));  number_reg_dictionary.define("rst", new variable_reg(&rst_reg_contents));  number_reg_dictionary.define("ssc", new variable_reg(&ssc_reg_contents));  number_reg_dictionary.define("skw", new variable_reg(&skw_reg_contents));  number_reg_dictionary.define("hp", new horizontal_place_reg);}// Hyphenation - TeX's hyphenation algorithm with a less fancy implementation.struct trie_node;class trie {  trie_node *tp;  virtual void do_match(int len, void *val) = 0;  virtual void do_delete(void *) = 0;  void delete_trie_node(trie_node *);public:  trie() : tp(0) {}  virtual ~trie();		// virtual to shut up g++  void insert(const char *, int, void *);  // find calls do_match for each match it finds  void find(const char *pat, int patlen);  void clear();};class hyphen_trie : private trie {  int *h;  void do_match(int i, void *v);  void do_delete(void *v);  void insert_pattern(const char *pat, int patlen, int *num);public:  hyphen_trie() {}  ~hyphen_trie() {}  void hyphenate(const char *word, int len, int *hyphens);  void read_patterns_file(const char *name);};struct hyphenation_language {  symbol name;  dictionary exceptions;  hyphen_trie patterns;  hyphenation_language(symbol nm) : name(nm), exceptions(501) {}  ~hyphenation_language() { }};dictionary language_dictionary(5);hyphenation_language *current_language = 0;static void set_hyphenation_language(){  symbol nm = get_name(1);  if (!nm.is_null()) {    current_language = (hyphenation_language *)language_dictionary.lookup(nm);    if (!current_language) {      current_language = new hyphenation_language(nm);      (void)language_dictionary.lookup(nm, (void *)current_language);    }  }  skip_line();}const int WORD_MAX = 1024;static void hyphen_word(){  if (!current_language) {    error("no current hyphenation language");    skip_line();    return;  }  char buf[WORD_MAX + 1];  unsigned char pos[WORD_MAX + 2];  for (;;) {    tok.skip();    if (tok.newline() || tok.eof())      break;    int i = 0;    int npos = 0;    while (i < WORD_MAX && !tok.space() && !tok.newline() && !tok.eof()) {      charinfo *ci = tok.get_char(1);      if (ci == 0) {	skip_line();	return;      }      tok.next();      if (ci->get_ascii_code() == '-') {	if (i > 0 && (npos == 0 || pos[npos - 1] != i))	  pos[npos++] = i;      }      else {	int c = ci->get_hyphenation_code();	if (c == 0)	  break;	buf[i++] = c;      }    }    if (i > 0) {      pos[npos] = 0;      buf[i] = 0;      unsigned char *tem = new unsigned char[npos + 1];      memcpy(tem, pos, npos+1);      tem = (unsigned char *)current_language->exceptions.lookup(symbol(buf),								 tem);      if (tem)	a_delete tem;    }  }  skip_line();}struct trie_node {  char c;  trie_node *down;  trie_node *right;  void *val;  trie_node(char, trie_node *);};trie_node::trie_node(char ch, trie_node *p) : c(ch), right(p), down(0), val(0){}trie::~trie(){  clear();}void trie::clear(){  delete_trie_node(tp);  tp = 0;}void trie::delete_trie_node(trie_node *p){  if (p) {    delete_trie_node(p->down);    delete_trie_node(p->right);    if (p->val)      do_delete(p->val);    delete p;  }}void trie::insert(const char *pat, int patlen, void *val){  trie_node **p = &tp;  assert(patlen > 0 && pat != 0);  for (;;) {    while (*p != 0 && (*p)->c < pat[0])      p = &((*p)->right);    if (*p == 0 || (*p)->c != pat[0])      *p = new trie_node(pat[0], *p);    if (--patlen == 0) {      (*p)->val = val;      break;    }    ++pat;    p = &((*p)->down);  }}void trie::find(const char *pat, int patlen){  trie_node *p = tp;  for (int i = 0; p != 0 && i < patlen; i++) {    while (p != 0 && p->c < pat[i])      p = p->right;    if (p != 0 && p->c == pat[i]) {      if (p->val != 0)	do_match(i+1, p->val);      p = p->down;    }    else      break;  }}struct operation {  operation *next;  short distance;  short num;  operation(int, int, operation *);};operation::operation(int i, int j, operation *op): num(i), distance(j), next(op){}void hyphen_trie::insert_pattern(const char *pat, int patlen, int *num){  operation *op = 0;  for (int i = 0; i < patlen+1; i++)    if

⌨️ 快捷键说明

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