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

📄 object.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 3 页
字号:
// -*- 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 "pic.h"#include "ptable.h"#include "object.h"void print_object_list(object *);line_type::line_type(): type(solid), thickness(1.0){}output::output() : desired_height(0.0), desired_width(0.0), args(0){}output::~output(){  a_delete args;}void output::set_desired_width_height(double wid, double ht){  desired_width = wid;  desired_height = ht;}void output::set_args(const char *s){  a_delete args;  if (s == 0 || *s == '\0')    args = 0;  else    args = strsave(s);}void output::command(const char *, const char *, int){}void output::set_location(const char *, int){}int output::supports_filled_polygons(){  return 0;}void output::begin_block(const position &, const position &){}void output::end_block(){}double output::compute_scale(double sc, const position &ll, const position &ur){  distance dim = ur - ll;  if (desired_width != 0.0 || desired_height != 0.0) {    sc = 0.0;    if (desired_width != 0.0) {      if (dim.x == 0.0)	error("width specified for picture with zero width");      else	sc = dim.x/desired_width;    }    if (desired_height != 0.0) {      if (dim.y == 0.0)	error("height specified for picture with zero height");      else {	double tem = dim.y/desired_height;	if (tem > sc)	  sc = tem;      }    }    return sc == 0.0 ? 1.0 : sc;  }  else {    if (sc <= 0.0)      sc = 1.0;    distance sdim = dim/sc;    double max_width = 0.0;    lookup_variable("maxpswid", &max_width);    double max_height = 0.0;    lookup_variable("maxpsht", &max_height);    if ((max_width > 0.0 && sdim.x > max_width)	|| (max_height > 0.0 && sdim.y > max_height)) {      double xscale = dim.x/max_width;      double yscale = dim.y/max_height;      return xscale > yscale ? xscale : yscale;    }    else      return sc;  }}position::position(const place &pl){  if (pl.obj != 0) {    // Use two statements to work around bug in SGI C++.    object *tem = pl.obj;    *this = tem->origin();  }  else {    x = pl.x;    y = pl.y;  }}position::position() : x(0.0), y(0.0){}position::position(double a, double b) : x(a), y(b){}/* * XXX workaround for gcc 2.3.3 initializer bug. * From: Chris Torek <torek@BSDI.COM> */position &posref(position p) { return p; }int operator==(const position &a, const position &b){  return a.x == b.x && a.y == b.y;}int operator!=(const position &a, const position &b){  return a.x != b.x || a.y != b.y;}position &position::operator+=(const position &a){  x += a.x;  y += a.y;  return *this;}position &position::operator-=(const position &a){  x -= a.x;  y -= a.y;  return *this;}position &position::operator*=(double a){  x *= a;  y *= a;  return *this;}position &position::operator/=(double a){  x /= a;  y /= a;  return *this;}position operator-(const position &a){  return position(-a.x, -a.y);}position operator+(const position &a, const position &b){  return position(a.x + b.x, a.y + b.y);}position operator-(const position &a, const position &b){  return position(a.x - b.x, a.y - b.y);}position operator/(const position &a, double n){  return position(a.x/n, a.y/n);}position operator*(const position &a, double n){  return position(a.x*n, a.y*n);}// dot productdouble operator*(const position &a, const position &b){  return a.x*b.x + a.y*b.y;}double hypot(const position &a){  return hypot(a.x, a.y);}struct arrow_head_type {  double height;  double width;  int solid;};void draw_arrow(const position &pos, const distance &dir,		const arrow_head_type &aht, const line_type &lt){  double hyp = hypot(dir);  if (hyp == 0.0) {    error("cannot draw arrow on object with zero length");    return;  }  position base = -dir;  base *= aht.height/hyp;  position n(dir.y, -dir.x);  n *= aht.width/(hyp*2.0);  line_type slt = lt;  slt.type = line_type::solid;  if (aht.solid && out->supports_filled_polygons()) {    position v[3];    v[0] = pos;    v[1] = pos + base + n;    v[2] = pos + base - n;    // A value > 1 means fill with the current color.    out->polygon(v, 3, slt, 2.0);  }  else {    position v[2];    v[0] = pos;    v[1] = pos + base + n;    out->line(pos + base - n, v, 2, slt);  }}object::object() : prev(0), next(0){}object::~object(){}void object::move_by(const position &){}void object::print(){}void object::print_text(){}int object::blank(){  return 0;}struct bounding_box {  int blank;  position ll;  position ur;  bounding_box();  void encompass(const position &);};bounding_box::bounding_box(): blank(1){}void bounding_box::encompass(const position &pos){  if (blank) {    ll = pos;    ur = pos;    blank = 0;  }  else {    if (pos.x < ll.x)      ll.x = pos.x;    if (pos.y < ll.y)      ll.y = pos.y;    if (pos.x > ur.x)      ur.x = pos.x;    if (pos.y > ur.y)      ur.y = pos.y;  }}void object::update_bounding_box(bounding_box *){}position object::origin(){  return position(0.0,0.0);}position object::north(){  return origin();}position object::south(){  return origin();}position object::east(){  return origin();}position object::west(){  return origin();}position object::north_east(){  return origin();}position object::north_west(){  return origin();}position object::south_east(){  return origin();}position object::south_west(){  return origin();}position object::start(){  return origin();}position object::end(){  return origin();}position object::center(){  return origin();}double object::width(){  return 0.0;}double object::radius(){  return 0.0;}double object::height(){  return 0.0;}place *object::find_label(const char *){  return 0;}segment::segment(const position &a, int n, segment *p): pos(a), is_absolute(n), next(p){}text_item::text_item(char *t, const char *fn, int ln): filename(fn), lineno(ln), text(t), next(0){  adj.h = CENTER_ADJUST;  adj.v = NONE_ADJUST;}text_item::~text_item(){  a_delete text;}object_spec::object_spec(object_type t) : type(t){  flags = 0;  tbl = 0;  segment_list = 0;  segment_width = segment_height = 0.0;  segment_is_absolute = 0;  text = 0;  with = 0;  dir = RIGHT_DIRECTION;}object_spec::~object_spec(){  delete tbl;  while (segment_list != 0) {    segment *tem = segment_list;    segment_list = segment_list->next;    delete tem;  }  object *p = oblist.head;  while (p != 0) {    object *tem = p;    p = p->next;    delete tem;  }  while (text != 0) {    text_item *tem = text;    text = text->next;    delete tem;  }  delete with;}class command_object : public object {  char *s;  const char *filename;  int lineno;public:  command_object(char *, const char *, int);  ~command_object();  object_type type() { return OTHER_OBJECT; }  void print();};command_object::command_object(char *p, const char *fn, int ln): s(p), filename(fn), lineno(ln){}command_object::~command_object(){  a_delete s;}void command_object::print(){  out->command(s, filename, lineno);}object *make_command_object(char *s, const char *fn, int ln){  return new command_object(s, fn, ln);}class mark_object : public object {public:  mark_object();  object_type type();};object *make_mark_object(){  return new mark_object();}mark_object::mark_object(){}object_type mark_object::type(){  return MARK_OBJECT;}object_list::object_list() : head(0), tail(0){}void object_list::append(object *obj){  if (tail == 0) {    obj->next = obj->prev = 0;    head = tail = obj;  }  else {    obj->prev = tail;    obj->next = 0;    tail->next = obj;    tail = obj;  }}void object_list::wrap_up_block(object_list *ol){  for (object *p = tail; p && p->type() != MARK_OBJECT; p = p->prev)    ;  assert(p != 0);  ol->head = p->next;  if (ol->head) {    ol->tail = tail;    ol->head->prev = 0;  }  else    ol->tail = 0;  tail = p->prev;  if (tail)    tail->next = 0;  else    head = 0;  delete p;}text_piece::text_piece(): text(0), filename(0), lineno(-1){  adj.h = CENTER_ADJUST;  adj.v = NONE_ADJUST;}text_piece::~text_piece(){  a_delete text;}class graphic_object : public object {  int ntext;  text_piece *text;  int aligned;protected:  line_type lt;public:  graphic_object();  ~graphic_object();  object_type type() = 0;  void print_text();  void add_text(text_item *, int);  void set_dotted(double);  void set_dashed(double);  void set_thickness(double);  void set_invisible();  virtual void set_fill(double);};graphic_object::graphic_object() : ntext(0), text(0), aligned(0){}void graphic_object::set_dotted(double wid){  lt.type = line_type::dotted;  lt.dash_width = wid;}void graphic_object::set_dashed(double wid){  lt.type = line_type::dashed;  lt.dash_width = wid;}void graphic_object::set_thickness(double th){  lt.thickness = th;}void graphic_object::set_fill(double){}void graphic_object::set_invisible(){  lt.type = line_type::invisible;}void graphic_object::add_text(text_item *t, int a){  aligned = a;  int len = 0;  for (text_item *p = t; p; p = p->next)    len++;  if (len == 0)    text = 0;  else {    text = new text_piece[len];

⌨️ 快捷键说明

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