📄 object.cc
字号:
// -*- 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 <){ 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 + -