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

📄 env.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
    if (tok.ch() == 0)      error("bad control character");    else      curenv->control_char = tok.ch();  }  skip_line();}void no_break_control_char(){  curenv->no_break_control_char = '\'';  if (has_arg()) {    if (tok.ch() == 0)      error("bad control character");    else      curenv->no_break_control_char = tok.ch();  }  skip_line();}void margin_character(){  charinfo *ci = get_optional_char();  if (ci) {    node *nd = curenv->make_char_node(ci);    if (nd) {      delete curenv->margin_character_node;      curenv->margin_character_node = nd;      curenv->margin_character_flags = (MARGIN_CHARACTER_ON					|MARGIN_CHARACTER_NEXT);      hunits d;      if (has_arg() && get_hunits(&d, 'm'))	curenv->margin_character_distance = d;    }  }  else {    curenv->margin_character_flags &= ~MARGIN_CHARACTER_ON;    if (curenv->margin_character_flags == 0) {      delete curenv->margin_character_node;      curenv->margin_character_node = 0;    }  }  skip_line();}void number_lines(){  delete_node_list(curenv->numbering_nodes);  curenv->numbering_nodes = 0;  if (has_arg()) {    node *nd = 0;    for (int i = '9'; i >= '0'; i--) {      node *tem = make_node(charset_table[i], curenv);      if (!tem) {	skip_line();	return;      }      tem->next = nd;      nd = tem;    }    curenv->numbering_nodes = nd;    curenv->line_number_digit_width = env_digit_width(curenv);    int n;    if (!tok.delimiter()) {      if (get_integer(&n, next_line_number)) {	next_line_number = n;	if (next_line_number < 0) {	  warning(WARN_RANGE, "negative line number");	  next_line_number = 0;	}      }    }    else      while (!tok.space() && !tok.newline() && !tok.eof())	tok.next();    if (has_arg()) {      if (!tok.delimiter()) {	if (get_integer(&n)) {	  if (n <= 0) {	    warning(WARN_RANGE, "negative or zero line number multiple");	  }	  else	    curenv->line_number_multiple = n;	}      }      else	while (!tok.space() && !tok.newline() && !tok.eof())	  tok.next();      if (has_arg()) {	if (!tok.delimiter()) {	  if (get_integer(&n))	    curenv->number_text_separation = n;	}	else	  while (!tok.space() && !tok.newline() && !tok.eof())	    tok.next();	if (has_arg() && !tok.delimiter() && get_integer(&n))	  curenv->line_number_indent = n;      }    }  }  skip_line();}void no_number(){  int n;  if (has_arg() && get_integer(&n))    curenv->no_number_count = n > 0 ? n : 0;  else    curenv->no_number_count = 1;  skip_line();}void no_hyphenate(){  curenv->hyphenation_flags = 0;  skip_line();}void hyphenate_request(){  int n;  if (has_arg() && get_integer(&n))    curenv->hyphenation_flags = n;  else    curenv->hyphenation_flags = 1;  skip_line();}void hyphen_char(){  curenv->hyphen_indicator_char = get_optional_char();  skip_line();}void hyphen_line_max_request(){  int n;  if (has_arg() && get_integer(&n))    curenv->hyphen_line_max = n;  else    curenv->hyphen_line_max = -1;  skip_line();}void environment::interrupt(){  if (!dummy) {    add_node(new transparent_dummy_node);    interrupted = 1;  }}void environment::newline(){  if (underline_lines > 0) {    if (--underline_lines == 0) {      prev_fontno = fontno;      fontno = pre_underline_fontno;    }  }  if (current_field)    wrap_up_field();  if (current_tab)    wrap_up_tab();  // strip trailing spaces  while (line != 0 && line->discardable()) {    width_total -= line->width();    space_total -= line->nspaces();    node *tem = line;    line = line->next;    delete tem;  }  node *to_be_output = 0;  hunits to_be_output_width;  prev_line_interrupted = 0;  if (dummy)    space_newline();  else if (interrupted) {    interrupted = 0;    // see environment::final_break    prev_line_interrupted = exit_started ? 2 : 1;  }  else if (center_lines > 0) {    --center_lines;    hunits x = target_text_length - width_total;    if (x > H0)      saved_indent += x/2;    to_be_output = line;    to_be_output_width = width_total;    line = 0;  }  else if (right_justify_lines > 0) {    --right_justify_lines;    hunits x = target_text_length - width_total;    if (x > H0)      saved_indent += x;    to_be_output = line;    to_be_output_width = width_total;    line = 0;  }  else if (fill)    space_newline();  else {    to_be_output = line;    to_be_output_width = width_total;    line = 0;  }  input_line_start = line == 0 ? H0 : width_total;  if (to_be_output) {    output_line(to_be_output, to_be_output_width);    hyphen_line_count = 0;  }  if (input_trap_count > 0) {    if (--input_trap_count == 0)      spring_trap(input_trap);  }}void environment::output_line(node *n, hunits width){  prev_text_length = width;  if (margin_character_flags) {    hunits d = line_length + margin_character_distance - saved_indent - width;    if (d > 0) {      n = new hmotion_node(d, n);      width += d;    }    margin_character_flags &= ~MARGIN_CHARACTER_NEXT;    node *tem;    if (!margin_character_flags) {      tem = margin_character_node;      margin_character_node = 0;    }    else      tem = margin_character_node->copy();    tem->next = n;    n = tem;    width += tem->width();  }  node *nn = 0;  while (n != 0) {    node *tem = n->next;    n->next = nn;    nn = n;    n = tem;  }  if (!saved_indent.is_zero())    nn = new hmotion_node(saved_indent, nn);  width += saved_indent;  if (no_number_count > 0)    --no_number_count;  else if (numbering_nodes) {    hunits w = (line_number_digit_width		*(3+line_number_indent+number_text_separation));    if (next_line_number % line_number_multiple != 0)      nn = new hmotion_node(w, nn);    else {      hunits x = w;      nn = new hmotion_node(number_text_separation*line_number_digit_width,			    nn);      x -= number_text_separation*line_number_digit_width;      char buf[30];      sprintf(buf, "%3d", next_line_number);      for (char *p = strchr(buf, '\0') - 1; p >= buf && *p != ' '; --p) {	node *gn = numbering_nodes;	for (int count = *p - '0'; count > 0; count--)	  gn = gn->next;	gn = gn->copy();	x -= gn->width();	gn->next = nn;	nn = gn;      }      nn = new hmotion_node(x, nn);    }    width += w;    ++next_line_number;  }  output(nn, !fill, vertical_spacing, line_spacing, width);}void environment::start_line(){  assert(line == 0);  discarding = 0;  line = new line_start_node;  if (have_temporary_indent) {    saved_indent = temporary_indent;    have_temporary_indent = 0;  }  else    saved_indent = indent;  target_text_length = line_length - saved_indent;  width_total = H0;  space_total = 0;}hunits environment::get_hyphenation_space(){  return hyphenation_space;}void hyphenation_space_request(){  hunits n;  if (get_hunits(&n, 'm')) {    if (n < H0) {      warning(WARN_RANGE, "hyphenation space cannot be negative");      n = H0;    }    curenv->hyphenation_space = n;  }  skip_line();}hunits environment::get_hyphenation_margin(){  return hyphenation_margin;}void hyphenation_margin_request(){  hunits n;  if (get_hunits(&n, 'm')) {    if (n < H0) {      warning(WARN_RANGE, "hyphenation margin cannot be negative");      n = H0;    }    curenv->hyphenation_margin = n;  }  skip_line();}breakpoint *environment::choose_breakpoint(){  hunits x = width_total;  int s = space_total;  node *n = line;  breakpoint *best_bp = 0;	// the best breakpoint so far  int best_bp_fits = 0;  while (n != 0) {    x -= n->width();    s -= n->nspaces();    breakpoint *bp = n->get_breakpoints(x, s);    while (bp != 0) {      if (bp->width <= target_text_length) {	if (!bp->hyphenated) {	  breakpoint *tem = bp->next;	  bp->next = 0;	  while (tem != 0) {	    breakpoint *tem1 = tem;	    tem = tem->next;	    delete tem1;	  }	  if (best_bp_fits	      // Decide whether to use the hyphenated breakpoint.	      && (hyphen_line_max < 0		  // Only choose the hyphenated breakpoint if it would not		  // exceed the maximum number of consecutive hyphenated		  // lines.		  || hyphen_line_count + 1 <= hyphen_line_max)	      && !(adjust_mode == ADJUST_BOTH		   // Don't choose the hyphenated breakpoint if the line		   // can be justified by adding no more than		   // hyphenation_space to any word space.		   ? (bp->nspaces > 0		      && (((target_text_length - bp->width			    + (bp->nspaces - 1)*hresolution)/bp->nspaces)			  <= hyphenation_space))		   // Don't choose the hyphenated breakpoint if the line		   // is no more than hyphenation_margin short.		   : target_text_length - bp->width <= hyphenation_margin)) {	    delete bp;	    return best_bp;	  }	  if (best_bp)	    delete best_bp;	  return bp;	}	else {	  if ((adjust_mode == ADJUST_BOTH	       ? hyphenation_space == H0	       : hyphenation_margin == H0)	      && (hyphen_line_max < 0		  || hyphen_line_count + 1 <= hyphen_line_max)) {	    // No need to consider a non-hyphenated breakpoint.	    if (best_bp)	      delete best_bp;	    return bp;	  }	  // It fits but it's hyphenated.	  if (!best_bp_fits) {	    if (best_bp)	      delete best_bp;	    best_bp = bp;	    bp = bp->next;	    best_bp_fits = 1;	  }	  else {	    breakpoint *tem = bp;	    bp = bp->next;	    delete tem;	  }	}      }      else {	if (best_bp)	  delete best_bp;	best_bp = bp;	bp = bp->next;      }    }    n = n->next;  }  if (best_bp) {    if (!best_bp_fits)      warning(WARN_BREAK, "can't break line");    return best_bp;  }  return 0;}void environment::hyphenate_line(){  if (line == 0)    return;  hyphenation_type prev_type = line->get_hyphenation_type();  for (node **startp = &line->next; *startp != 0; startp = &(*startp)->next) {    hyphenation_type this_type = (*startp)->get_hyphenation_type();    if (prev_type == HYPHEN_BOUNDARY && this_type == HYPHEN_MIDDLE)      break;    prev_type = this_type;  }  if (*startp == 0)    return;  node *tem = *startp;  int i = 0;  do {    ++i;    tem = tem->next;  } while (tem != 0 && tem->get_hyphenation_type() == HYPHEN_MIDDLE);  int inhibit = (tem != 0 && tem->get_hyphenation_type() == HYPHEN_INHIBIT);  node *end = tem;  hyphen_list *sl = 0;  tem = *startp;  node *forward = 0;  while (tem != end) {    sl = tem->get_hyphen_list(sl);    node *tem1 = tem;    tem = tem->next;    tem1->next = forward;    forward = tem1;  }  if (!inhibit) {    // this is for characters like hyphen and emdash    int prev_code = 0;    for (hyphen_list *h = sl; h; h = h->next) {      h->breakable = (prev_code != 0		      && h->next != 0		      && h->next->hyphenation_code != 0);      prev_code = h->hyphenation_code;    }  }  if (hyphenation_flags != 0      && !inhibit      // this may not be right if we have extra space on this line      && !((hyphenation_flags & HYPHEN_LAST_LINE)	   && curdiv->distance_to_next_trap() <= line_spacing*vertical_spacing)      && i >= 4)    hyphenate(sl, hyphenation_flags);  while (forward != 0) {    node *tem1 = forward;    forward = forward->next;    tem1->next = 0;    tem = tem1->add_self(tem, &sl);  }  *startp = tem;}static node *node_list_reverse(node *n){  node *res = 0;  while (n) {    node *tem = n;    n = n->next;    tem->next = res;    res = tem;  }  return res;}static void distribute_space(node *n, int nspaces, hunits desired_space,			     int force_reverse = 0){  static int reverse = 0;  if (force_reverse || reverse)    n = node_list_reverse(n);  for (node *tem = n; tem; tem = tem->next)    tem->spread_space(&nspaces, &desired_space);  if (force_reverse || reverse)    (void)node_list_reverse(n);  if (!force_reverse)    reverse = !reverse;  assert(desired_space.is_zero() && nspaces == 0);}void environment::possibly_break_line(int forced){  if (!fill || current_tab || current_field || dummy)    return;  while (line != 0 && (forced || width_total > target_text_length)) {    hyphenate_line();    breakpoint *bp = choose_breakpoint();    if (bp == 0)      // we'll find one eventually      return;    node *pre, *post;    node **ndp = &line;    while (*ndp != bp->nd)      ndp = &(*ndp)->next;    bp->nd->split(bp->index, &pre, &post);    *ndp = post;    hunits extra_space_width = H0;    switch(adjust_mode) {    case ADJUST_BOTH:      if (bp->nspaces != 0)	extra_space_width = target_text_length - bp->width;      break;    case ADJUST_CENTER:      saved_indent += (target_text_length - bp->width)/2;      break;    case ADJUST_RIGHT:      saved_indent += target_text_length - bp->width;      break;    }    distribute_space(pre, bp->nspaces, extra_space_width);    hunits output_width = bp->width + extra_space_width;    input_line_start -= output_width;    if (bp->hyphenated)      hyphen_line_count++;    else      hyphen_line_count = 0;    delete bp;    space_total = 0;    width_total = 0;    node *first_non_discardable = 0;    for (node *tem = line; tem != 0; tem = tem->next)      if (!tem->discardable())	first_non_discardable = tem;    node *to_be_discarded;    if (first_non_discardable) {      to_be_discarded = first_non_discardable->next;      first_non_discardable->next = 0;      for (tem = line; tem != 0; tem = tem->next) {	width_total += tem->width();	space_total += tem->nspaces();      }      discarding = 0;    }    else {      discarding = 1;      to_be_discarded = line;      line = 0;    }    // Do output_line() here so that line will be 0 iff the    // the environment will be empty.    output_line(pre, output_width);    while (to_be_discarded != 0) {      tem = to_be_discarded;      to_be_discarded = to_be_discarded->next;      input_line_start -= tem->width();      delete tem;    }    if (line != 0) {      if (have_temporary_indent) {	saved_indent = temporary_indent;	have_temporary_indent = 0;      }      else

⌨️ 快捷键说明

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