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

📄 object.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
    for (p = t, len = 0; p; p = p->next, len++) {      text[len].text = p->text;      p->text = 0;      text[len].adj = p->adj;      text[len].filename = p->filename;      text[len].lineno = p->lineno;    }  }  ntext = len;}void graphic_object::print_text(){  double angle = 0.0;  if (aligned) {    position d(end() - start());    if (d.x != 0.0 || d.y != 0.0)      angle = atan2(d.y, d.x);  }  if (text != 0)    out->text(center(), text, ntext, angle);}graphic_object::~graphic_object(){  if (text)    ad_delete(ntext) text;}class rectangle_object : public graphic_object {protected:  position cent;  position dim;public:  rectangle_object(const position &);  double width() { return dim.x; }  double height() { return dim.y; }  position origin() { return cent; }  position center() { return cent; }  position north() { return position(cent.x, cent.y + dim.y/2.0); }  position south() { return position(cent.x, cent.y - dim.y/2.0); }  position east() { return position(cent.x + dim.x/2.0, cent.y); }  position west() { return position(cent.x - dim.x/2.0, cent.y); }  position north_east() { return position(cent.x + dim.x/2.0, cent.y + dim.y/2.0); }  position north_west() { return position(cent.x - dim.x/2.0, cent.y + dim.y/2.0); }  position south_east() { return position(cent.x + dim.x/2.0, cent.y - dim.y/2.0); }  position south_west() { return position(cent.x - dim.x/2.0, cent.y - dim.y/2.0); }  object_type type() = 0;  void update_bounding_box(bounding_box *);  void move_by(const position &);};rectangle_object::rectangle_object(const position &d): dim(d){}void rectangle_object::update_bounding_box(bounding_box *p){  p->encompass(cent - dim/2.0);  p->encompass(cent + dim/2.0);}void rectangle_object::move_by(const position &a){  cent += a;}class closed_object : public rectangle_object {public:  closed_object(const position &);  object_type type() = 0;  void set_fill(double);protected:  double fill;			// < 0 if not filled};closed_object::closed_object(const position &pos): rectangle_object(pos), fill(-1.0){}void closed_object::set_fill(double f){  assert(f >= 0.0);  fill = f;}class box_object : public closed_object {  double xrad;  double yrad;public:  box_object(const position &, double);  object_type type() { return BOX_OBJECT; }  void print();  position north_east();  position north_west();  position south_east();  position south_west();};box_object::box_object(const position &pos, double r): closed_object(pos), xrad(dim.x > 0 ? r : -r), yrad(dim.y > 0 ? r : -r){}const double CHOP_FACTOR = 1.0 - 1.0/M_SQRT2;position box_object::north_east(){  return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad,		  cent.y + dim.y/2.0 - CHOP_FACTOR*yrad);}position box_object::north_west(){  return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad,		  cent.y + dim.y/2.0 - CHOP_FACTOR*yrad);}position box_object::south_east(){  return position(cent.x + dim.x/2.0 - CHOP_FACTOR*xrad,		  cent.y - dim.y/2.0 + CHOP_FACTOR*yrad);}position box_object::south_west(){  return position(cent.x - dim.x/2.0 + CHOP_FACTOR*xrad,		  cent.y - dim.y/2.0 + CHOP_FACTOR*yrad);}void box_object::print(){  if (lt.type == line_type::invisible && fill < 0.0)    return;  if (xrad == 0.0) {    distance dim2 = dim/2.0;    position vec[4];    vec[0] = cent + position(dim2.x, -dim2.y);    vec[1] = cent + position(dim2.x, dim2.y);    vec[2] = cent + position(-dim2.x, dim2.y);    vec[3] = cent + position(-dim2.x, -dim2.y);    out->polygon(vec, 4, lt, fill);  }  else {    distance abs_dim(fabs(dim.x), fabs(dim.y));    out->rounded_box(cent, abs_dim, fabs(xrad), lt, fill);  }}graphic_object *object_spec::make_box(position *curpos, direction *dirp){  static double last_box_height;  static double last_box_width;  static double last_box_radius;  static int have_last_box = 0;  if (!(flags & HAS_HEIGHT)) {    if ((flags & IS_SAME) && have_last_box)      height = last_box_height;    else      lookup_variable("boxht", &height);  }  if (!(flags & HAS_WIDTH)) {    if ((flags & IS_SAME) && have_last_box)      width = last_box_width;    else      lookup_variable("boxwid", &width);  }  if (!(flags & HAS_RADIUS)) {    if ((flags & IS_SAME) && have_last_box)      radius = last_box_radius;    else      lookup_variable("boxrad", &radius);  }  last_box_width = width;  last_box_height = height;  last_box_radius = radius;  have_last_box = 1;  radius = fabs(radius);  if (radius*2.0 > fabs(width))    radius = fabs(width/2.0);  if (radius*2.0 > fabs(height))    radius = fabs(height/2.0);  box_object *p = new box_object(position(width, height), radius);  if (!position_rectangle(p, curpos, dirp)) {    delete p;    p = 0;  }  return p;}// return non-zero for successint object_spec::position_rectangle(rectangle_object *p,				    position *curpos, direction *dirp){  position pos;  dir = *dirp;			// ignore any direction in attribute list  position motion;  switch (dir) {  case UP_DIRECTION:    motion.y = p->height()/2.0;    break;  case DOWN_DIRECTION:    motion.y = -p->height()/2.0;    break;  case LEFT_DIRECTION:    motion.x = -p->width()/2.0;    break;  case RIGHT_DIRECTION:    motion.x = p->width()/2.0;    break;  default:    assert(0);  }  if (flags & HAS_AT) {    pos = at;    if (flags & HAS_WITH) {      place offset;      place here;      here.obj = p;      if (!with->follow(here, &offset))	return 0;      pos -= offset;    }  }  else {    pos = *curpos;    pos += motion;  }  p->move_by(pos);  pos += motion;  *curpos = pos;  return 1;}class block_object : public rectangle_object {  object_list oblist;  PTABLE(place) *tbl;public:  block_object(const position &, const object_list &ol, PTABLE(place) *t);  ~block_object();  place *find_label(const char *);  object_type type();  void move_by(const position &);  void print();};block_object::block_object(const position &d, const object_list &ol,			   PTABLE(place) *t): oblist(ol), tbl(t), rectangle_object(d){}block_object::~block_object(){  delete tbl;  object *p = oblist.head;  while (p != 0) {    object *tem = p;    p = p->next;    delete tem;  }}void block_object::print(){  out->begin_block(south_west(), north_east());  print_object_list(oblist.head);  out->end_block();}static void adjust_objectless_places(PTABLE(place) *tbl, const position &a){  // Adjust all the labels that aren't attached to objects.  PTABLE_ITERATOR(place) iter(tbl);  const char *key;  place *pl;  while (iter.next(&key, &pl))    if (key && csupper(key[0]) && pl->obj == 0) {      pl->x += a.x;      pl->y += a.y;    }}void block_object::move_by(const position &a){  cent += a;  for (object *p = oblist.head; p; p = p->next)    p->move_by(a);  adjust_objectless_places(tbl, a);}place *block_object::find_label(const char *name){  return tbl->lookup(name);}object_type block_object::type(){  return BLOCK_OBJECT;}graphic_object *object_spec::make_block(position *curpos, direction *dirp){  bounding_box bb;  for (object *p = oblist.head; p; p = p->next)    p->update_bounding_box(&bb);  position dim;  if (!bb.blank) {    position m = -(bb.ll + bb.ur)/2.0;    for (object *p = oblist.head; p; p = p->next)      p->move_by(m);    adjust_objectless_places(tbl, m);    dim = bb.ur - bb.ll;  }  if (flags & HAS_WIDTH)    dim.x = width;  if (flags & HAS_HEIGHT)    dim.y = height;  block_object *block = new block_object(dim, oblist, tbl);  if (!position_rectangle(block, curpos, dirp)) {    delete block;    block = 0;  }  tbl = 0;  oblist.head = oblist.tail = 0;  return block;}class text_object : public rectangle_object {public:  text_object(const position &);  object_type type() { return TEXT_OBJECT; }};text_object::text_object(const position &d): rectangle_object(d){}graphic_object *object_spec::make_text(position *curpos, direction *dirp){  if (!(flags & HAS_HEIGHT)) {    lookup_variable("textht", &height);    int nitems = 0;    for (text_item *t = text; t; t = t->next)      nitems++;    height *= nitems;  }  if (!(flags & HAS_WIDTH))    lookup_variable("textwid", &width);  text_object *p = new text_object(position(width, height));  if (!position_rectangle(p, curpos, dirp)) {    delete p;    p = 0;  }  return p;}class ellipse_object : public closed_object {public:  ellipse_object(const position &);  position north_east() { return position(cent.x + dim.x/(M_SQRT2*2.0),					  cent.y + dim.y/(M_SQRT2*2.0)); }  position north_west() { return position(cent.x - dim.x/(M_SQRT2*2.0),					  cent.y + dim.y/(M_SQRT2*2.0)); }  position south_east() { return position(cent.x + dim.x/(M_SQRT2*2.0),					  cent.y - dim.y/(M_SQRT2*2.0)); }  position south_west() { return position(cent.x - dim.x/(M_SQRT2*2.0),					  cent.y - dim.y/(M_SQRT2*2.0)); }  double radius() { return dim.x/2.0; }  object_type type() { return ELLIPSE_OBJECT; }  void print();};ellipse_object::ellipse_object(const position &d): closed_object(d){}void ellipse_object::print(){  if (lt.type == line_type::invisible && fill < 0.0)    return;  out->ellipse(cent, dim, lt, fill);}graphic_object *object_spec::make_ellipse(position *curpos, direction *dirp){  static double last_ellipse_height;  static double last_ellipse_width;  static int have_last_ellipse = 0;  if (!(flags & HAS_HEIGHT)) {    if ((flags & IS_SAME) && have_last_ellipse)      height = last_ellipse_height;    else      lookup_variable("ellipseht", &height);  }  if (!(flags & HAS_WIDTH)) {    if ((flags & IS_SAME) && have_last_ellipse)      width = last_ellipse_width;    else      lookup_variable("ellipsewid", &width);  }  last_ellipse_width = width;  last_ellipse_height = height;  have_last_ellipse = 1;  ellipse_object *p = new ellipse_object(position(width, height));  if (!position_rectangle(p, curpos, dirp)) {    delete p;    return 0;  }  return p;}class circle_object : public ellipse_object {public:  circle_object(double);  object_type type() { return CIRCLE_OBJECT; }  void print();};/* * XXX call posref to gain reference to avoid g++ core dump. * From: Chris Torek <torek@BSDI.COM> */circle_object::circle_object(double diam): ellipse_object(posref(position(diam, diam))){}void circle_object::print(){  if (lt.type == line_type::invisible && fill < 0.0)    return;  out->circle(cent, dim.x/2.0, lt, fill);}graphic_object *object_spec::make_circle(position *curpos, direction *dirp){  static double last_circle_radius;  static int have_last_circle = 0;  if (!(flags & HAS_RADIUS)) {    if ((flags & IS_SAME) && have_last_circle)      radius = last_circle_radius;    else      lookup_variable("circlerad", &radius);  }  last_circle_radius = radius;  have_last_circle = 1;  circle_object *p = new circle_object(radius*2.0);  if (!position_rectangle(p, curpos, dirp)) {    delete p;    return 0;  }  return p;}class move_object : public graphic_object {  position strt;  position en;public:  move_object(const position &s, const position &e);  position origin() { return en; }  object_type type() { return MOVE_OBJECT; }  void update_bounding_box(bounding_box *);  void move_by(const position &);};move_object::move_object(const position &s, const position &e): strt(s), en(e){}void move_object::update_bounding_box(bounding_box *p){  p->encompass(strt);  p->encompass(en);}void move_object::move_by(const position &a){  strt += a;  en += a;}graphic_object *object_spec::make_move(position *curpos, direction *dirp){  static position last_move;  static int have_last_move = 0;  *dirp = dir;  // No need to look at at since `at' attribute sets `from' attribute.  position startpos = (flags & HAS_FROM) ? from : *curpos;  if (!(flags & HAS_SEGMENT)) {    if ((flags && IS_SAME) && have_last_move)      segment_pos = last_move;    else {      switch (dir) {      case UP_DIRECTION:	segment_pos.y = segment_height;	break;      case DOWN_DIRECTION:	segment_pos.y = -segment_height;	break;      case LEFT_DIRECTION:	segment_pos.x = -segment_width;	break;      case RIGHT_DIRECTION:	segment_pos.x = segment_width;	break;      default:	assert(0);      }    }  }  segment_list = new segment(segment_pos, segment_is_absolute, segment_list);  // Reverse the segment_list so that it's in forward order.  segment *old = segment_list;  segment_list = 0;  while (old != 0) {    segment *tem = old->next;    old->next = segment_list;    segment_list = old;    old = tem;  }  // Compute the end position.  position endpos = startpos;  for (segment *s = segment_list; s; s = s->next)    if (s->is_absolute)      endpos = s->pos;    else       endpos += s->pos;  have_last_move = 1;  last_move = endpos - startpos;  move_object *p = new move_object(startpos, endpos);  *curpos = endpos;  return p;}class linear_object : public graphic_object {protected:  char arrow_at_start;  char arrow_at_end;  arrow_head_type aht;  position strt;  position en;public:  linear_object(const position &s, const position &e);  position start() { return strt; }  position end() { return en; }  void move_by(const position &);  void update_bounding_box(bounding_box *) = 0;  object_type type() = 0;  void add_arrows(int at_start, int at_end, const arrow_head_type &);};class line_object : public linear_object {protected:  position *v;  int n;public:  line_object(const position &s, const position &e, position *, int);  ~line_object();  position origin() { return strt; }  position center() { return (strt + en)/2.0; }  position north() { return (en.y - strt.y) > 0 ? en : strt; }  position south() { return (en.y - strt.y) < 0 ? en : strt; }  position east() { return (en.x - strt.x) > 0 ? en : strt; }  position west() { return (en.x - strt.x) < 0 ? en : strt; }  object_type type() { return LINE_OBJECT; }  void update_bounding_box(bounding_box *);  void print();  void move_by(const position &);};class arrow_object : public line_object {public:  arrow_object(const position &, const position &, position *, int);  object_type type() { return ARROW_OBJECT; }};class spline_object : public line_object {public:  spline_object(const position &, const position &, position *, int);  object_type type() { return SPLINE_OBJECT; }  void print();  void update_bounding_box(bounding_box *);};linear_object::linear_object(const position &s, const position &e): strt(s), en(e), arrow_at_start(0), arrow_at_end(0){}void linear_object::move_by(const position &a){  strt += a;  en += a;}void linear_object::add_arrows(int at_start, int at_end,			       const arrow_head_type &a){  arrow_at_start = at_start;

⌨️ 快捷键说明

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