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

📄 node.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 5 页
字号:
// -*- 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 "troff.h"#include "symbol.h"#include "dictionary.h"#include "hvunits.h"#include "env.h"#include "request.h"#include "node.h"#include "token.h"#include "charinfo.h"#include "font.h"#include "reg.h"#define STORE_WIDTH 1symbol HYPHEN_SYMBOL("hy");// Character used when a hyphen is inserted at a line break.static charinfo *soft_hyphen_char;enum constant_space_type {   CONSTANT_SPACE_NONE,  CONSTANT_SPACE_RELATIVE,  CONSTANT_SPACE_ABSOLUTE  };struct special_font_list {  int n;  special_font_list *next;};special_font_list *global_special_fonts;static int global_ligature_mode = 1;static int global_kern_mode = 1;class track_kerning_function {  int non_zero;  units min_size;  hunits min_amount;  units max_size;  hunits max_amount;public:  track_kerning_function();  track_kerning_function(units, hunits, units, hunits);  int operator==(const track_kerning_function &);  int operator!=(const track_kerning_function &);  hunits compute(int point_size);};// embolden fontno when this is the current fontstruct conditional_bold {  conditional_bold *next;  int fontno;  hunits offset;  conditional_bold(int, hunits, conditional_bold * = 0);};struct tfont;class font_info {  tfont *last_tfont;  int number;  font_size last_size;  int last_height;  int last_slant;  symbol internal_name;  symbol external_name;  font *fm;  char is_bold;  hunits bold_offset;  track_kerning_function track_kern;  constant_space_type is_constant_spaced;  units constant_space;  int last_ligature_mode;  int last_kern_mode;  conditional_bold *cond_bold_list;  void flush();public:  special_font_list *sf;    font_info(symbol nm, int n, symbol enm, font *f);  int contains(charinfo *);  void set_bold(hunits);  void unbold();  void set_conditional_bold(int, hunits);  void conditional_unbold(int);  void set_track_kern(track_kerning_function &);  void set_constant_space(constant_space_type, units = 0);  int is_named(symbol);  symbol get_name();  tfont *get_tfont(font_size, int, int, int);  hunits get_space_width(font_size, int);  hunits get_narrow_space_width(font_size);  hunits get_half_narrow_space_width(font_size);  int get_bold(hunits *);  int is_special();  int is_style();};class tfont_spec {protected:  symbol name;  int input_position;  font *fm;  font_size size;  char is_bold;  char is_constant_spaced;  int ligature_mode;  int kern_mode;  hunits bold_offset;  hunits track_kern;			// add this to the width  hunits constant_space_width;  int height;  int slant;public:  tfont_spec(symbol nm, int pos, font *, font_size, int, int);  tfont_spec plain();  int operator==(const tfont_spec &);  friend tfont *font_info::get_tfont(font_size fs, int, int, int);};class tfont : public tfont_spec {  static tfont *tfont_list;  tfont *next;  tfont *plain_version;public:  tfont(tfont_spec &);  int contains(charinfo *);  hunits get_width(charinfo *c);  int get_bold(hunits *);  int get_constant_space(hunits *);  hunits get_track_kern();  tfont *get_plain();  font_size get_size();  symbol get_name();  charinfo *get_lig(charinfo *c1, charinfo *c2);  int get_kern(charinfo *c1, charinfo *c2, hunits *res);  int get_input_position();  int get_character_type(charinfo *);  int get_height();  int get_slant();  vunits get_char_height(charinfo *);  vunits get_char_depth(charinfo *);  hunits get_char_skew(charinfo *);  hunits get_italic_correction(charinfo *);  hunits get_left_italic_correction(charinfo *);  hunits get_subscript_correction(charinfo *);  friend tfont *make_tfont(tfont_spec &);};inline int env_definite_font(environment *env){  return env->get_family()->make_definite(env->get_font());}static void invalidate_fontno(int n);/* font_info functions */static font_info **font_table = 0;static int font_table_size = 0;font_info::font_info(symbol nm, int n, symbol enm, font *f): internal_name(nm), external_name(enm), fm(f), number(n),  is_constant_spaced(CONSTANT_SPACE_NONE),  sf(0), is_bold(0), cond_bold_list(0),  last_ligature_mode(1), last_kern_mode(1),  last_tfont(0), last_size(0){}inline int font_info::contains(charinfo *ci){  return fm != 0 && fm->contains(ci->get_index());}inline int font_info::is_special(){  return fm != 0 && fm->is_special();}inline int font_info::is_style(){  return fm == 0;}// this is the current_font, fontno is where we found the character,// presumably a special fonttfont *font_info::get_tfont(font_size fs, int height, int slant, int fontno){  if (last_tfont == 0 || fs != last_size      || height != last_height || slant != last_slant      || global_ligature_mode != last_ligature_mode      || global_kern_mode != last_kern_mode      || fontno != number) {	font_info *f = font_table[fontno];	tfont_spec spec(f->external_name, f->number, f->fm, fs, height, slant);	for (conditional_bold *p = cond_bold_list; p; p = p->next)	  if (p->fontno == fontno) {	    spec.is_bold = 1;	    spec.bold_offset = p->offset;	    break;	  }	if (!spec.is_bold && is_bold) {	  spec.is_bold = 1;	  spec.bold_offset = bold_offset;	}	spec.track_kern = track_kern.compute(fs.to_scaled_points());	spec.ligature_mode = global_ligature_mode;	spec.kern_mode = global_kern_mode;	switch (is_constant_spaced) {	case CONSTANT_SPACE_NONE:	  break;	case CONSTANT_SPACE_ABSOLUTE:	  spec.is_constant_spaced = 1;	  spec.constant_space_width = constant_space;	  break;	case CONSTANT_SPACE_RELATIVE:	  spec.is_constant_spaced = 1;	  spec.constant_space_width	    = scale(constant_space*fs.to_scaled_points(),		    units_per_inch,		    36*72*sizescale);	  break;	default:	  assert(0);	}	if (fontno != number)	  return make_tfont(spec);	last_tfont = make_tfont(spec);	last_size = fs;	last_height = height;	last_slant = slant;	last_ligature_mode = global_ligature_mode;	last_kern_mode = global_kern_mode;      }  return last_tfont;}int font_info::get_bold(hunits *res){  if (is_bold) {    *res = bold_offset;    return 1;  }  else    return 0;}void font_info::unbold(){  if (is_bold) {    is_bold = 0;    flush();  }}void font_info::set_bold(hunits offset){  if (!is_bold || offset != bold_offset) {    is_bold = 1;    bold_offset = offset;    flush();  }}void font_info::set_conditional_bold(int fontno, hunits offset){  for (conditional_bold *p = cond_bold_list; p; p = p->next)    if (p->fontno == fontno) {      if (offset != p->offset) {	p->offset = offset;	flush();      }      return;    }  cond_bold_list = new conditional_bold(fontno, offset, cond_bold_list);}conditional_bold::conditional_bold(int f, hunits h, conditional_bold *x)     : fontno(f), offset(h), next(x){}void font_info::conditional_unbold(int fontno){  for (conditional_bold **p = &cond_bold_list; *p; p = &(*p)->next)    if ((*p)->fontno == fontno) {      conditional_bold *tem = *p;      *p = (*p)->next;      delete tem;      flush();      return;    }}				 void font_info::set_constant_space(constant_space_type type, units x){  if (type != is_constant_spaced      || (type != CONSTANT_SPACE_NONE && x != constant_space)) {	flush();	is_constant_spaced = type;	constant_space = x;      }}void font_info::set_track_kern(track_kerning_function  &tk){  if (track_kern != tk) {    track_kern = tk;    flush();  }}void font_info::flush(){  last_tfont = 0;}int font_info::is_named(symbol s){  return internal_name == s;}symbol font_info::get_name(){  return internal_name;}hunits font_info::get_space_width(font_size fs, int space_size){  if (is_constant_spaced == CONSTANT_SPACE_NONE)    return scale(hunits(fm->get_space_width(fs.to_scaled_points())),			space_size, 12);  else if (is_constant_spaced == CONSTANT_SPACE_ABSOLUTE)    return constant_space;  else    return scale(constant_space*fs.to_scaled_points(),		 units_per_inch, 36*72*sizescale);}hunits font_info::get_narrow_space_width(font_size fs){  charinfo *ci = get_charinfo(symbol("|"));  if (fm->contains(ci->get_index()))    return hunits(fm->get_width(ci->get_index(), fs.to_scaled_points()));  else    return hunits(fs.to_units()/6);}hunits font_info::get_half_narrow_space_width(font_size fs){  charinfo *ci = get_charinfo(symbol("^"));  if (fm->contains(ci->get_index()))    return hunits(fm->get_width(ci->get_index(), fs.to_scaled_points()));  else    return hunits(fs.to_units()/12);}/* tfont */tfont_spec::tfont_spec(symbol nm, int n, font *f, 		       font_size s, int h, int sl)     : name(nm), input_position(n), fm(f), size(s),     is_bold(0), is_constant_spaced(0), ligature_mode(1), kern_mode(1),     height(h), slant(sl){  if (height == size.to_scaled_points())    height = 0;}int tfont_spec::operator==(const tfont_spec &spec){  if (fm == spec.fm       && size == spec.size      && input_position == spec.input_position      && name == spec.name      && height == spec.height      && slant == spec.slant      && (is_bold 	  ? (spec.is_bold && bold_offset == spec.bold_offset)	  : !spec.is_bold)      && track_kern == spec.track_kern      && (is_constant_spaced	  ? (spec.is_constant_spaced 	     && constant_space_width == spec.constant_space_width)	  : !spec.is_constant_spaced)      && ligature_mode == spec.ligature_mode      && kern_mode == spec.kern_mode)    return 1;  else    return 0;}tfont_spec tfont_spec::plain(){  return tfont_spec(name, input_position, fm, size, height, slant);}hunits tfont::get_width(charinfo *c){  if (is_constant_spaced)    return constant_space_width;  else if (is_bold)    return (hunits(fm->get_width(c->get_index(), size.to_scaled_points()))	    + track_kern + bold_offset);  else    return (hunits(fm->get_width(c->get_index(), size.to_scaled_points())) + track_kern);}vunits tfont::get_char_height(charinfo *c){  vunits v = fm->get_height(c->get_index(), size.to_scaled_points());  if (height != 0 && height != size.to_scaled_points())    return scale(v, height, size.to_scaled_points());  else    return v;}vunits tfont::get_char_depth(charinfo *c){  vunits v = fm->get_depth(c->get_index(), size.to_scaled_points());  if (height != 0 && height != size.to_scaled_points())    return scale(v, height, size.to_scaled_points());  else    return v;}hunits tfont::get_char_skew(charinfo *c){  return hunits(fm->get_skew(c->get_index(), size.to_scaled_points(), slant));}hunits tfont::get_italic_correction(charinfo *c){  return hunits(fm->get_italic_correction(c->get_index(), size.to_scaled_points()));}hunits tfont::get_left_italic_correction(charinfo *c){  return hunits(fm->get_left_italic_correction(c->get_index(),					       size.to_scaled_points()));}hunits tfont::get_subscript_correction(charinfo *c){  return hunits(fm->get_subscript_correction(c->get_index(),					     size.to_scaled_points()));}inline int tfont::get_input_position(){  return input_position;}inline int tfont::contains(charinfo *ci){  return fm->contains(ci->get_index());}inline int tfont::get_character_type(charinfo *ci){  return fm->get_character_type(ci->get_index());}inline int tfont::get_bold(hunits *res){  if (is_bold) {    *res = bold_offset;    return 1;  }  else    return 0;}inline int tfont::get_constant_space(hunits *res){  if (is_constant_spaced) {    *res = constant_space_width;    return 1;  }  else    return 0;}inline hunits tfont::get_track_kern(){  return track_kern;}inline tfont *tfont::get_plain(){  return plain_version;}inline font_size tfont::get_size(){  return size;}inline symbol tfont::get_name(){  return name;}inline int tfont::get_height(){  return height;}inline int tfont::get_slant(){  return slant;}symbol SYMBOL_ff("ff");symbol SYMBOL_fi("fi");symbol SYMBOL_fl("fl");symbol SYMBOL_Fi("Fi");symbol SYMBOL_Fl("Fl");charinfo *tfont::get_lig(charinfo *c1, charinfo *c2){  if (ligature_mode == 0)    return 0;  charinfo *ci = 0;  if (c1->get_ascii_code() == 'f') {    switch (c2->get_ascii_code()) {    case 'f':      if (fm->has_ligature(font::LIG_ff))	ci = get_charinfo(SYMBOL_ff);      break;    case 'i':      if (fm->has_ligature(font::LIG_fi))	ci = get_charinfo(SYMBOL_fi);      break;    case 'l':      if (fm->has_ligature(font::LIG_fl))	ci = get_charinfo(SYMBOL_fl);      break;    }  }  else if (ligature_mode != 2 && c1->nm == SYMBOL_ff) {    switch (c2->get_ascii_code()) {    case 'i':      if (fm->has_ligature(font::LIG_ffi))	ci = get_charinfo(SYMBOL_Fi);      break;    case 'l':      if (fm->has_ligature(font::LIG_ffl))	ci = get_charinfo(SYMBOL_Fl);      break;    }  }  if (ci != 0 && fm->contains(ci->get_index()))    return ci;  return 0;}inline int tfont::get_kern(charinfo *c1, charinfo *c2, hunits *res){  if (kern_mode == 0)    return 0;  else {    int n = fm->get_kern(c1->get_index(),			 c2->get_index(),			 size.to_scaled_points());    if (n) {      *res = hunits(n);      return 1;    }    else      return 0;  }}tfont *make_tfont(tfont_spec &spec){  for (tfont *p = tfont::tfont_list; p; p = p->next)    if (*p == spec)      return p;  return new tfont(spec);}tfont *tfont::tfont_list = 0;tfont::tfont(tfont_spec &spec) : tfont_spec(spec){  next = tfont_list;  tfont_list = this;  tfont_spec plain_spec = plain();  for (tfont *p = tfont_list; p; p = p->next)    if (*p == plain_spec) {      plain_version = p;      break;    }  if (!p)    plain_version = new tfont(plain_spec);}/* output_file */class real_output_file : public output_file {  int piped;  int printing;  virtual void really_transparent_char(unsigned char) = 0;  virtual void really_print_line(hunits x, vunits y, node *n,				 vunits before, vunits after) = 0;  virtual void really_begin_page(int pageno, vunits page_length) = 0;  virtual void really_copy_file(hunits x, vunits y, const char *filename);protected:  FILE *fp;public:  real_output_file();  ~real_output_file();  void flush();  void transparent_char(unsigned char);  void print_line(hunits x, vunits y, node *n, vunits before, vunits after);  void begin_page(int pageno, vunits page_length);  int is_printing();  void copy_file(hunits x, vunits y, const char *filename);};class suppress_output_file : public real_output_file {public:  suppress_output_file();  void really_transparent_char(unsigned char);  void really_print_line(hunits x, vunits y, node *n, vunits, vunits);  void really_begin_page(int pageno, vunits page_length);};class ascii_output_file : public real_output_file {public:  ascii_output_file();  void really_transparent_char(unsigned char);  void really_print_line(hunits x, vunits y, node *n, vunits, vunits);  void really_begin_page(int pageno, vunits page_length);  void outc(unsigned char c);  void outs(const char *s);};void ascii_output_file::outc(unsigned char c){  fputc(c, fp);}void ascii_output_file::outs(const char *s){  fputc('<', fp);  if (s)    fputs(s, fp);  fputc('>', fp);}struct hvpair;      class troff_output_file : public real_output_file {  units hpos;  units vpos;  units output_vpos;  units output_hpos;  int force_motion;  int current_size;  int current_slant;  int current_height;

⌨️ 快捷键说明

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