diff options
author | wlemb <wlemb> | 2004-07-06 07:45:17 +0000 |
---|---|---|
committer | wlemb <wlemb> | 2004-07-06 07:45:17 +0000 |
commit | 80d9595bcfcd3c0bcbf3b8eb2bd2cf11781bff45 (patch) | |
tree | 473dddb3539b81c303b2c861fc0e27be3533dbdc /src | |
parent | aeb419f2fb91f984de14d60819746f5390b3821b (diff) | |
download | groff-80d9595bcfcd3c0bcbf3b8eb2bd2cf11781bff45.tar.gz |
* doc/groff.texinfo: Further improve documentation of `hcode'.
Improve appearance of arrows in pic.
* src/preproc/pic/object.cpp (draw_arrow): Make outline of filled
arrow head thin.
Use two line segments for drawing non-filled arrow head.
(line_object::print, spline_object::print): Shorten line length to
avoid arrow sticking.
(arc_object::print): Take arrow direction into account.
Diffstat (limited to 'src')
-rw-r--r-- | src/preproc/pic/object.cpp | 177 |
1 files changed, 148 insertions, 29 deletions
diff --git a/src/preproc/pic/object.cpp b/src/preproc/pic/object.cpp index a14d022a..1f70c45b 100644 --- a/src/preproc/pic/object.cpp +++ b/src/preproc/pic/object.cpp @@ -233,13 +233,14 @@ void draw_arrow(const position &pos, const distance &dir, v[2] = pos + base - n; // fill with outline color out->set_color(outline_color_for_fill, outline_color_for_fill); + // make stroke thin to avoid arrow sticking + slt.thickness = 0.1; out->polygon(v, 3, slt, 1); } else { - position v[2]; - v[0] = pos; - v[1] = pos + base + n; - out->line(pos + base - n, v, 2, slt); + // use two line segments to avoid arrow sticking + out->line(pos + base - n, &pos, 1, slt); + out->line(pos + base + n, &pos, 1, slt); } } @@ -1258,12 +1259,47 @@ 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, graphic_object::get_outline_color()); - if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt, - graphic_object::get_outline_color()); + // shorten line length to avoid arrow sticking. + position sp = strt; + if (arrow_at_start) { + position base = v[0] - strt; + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(strt, strt - v[0], aht, lt, + graphic_object::get_outline_color()); + sp = strt + base; + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + sp = strt + base; + draw_arrow(sp, sp - v[0], aht, lt, + graphic_object::get_outline_color()); + } + } + if (arrow_at_end) { + position base = v[n-1] - (n > 1 ? v[n-2] : strt); + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(en, v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + v[n-1] = en - base; + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + v[n-1] = en - base; + draw_arrow(v[n-1], v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + } + } + out->line(sp, v, n, lt); out->reset_color(); } @@ -1328,12 +1364,47 @@ 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, graphic_object::get_outline_color()); - if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt, - graphic_object::get_outline_color()); + // shorten line length for spline to avoid arrow sticking + position sp = strt; + if (arrow_at_start) { + position base = v[0] - strt; + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(strt, strt - v[0], aht, lt, + graphic_object::get_outline_color()); + sp = strt + base*0.1; // to reserve spline shape + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + sp = strt + base; + draw_arrow(sp, sp - v[0], aht, lt, + graphic_object::get_outline_color()); + } + } + if (arrow_at_end) { + position base = v[n-1] - (n > 1 ? v[n-2] : strt); + double hyp = hypot(base); + if (hyp == 0.0) { + error("cannot draw arrow on object with zero length"); + return; + } + if (aht.solid && out->supports_filled_polygons()) { + base *= aht.height / hyp; + draw_arrow(en, v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + v[n-1] = en - base*0.1; // to reserve spline shape + } else { + base *= fabs(lt.thickness) / hyp / 72 / 4; + v[n-1] = en - base; + draw_arrow(v[n-1], v[n-1] - (n > 1 ? v[n-2] : strt), aht, lt, + graphic_object::get_outline_color()); + } + } + out->spline(sp, v, n, lt); out->reset_color(); } @@ -1542,22 +1613,70 @@ 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 - out->arc(strt, cent, en, lt); + // handle arrow direction; make shorter line for arc + position sp, ep, b; + if (clockwise) { + sp = en; + ep = strt; + } else { + sp = strt; + ep = en; + } if (arrow_at_start) { - position c = cent - strt; - draw_arrow(strt, - (clockwise ? position(c.y, -c.x) : position(-c.y, c.x)), - aht, lt, graphic_object::get_outline_color()); + double theta = aht.height / rad; + if (clockwise) + theta = - theta; + b = strt - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + if (clockwise) + ep = b; + else + sp = b; + if (aht.solid && out->supports_filled_polygons()) { + draw_arrow(strt, strt - b, aht, lt, + graphic_object::get_outline_color()); + } else { + position v = b; + theta = fabs(lt.thickness) / 72 / 4 / rad; + if (clockwise) + theta = - theta; + b = strt - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + draw_arrow(b, b - v, aht, lt, + graphic_object::get_outline_color()); + out->line(b, &v, 1, lt); + } } if (arrow_at_end) { - position e = en - cent; - draw_arrow(en, - (clockwise ? position(e.y, -e.x) : position(-e.y, e.x)), - aht, lt, graphic_object::get_outline_color()); + double theta = aht.height / rad; + if (!clockwise) + theta = - theta; + b = en - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + if (clockwise) + sp = b; + else + ep = b; + if (aht.solid && out->supports_filled_polygons()) { + draw_arrow(en, en - b, aht, lt, + graphic_object::get_outline_color()); + } else { + position v = b; + theta = fabs(lt.thickness) / 72 / 4 / rad; + if (!clockwise) + theta = - theta; + b = en - cent; + b = position(b.x*cos(theta) - b.y*sin(theta), + b.x*sin(theta) + b.y*cos(theta)) + cent; + draw_arrow(b, b - v, aht, lt, + graphic_object::get_outline_color()); + out->line(b, &v, 1, lt); + } } + out->arc(sp, cent, ep, lt); out->reset_color(); } @@ -1753,7 +1872,7 @@ object *object_spec::make_object(position *curpos, direction *dirp) 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 | IS_FILLED)) { if (flags & IS_SHADED) obj->set_fill_color(shaded); else { |