diff options
Diffstat (limited to 'contrib/groff/src/preproc/pic/object.cc')
-rw-r--r-- | contrib/groff/src/preproc/pic/object.cc | 141 |
1 files changed, 101 insertions, 40 deletions
diff --git a/contrib/groff/src/preproc/pic/object.cc b/contrib/groff/src/preproc/pic/object.cc index 6b34633..fd25371 100644 --- a/contrib/groff/src/preproc/pic/object.cc +++ b/contrib/groff/src/preproc/pic/object.cc @@ -1,5 +1,6 @@ // -*- C++ -*- -/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. +/* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002 + Free Software Foundation, Inc. Written by James Clark (jjc@jclark.com) This file is part of groff. @@ -53,14 +54,6 @@ void output::set_args(const char *s) 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; @@ -219,7 +212,8 @@ struct arrow_head_type { }; void draw_arrow(const position &pos, const distance &dir, - const arrow_head_type &aht, const line_type <) + const arrow_head_type &aht, const line_type <, + char *outline_color_for_fill) { double hyp = hypot(dir); if (hyp == 0.0) { @@ -237,8 +231,9 @@ void draw_arrow(const position &pos, const distance &dir, 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); + // fill with outline color + out->set_color(outline_color_for_fill, outline_color_for_fill); + out->polygon(v, 3, slt, 1); } else { position v[2]; @@ -549,6 +544,8 @@ class graphic_object : public object { int aligned; protected: line_type lt; + char *outline_color; + char *color_fill; public: graphic_object(); ~graphic_object(); @@ -559,10 +556,14 @@ public: void set_dashed(double); void set_thickness(double); void set_invisible(); + void set_outline_color(char *); + char *get_outline_color(); virtual void set_fill(double); + virtual void set_fill_color(char *); }; -graphic_object::graphic_object() : ntext(0), text(0), aligned(0) +graphic_object::graphic_object() +: ntext(0), text(0), aligned(0), outline_color(0), color_fill(0) { } @@ -587,6 +588,21 @@ void graphic_object::set_fill(double) { } +void graphic_object::set_fill_color(char *c) +{ + color_fill = c; +} + +void graphic_object::set_outline_color(char *c) +{ + outline_color = c; +} + +char *graphic_object::get_outline_color() +{ + return outline_color; +} + void graphic_object::set_invisible() { lt.type = line_type::invisible; @@ -622,8 +638,11 @@ void graphic_object::print_text() if (d.x != 0.0 || d.y != 0.0) angle = atan2(d.y, d.x); } - if (text != 0) + if (text != 0) { + out->set_color(color_fill, get_outline_color()); out->text(center(), text, ntext, angle); + out->reset_color(); + } } graphic_object::~graphic_object() @@ -676,12 +695,14 @@ public: closed_object(const position &); object_type type() = 0; void set_fill(double); + void set_fill_color(char *fill); protected: double fill; // < 0 if not filled + char *color_fill; // = 0 if not colored }; closed_object::closed_object(const position &pos) -: rectangle_object(pos), fill(-1.0) +: rectangle_object(pos), fill(-1.0), color_fill(0) { } @@ -691,6 +712,10 @@ void closed_object::set_fill(double f) fill = f; } +void closed_object::set_fill_color(char *fill) +{ + color_fill = fill; +} class box_object : public closed_object { double xrad; @@ -738,8 +763,9 @@ position box_object::south_west() void box_object::print() { - if (lt.type == line_type::invisible && fill < 0.0) + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) return; + out->set_color(color_fill, graphic_object::get_outline_color()); if (xrad == 0.0) { distance dim2 = dim/2.0; position vec[4]; @@ -753,6 +779,7 @@ void box_object::print() distance abs_dim(fabs(dim.x), fabs(dim.y)); out->rounded_box(cent, abs_dim, fabs(xrad), lt, fill); } + out->reset_color(); } graphic_object *object_spec::make_box(position *curpos, direction *dirp) @@ -990,9 +1017,11 @@ ellipse_object::ellipse_object(const position &d) void ellipse_object::print() { - if (lt.type == line_type::invisible && fill < 0.0) + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) return; + out->set_color(color_fill, graphic_object::get_outline_color()); out->ellipse(cent, dim, lt, fill); + out->reset_color(); } graphic_object *object_spec::make_ellipse(position *curpos, direction *dirp) @@ -1037,9 +1066,11 @@ circle_object::circle_object(double diam) void circle_object::print() { - if (lt.type == line_type::invisible && fill < 0.0) + if (lt.type == line_type::invisible && fill < 0.0 && color_fill == 0) return; + out->set_color(color_fill, graphic_object::get_outline_color()); out->circle(cent, dim.x/2.0, lt, fill); + out->reset_color(); } graphic_object *object_spec::make_circle(position *curpos, direction *dirp) @@ -1098,7 +1129,7 @@ graphic_object *object_spec::make_move(position *curpos, direction *dirp) // 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) + if ((flags & IS_SAME) && have_last_move) segment_pos = last_move; else { switch (dir) { @@ -1222,11 +1253,14 @@ void line_object::print() { if (lt.type == line_type::invisible) return; + out->set_color(0, graphic_object::get_outline_color()); out->line(strt, v, n, lt); if (arrow_at_start) - draw_arrow(strt, strt-v[0], aht, lt); + draw_arrow(strt, strt-v[0], aht, lt, graphic_object::get_outline_color()); if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt); + draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt, + graphic_object::get_outline_color()); + out->reset_color(); } void line_object::update_bounding_box(bounding_box *p) @@ -1289,11 +1323,14 @@ void spline_object::print() { if (lt.type == line_type::invisible) return; + out->set_color(0, graphic_object::get_outline_color()); out->spline(strt, v, n, lt); if (arrow_at_start) - draw_arrow(strt, strt-v[0], aht, lt); + draw_arrow(strt, strt-v[0], aht, lt, graphic_object::get_outline_color()); if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt); + draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt, + graphic_object::get_outline_color()); + out->reset_color(); } line_object::~line_object() @@ -1500,6 +1537,7 @@ void arc_object::print() { if (lt.type == line_type::invisible) return; + out->set_color(0, graphic_object::get_outline_color()); if (clockwise) out->arc(en, cent, strt, lt); else @@ -1508,14 +1546,15 @@ void arc_object::print() position c = cent - strt; draw_arrow(strt, (clockwise ? position(c.y, -c.x) : position(-c.y, c.x)), - aht, lt); + aht, lt, graphic_object::get_outline_color()); } if (arrow_at_end) { position e = en - cent; draw_arrow(en, (clockwise ? position(e.y, -e.x) : position(-e.y, e.x)), - aht, lt); + aht, lt, graphic_object::get_outline_color()); } + out->reset_color(); } inline double max(double a, double b) @@ -1708,13 +1747,19 @@ object *object_spec::make_object(position *curpos, direction *dirp) else lookup_variable("linethick", &th); obj->set_thickness(th); + if (flags & IS_OUTLINED) + obj->set_outline_color(outlined); if (flags & (IS_DEFAULT_FILLED|IS_FILLED)) { - if (flags & IS_DEFAULT_FILLED) - lookup_variable("fillval", &fill); - if (fill < 0.0) - error("bad fill value %1", fill); - else - obj->set_fill(fill); + if (flags & IS_SHADED) + obj->set_fill_color(shaded); + else { + if (flags & IS_DEFAULT_FILLED) + lookup_variable("fillval", &fill); + if (fill < 0.0) + error("bad fill value %1", fill); + else + obj->set_fill(fill); + } } } return obj; @@ -1737,18 +1782,28 @@ string_list::~string_list() a_delete str; } -/* A path is used to hold the argument to the with attribute. For example, -`.nw' or `.A.s' or `.A'. The major operation on a path is to take a -place and follow the path through the place to place within the place. -Note that `.A.B.C.sw' will work. */ +/* A path is used to hold the argument to the `with' attribute. For + example, `.nw' or `.A.s' or `.A'. The major operation on a path is to + take a place and follow the path through the place to place within the + place. Note that `.A.B.C.sw' will work. + + For compatibility with DWB pic, `with' accepts positions also (this + is incorrectly documented in CSTR 116). */ path::path(corner c) -: crn(c), label_list(0), ypath(0) +: crn(c), label_list(0), ypath(0), is_position(0) { } +path::path(position p) +: crn(0), label_list(0), ypath(0), is_position(1) +{ + pos.x = p.x; + pos.y = p.y; +} + path::path(char *l, corner c) -: crn(c), ypath(0) +: crn(c), ypath(0), is_position(0) { label_list = new string_list(l); } @@ -1786,6 +1841,12 @@ void path::set_ypath(path *p) int path::follow(const place &pl, place *result) const { + if (is_position) { + result->x = pos.x; + result->y = pos.y; + result->obj = 0; + return 1; + } const place *p = &pl; for (string_list *lb = label_list; lb; lb = lb->next) if (p->obj == 0 || (p = p->obj->find_label(lb->str)) == 0) { @@ -1795,9 +1856,9 @@ int path::follow(const place &pl, place *result) const if (crn == 0 || p->obj == 0) *result = *p; else { - position pos = ((p->obj)->*(crn))(); - result->x = pos.x; - result->y = pos.y; + position ps = ((p->obj)->*(crn))(); + result->x = ps.x; + result->y = ps.y; result->obj = 0; } if (ypath) { |