diff options
Diffstat (limited to 'gnu/usr.bin/groff/pic')
-rw-r--r-- | gnu/usr.bin/groff/pic/Makefile.dep | 24 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/Makefile.sub | 11 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/TODO | 37 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/common.cc | 497 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/common.h | 70 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/depend | 21 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/lex.cc | 1939 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/main.cc | 621 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/object.cc | 1833 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/object.h | 217 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/output.h | 79 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/pic.1_in | 759 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/pic.h | 102 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/pic.y | 1784 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/position.h | 47 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/tex.cc | 411 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/text.h | 28 | ||||
-rw-r--r-- | gnu/usr.bin/groff/pic/troff.cc | 500 |
18 files changed, 0 insertions, 8980 deletions
diff --git a/gnu/usr.bin/groff/pic/Makefile.dep b/gnu/usr.bin/groff/pic/Makefile.dep deleted file mode 100644 index 1e07874890b..00000000000 --- a/gnu/usr.bin/groff/pic/Makefile.dep +++ /dev/null @@ -1,24 +0,0 @@ -lex.o: lex.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h ../include/ptable.h \ - object.h pic.cc -main.o: main.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h -object.o: object.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h ../include/ptable.h \ - object.h -common.o: common.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h common.h -troff.o: troff.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h common.h -tex.o: tex.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h common.h -pic.o: pic.cc pic.h ../include/assert.h ../include/cset.h \ - ../include/lib.h ../include/stringclass.h ../include/errarg.h \ - ../include/error.h position.h text.h output.h ../include/ptable.h \ - object.h diff --git a/gnu/usr.bin/groff/pic/Makefile.sub b/gnu/usr.bin/groff/pic/Makefile.sub deleted file mode 100644 index b36033cf449..00000000000 --- a/gnu/usr.bin/groff/pic/Makefile.sub +++ /dev/null @@ -1,11 +0,0 @@ -PROG=pic -MAN1=pic.1 -XLIBS=$(LIBGROFF) -MLIB=$(LIBM) -OBJS=pic.o lex.o main.o object.o common.o troff.o tex.o # fig.o -CCSRCS=lex.cc main.cc object.cc common.cc troff.cc tex.cc -HDRS=common.h object.h output.h pic.h position.h text.h -GRAM=pic.y -YTABC=pic.cc -YTABH=pic.tab.h -NAMEPREFIX=$(g) diff --git a/gnu/usr.bin/groff/pic/TODO b/gnu/usr.bin/groff/pic/TODO deleted file mode 100644 index 2346b575e1d..00000000000 --- a/gnu/usr.bin/groff/pic/TODO +++ /dev/null @@ -1,37 +0,0 @@ -Dotted and dashed ellipses. - -In troff mode, dotted and dashed splines. - -Make DELIMITED have type lstr; this would allow us to give better -error messages for problems within the body of for and if constructs. - -In troff mode without -x, fake \D't' with .ps commands. - -Perhaps an option to set command char. - -Add an output class for dumb line printers. It wouldn't be pretty but -it would be better than nothing. Integrate it with texinfo. Useful -for groff -Tascii as well. - -Option to allow better positioning of arrowheads on arcs. - -Perhaps add PostScript output mode. - -Change the interface to the output class so that output devices have -the opportunity to handle arrowheads themselves. - -Consider whether the line thickness should scale. - -Consider whether the test in a for loop should be fuzzy (as it -apparently is in grap). - -Possibly change fillval so that zero is black. - -Provide a way of getting text blocks (positioned with `.in' rather -than \h), into pic. Should be possible to use block of diverted text -in pic. Possibly something similar to T{ and T} in tbl. - -Option to provide macro backtraces. - -Have a path that is searched by `copy' statement. Set by environment -variable or command line option. diff --git a/gnu/usr.bin/groff/pic/common.cc b/gnu/usr.bin/groff/pic/common.cc deleted file mode 100644 index e83ef312258..00000000000 --- a/gnu/usr.bin/groff/pic/common.cc +++ /dev/null @@ -1,497 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "pic.h" -#include "common.h" - -// output a dashed circle as a series of arcs - -void common_output::dashed_circle(const position ¢, double rad, - const line_type <) -{ - assert(lt.type == line_type::dashed); - line_type slt = lt; - slt.type = line_type::solid; - double dash_angle = lt.dash_width/rad; - int ndashes; - double gap_angle; - if (dash_angle >= M_PI/4.0) { - if (dash_angle < M_PI/2.0) { - gap_angle = M_PI/2.0 - dash_angle; - ndashes = 4; - } - else if (dash_angle < M_PI) { - gap_angle = M_PI - dash_angle; - ndashes = 2; - } - else { - circle(cent, rad, slt, -1.0); - return; - } - } - else { - ndashes = 4*int(ceil(M_PI/(4.0*dash_angle))); - gap_angle = (M_PI*2.0)/ndashes - dash_angle; - } - for (int i = 0; i < ndashes; i++) { - double start_angle = i*(dash_angle+gap_angle) - dash_angle/2.0; - solid_arc(cent, rad, start_angle, start_angle + dash_angle, lt); - } -} - -// output a dotted circle as a series of dots - -void common_output::dotted_circle(const position ¢, double rad, - const line_type <) -{ - assert(lt.type == line_type::dotted); - double gap_angle = lt.dash_width/rad; - int ndots; - if (gap_angle >= M_PI/2.0) { - // always have at least 2 dots - gap_angle = M_PI; - ndots = 2; - } - else { - ndots = 4*int(M_PI/(2.0*gap_angle)); - gap_angle = (M_PI*2.0)/ndots; - } - double ang = 0.0; - for (int i = 0; i < ndots; i++, ang += gap_angle) - dot(cent + position(cos(ang), sin(ang))*rad, lt); -} - -// return non-zero iff we can compute a center - -int compute_arc_center(const position &start, const position ¢, - const position &end, position *result) -{ - // This finds the point along the vector from start to cent that - // is equidistant between start and end. - distance c = cent - start; - distance e = end - start; - double n = c*e; - if (n == 0.0) - return 0; - *result = start + c*((e*e)/(2.0*n)); - return 1; -} - -// output a dashed arc as a series of arcs - -void common_output::dashed_arc(const position &start, const position ¢, - const position &end, const line_type <) -{ - assert(lt.type == line_type::dashed); - position c; - if (!compute_arc_center(start, cent, end, &c)) { - line(start, &end, 1, lt); - return; - } - distance start_offset = start - c; - distance end_offset = end - c; - double start_angle = atan2(start_offset.y, start_offset.x); - double end_angle = atan2(end_offset.y, end_offset.x); - double rad = hypot(c - start); - double dash_angle = lt.dash_width/rad; - double total_angle = end_angle - start_angle; - while (total_angle < 0) - total_angle += M_PI + M_PI; - if (total_angle <= dash_angle*2.0) { - solid_arc(cent, rad, start_angle, end_angle, lt); - return; - } - int ndashes = int((total_angle - dash_angle)/(dash_angle*2.0) + .5); - double dash_and_gap_angle = (total_angle - dash_angle)/ndashes; - for (int i = 0; i <= ndashes; i++) - solid_arc(cent, rad, start_angle + i*dash_and_gap_angle, - start_angle + i*dash_and_gap_angle + dash_angle, lt); -} - -// output a dotted arc as a series of dots - -void common_output::dotted_arc(const position &start, const position ¢, - const position &end, const line_type <) -{ - assert(lt.type == line_type::dotted); - position c; - if (!compute_arc_center(start, cent, end, &c)) { - line(start, &end, 1, lt); - return; - } - distance start_offset = start - c; - distance end_offset = end - c; - double start_angle = atan2(start_offset.y, start_offset.x); - double total_angle = atan2(end_offset.y, end_offset.x) - start_angle; - while (total_angle < 0) - total_angle += M_PI + M_PI; - double rad = hypot(c - start); - int ndots = int(total_angle/(lt.dash_width/rad) + .5); - if (ndots == 0) - dot(start, lt); - else { - for (int i = 0; i <= ndots; i++) { - double a = start_angle + (total_angle*i)/ndots; - dot(cent + position(cos(a), sin(a))*rad, lt); - } - } -} - -void common_output::solid_arc(const position ¢, double rad, - double start_angle, double end_angle, - const line_type <) -{ - line_type slt = lt; - slt.type = line_type::solid; - arc(cent + position(cos(start_angle), sin(start_angle))*rad, - cent, - cent + position(cos(end_angle), sin(end_angle))*rad, - slt); -} - - -void common_output::rounded_box(const position ¢, const distance &dim, - double rad, const line_type <, double fill) -{ - if (fill >= 0.0) - filled_rounded_box(cent, dim, rad, fill); - switch (lt.type) { - case line_type::invisible: - break; - case line_type::dashed: - dashed_rounded_box(cent, dim, rad, lt); - break; - case line_type::dotted: - dotted_rounded_box(cent, dim, rad, lt); - break; - case line_type::solid: - solid_rounded_box(cent, dim, rad, lt); - break; - default: - assert(0); - } -} - - -void common_output::dashed_rounded_box(const position ¢, - const distance &dim, double rad, - const line_type <) -{ - line_type slt = lt; - slt.type = line_type::solid; - - double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad; - int n_hor_dashes = int(hor_length/(lt.dash_width*2.0) + .5); - double hor_gap_width = (n_hor_dashes != 0 - ? hor_length/n_hor_dashes - lt.dash_width - : 0.0); - - double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad; - int n_vert_dashes = int(vert_length/(lt.dash_width*2.0) + .5); - double vert_gap_width = (n_vert_dashes != 0 - ? vert_length/n_vert_dashes - lt.dash_width - : 0.0); - // Note that each corner arc has to be split into two for dashing, - // because one part is dashed using vert_gap_width, and the other - // using hor_gap_width. - double offset = lt.dash_width/2.0; - dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, - -M_PI/4.0, 0, slt, lt.dash_width, vert_gap_width, &offset); - dash_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad), - cent + position(dim.x/2.0, dim.y/2.0 - rad), - slt, lt.dash_width, vert_gap_width, &offset); - dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, - 0, M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset); - - offset = lt.dash_width/2.0; - dash_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, - M_PI/4.0, M_PI/2, slt, lt.dash_width, hor_gap_width, &offset); - dash_line(cent + position(dim.x/2.0 - rad, dim.y/2.0), - cent + position(-dim.x/2.0 + rad, dim.y/2.0), - slt, lt.dash_width, hor_gap_width, &offset); - dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, - M_PI/2, 3*M_PI/4.0, slt, lt.dash_width, hor_gap_width, &offset); - - offset = lt.dash_width/2.0; - dash_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, - 3.0*M_PI/4.0, M_PI, slt, lt.dash_width, vert_gap_width, &offset); - dash_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad), - cent + position(-dim.x/2.0, -dim.y/2.0 + rad), - slt, lt.dash_width, vert_gap_width, &offset); - dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, - M_PI, 5.0*M_PI/4.0, slt, lt.dash_width, vert_gap_width, &offset); - - offset = lt.dash_width/2.0; - dash_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, - 5*M_PI/4.0, 3*M_PI/2.0, slt, lt.dash_width, hor_gap_width, &offset); - dash_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0), - cent + position(dim.x/2.0 - rad, -dim.y/2.0), - slt, lt.dash_width, hor_gap_width, &offset); - dash_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, - 3*M_PI/2, 7*M_PI/4, slt, lt.dash_width, hor_gap_width, &offset); -} - -// Used by dashed_rounded_box. - -void common_output::dash_arc(const position ¢, double rad, - double start_angle, double end_angle, - const line_type <, - double dash_width, double gap_width, - double *offsetp) -{ - double length = (end_angle - start_angle)*rad; - double pos = 0.0; - for (;;) { - if (*offsetp >= dash_width) { - double rem = dash_width + gap_width - *offsetp; - if (pos + rem > length) { - *offsetp += length - pos; - break; - } - else { - pos += rem; - *offsetp = 0.0; - } - } - else { - double rem = dash_width - *offsetp; - if (pos + rem > length) { - solid_arc(cent, rad, start_angle + pos/rad, end_angle, lt); - *offsetp += length - pos; - break; - } - else { - solid_arc(cent, rad, start_angle + pos/rad, - start_angle + (pos + rem)/rad, lt); - pos += rem; - *offsetp = dash_width; - } - } - } -} - -// Used by dashed_rounded_box. - -void common_output::dash_line(const position &start, const position &end, - const line_type <, - double dash_width, double gap_width, - double *offsetp) -{ - distance dist = end - start; - double length = hypot(dist); - if (length == 0.0) - return; - double pos = 0.0; - for (;;) { - if (*offsetp >= dash_width) { - double rem = dash_width + gap_width - *offsetp; - if (pos + rem > length) { - *offsetp += length - pos; - break; - } - else { - pos += rem; - *offsetp = 0.0; - } - } - else { - double rem = dash_width - *offsetp; - if (pos + rem > length) { - line(start + dist*(pos/length), &end, 1, lt); - *offsetp += length - pos; - break; - } - else { - position p(start + dist*((pos + rem)/length)); - line(start + dist*(pos/length), &p, 1, lt); - pos += rem; - *offsetp = dash_width; - } - } - } -} - -void common_output::dotted_rounded_box(const position ¢, - const distance &dim, double rad, - const line_type <) -{ - line_type slt = lt; - slt.type = line_type::solid; - - double hor_length = dim.x + (M_PI/2.0 - 2.0)*rad; - int n_hor_dots = int(hor_length/lt.dash_width + .5); - double hor_gap_width = (n_hor_dots != 0 - ? hor_length/n_hor_dots - : lt.dash_width); - - double vert_length = dim.y + (M_PI/2.0 - 2.0)*rad; - int n_vert_dots = int(vert_length/lt.dash_width + .5); - double vert_gap_width = (n_vert_dots != 0 - ? vert_length/n_vert_dots - : lt.dash_width); - double epsilon = lt.dash_width/(rad*100.0); - - double offset = 0.0; - dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, - -M_PI/4.0, 0, slt, vert_gap_width, &offset); - dot_line(cent + position(dim.x/2.0, -dim.y/2.0 + rad), - cent + position(dim.x/2.0, dim.y/2.0 - rad), - slt, vert_gap_width, &offset); - dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, - 0, M_PI/4.0 - epsilon, slt, vert_gap_width, &offset); - - offset = 0.0; - dot_arc(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, - M_PI/4.0, M_PI/2, slt, hor_gap_width, &offset); - dot_line(cent + position(dim.x/2.0 - rad, dim.y/2.0), - cent + position(-dim.x/2.0 + rad, dim.y/2.0), - slt, hor_gap_width, &offset); - dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, - M_PI/2, 3*M_PI/4.0 - epsilon, slt, hor_gap_width, &offset); - - offset = 0.0; - dot_arc(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, - 3.0*M_PI/4.0, M_PI, slt, vert_gap_width, &offset); - dot_line(cent + position(-dim.x/2.0, dim.y/2.0 - rad), - cent + position(-dim.x/2.0, -dim.y/2.0 + rad), - slt, vert_gap_width, &offset); - dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, - M_PI, 5.0*M_PI/4.0 - epsilon, slt, vert_gap_width, &offset); - - offset = 0.0; - dot_arc(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, - 5*M_PI/4.0, 3*M_PI/2.0, slt, hor_gap_width, &offset); - dot_line(cent + position(-dim.x/2.0 + rad, -dim.y/2.0), - cent + position(dim.x/2.0 - rad, -dim.y/2.0), - slt, hor_gap_width, &offset); - dot_arc(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, - 3*M_PI/2, 7*M_PI/4 - epsilon, slt, hor_gap_width, &offset); -} - -// Used by dotted_rounded_box. - -void common_output::dot_arc(const position ¢, double rad, - double start_angle, double end_angle, - const line_type <, double gap_width, - double *offsetp) -{ - double length = (end_angle - start_angle)*rad; - double pos = 0.0; - for (;;) { - if (*offsetp == 0.0) { - double ang = start_angle + pos/rad; - dot(cent + position(cos(ang), sin(ang))*rad, lt); - } - double rem = gap_width - *offsetp; - if (pos + rem > length) { - *offsetp += length - pos; - break; - } - else { - pos += rem; - *offsetp = 0.0; - } - } -} - -// Used by dotted_rounded_box. - -void common_output::dot_line(const position &start, const position &end, - const line_type <, double gap_width, - double *offsetp) -{ - distance dist = end - start; - double length = hypot(dist); - if (length == 0.0) - return; - double pos = 0.0; - for (;;) { - if (*offsetp == 0.0) - dot(start + dist*(pos/length), lt); - double rem = gap_width - *offsetp; - if (pos + rem > length) { - *offsetp += length - pos; - break; - } - else { - pos += rem; - *offsetp = 0.0; - } - } -} - - -void common_output::solid_rounded_box(const position ¢, - const distance &dim, double rad, - const line_type <) -{ - position tem = cent - dim/2.0; - arc(tem + position(0.0, rad), - tem + position(rad, rad), - tem + position(rad, 0.0), - lt); - tem = cent + position(-dim.x/2.0, dim.y/2.0); - arc(tem + position(rad, 0.0), - tem + position(rad, -rad), - tem + position(0.0, -rad), - lt); - tem = cent + dim/2.0; - arc(tem + position(0.0, -rad), - tem + position(-rad, -rad), - tem + position(-rad, 0.0), - lt); - tem = cent + position(dim.x/2.0, -dim.y/2.0); - arc(tem + position(-rad, 0.0), - tem + position(-rad, rad), - tem + position(0.0, rad), - lt); - position end; - end = cent + position(-dim.x/2.0, dim.y/2.0 - rad); - line(cent - dim/2.0 + position(0.0, rad), &end, 1, lt); - end = cent + position(dim.x/2.0 - rad, dim.y/2.0); - line(cent + position(-dim.x/2.0 + rad, dim.y/2.0), &end, 1, lt); - end = cent + position(dim.x/2.0, -dim.y/2.0 + rad); - line(cent + position(dim.x/2.0, dim.y/2.0 - rad), &end, 1, lt); - end = cent + position(-dim.x/2.0 + rad, -dim.y/2.0); - line(cent + position(dim.x/2.0 - rad, -dim.y/2.0), &end, 1, lt); -} - -void common_output::filled_rounded_box(const position ¢, - const distance &dim, double rad, - double fill) -{ - line_type ilt; - ilt.type = line_type::invisible; - circle(cent + position(dim.x/2.0 - rad, dim.y/2.0 - rad), rad, ilt, fill); - circle(cent + position(-dim.x/2.0 + rad, dim.y/2.0 - rad), rad, ilt, fill); - circle(cent + position(-dim.x/2.0 + rad, -dim.y/2.0 + rad), rad, ilt, fill); - circle(cent + position(dim.x/2.0 - rad, -dim.y/2.0 + rad), rad, ilt, fill); - position vec[4]; - vec[0] = cent + position(dim.x/2.0, dim.y/2.0 - rad); - vec[1] = cent + position(-dim.x/2.0, dim.y/2.0 - rad); - vec[2] = cent + position(-dim.x/2.0, -dim.y/2.0 + rad); - vec[3] = cent + position(dim.x/2.0, -dim.y/2.0 + rad); - polygon(vec, 4, ilt, fill); - vec[0] = cent + position(dim.x/2.0 - rad, dim.y/2.0); - vec[1] = cent + position(-dim.x/2.0 + rad, dim.y/2.0); - vec[2] = cent + position(-dim.x/2.0 + rad, -dim.y/2.0); - vec[3] = cent + position(dim.x/2.0 - rad, -dim.y/2.0); - polygon(vec, 4, ilt, fill); -} diff --git a/gnu/usr.bin/groff/pic/common.h b/gnu/usr.bin/groff/pic/common.h deleted file mode 100644 index 25a6e10c689..00000000000 --- a/gnu/usr.bin/groff/pic/common.h +++ /dev/null @@ -1,70 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -class common_output : public output { -private: - void dash_line(const position &start, const position &end, - const line_type <, double dash_width, double gap_width, - double *offsetp); - void dash_arc(const position ¢, double rad, - double start_angle, double end_angle, const line_type <, - double dash_width, double gap_width, double *offsetp); - void dot_line(const position &start, const position &end, - const line_type <, double gap_width, double *offsetp); - void dot_arc(const position ¢, double rad, - double start_angle, double end_angle, const line_type <, - double gap_width, double *offsetp); -protected: - virtual void dot(const position &, const line_type &) = 0; - void dashed_circle(const position &, double rad, const line_type &); - void dotted_circle(const position &, double rad, const line_type &); - void dashed_arc(const position &, const position &, const position &, - const line_type &); - void dotted_arc(const position &, const position &, const position &, - const line_type &); - virtual void solid_arc(const position ¢, double rad, double start_angle, - double end_angle, const line_type <); - void dashed_rounded_box(const position &, const distance &, double, - const line_type &); - void dotted_rounded_box(const position &, const distance &, double, - const line_type &); - void solid_rounded_box(const position &, const distance &, double, - const line_type &); - void filled_rounded_box(const position &, const distance &, double, double); -public: - void start_picture(double sc, const position &ll, const position &ur) = 0; - void finish_picture() = 0; - void circle(const position &, double rad, const line_type &, double) = 0; - void text(const position &, text_piece *, int, double) = 0; - void line(const position &, const position *, int n, const line_type &) = 0; - void polygon(const position *, int n, const line_type &, double) = 0; - void spline(const position &, const position *, int n, - const line_type &) = 0; - void arc(const position &, const position &, const position &, - const line_type &) = 0; - void ellipse(const position &, const distance &, - const line_type &, double) = 0; - void rounded_box(const position &, const distance &, double, - const line_type &, double); -}; - -int compute_arc_center(const position &start, const position ¢, - const position &end, position *result); - diff --git a/gnu/usr.bin/groff/pic/depend b/gnu/usr.bin/groff/pic/depend deleted file mode 100644 index 73ac3ab9093..00000000000 --- a/gnu/usr.bin/groff/pic/depend +++ /dev/null @@ -1,21 +0,0 @@ -pic.tab.o : pic.tab.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h ../lib/ptable.h object.h -lex.o : lex.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h ../lib/ptable.h object.h pic.tab.h -main.o : main.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h -object.o : object.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h ../lib/ptable.h object.h -common.o : common.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h common.h -troff.o : troff.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h common.h -tex.o : tex.cc pic.h ../lib/assert.h ../lib/cset.h ../lib/lib.h \ - ../lib/stringclass.h ../lib/errarg.h ../lib/error.h position.h text.h \ - output.h common.h diff --git a/gnu/usr.bin/groff/pic/lex.cc b/gnu/usr.bin/groff/pic/lex.cc deleted file mode 100644 index 920938d538e..00000000000 --- a/gnu/usr.bin/groff/pic/lex.cc +++ /dev/null @@ -1,1939 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "pic.h" -#include "ptable.h" -#include "object.h" -#include "pic.tab.h" - -declare_ptable(char) -implement_ptable(char) - -PTABLE(char) macro_table; - -class macro_input : public input { - char *s; - char *p; -public: - macro_input(const char *); - ~macro_input(); - int get(); - int peek(); -}; - -class argument_macro_input : public input { - char *s; - char *p; - char *ap; - int argc; - char *argv[9]; -public: - argument_macro_input(const char *, int, char **); - ~argument_macro_input(); - int get(); - int peek(); -}; - -input::input() : next(0) -{ -} - -input::~input() -{ -} - -int input::get_location(const char **, int *) -{ - return 0; -} - -file_input::file_input(FILE *f, const char *fn) -: lineno(0), ptr(""), filename(fn) -{ - fp = f; -} - -file_input::~file_input() -{ - fclose(fp); -} - -int file_input::read_line() -{ - for (;;) { - line.clear(); - lineno++; - for (;;) { - int c = getc(fp); - if (c == EOF) - break; - else if (illegal_input_char(c)) - lex_error("illegal input character code %1", c); - else { - line += char(c); - if (c == '\n') - break; - } - } - if (line.length() == 0) - return 0; - if (!(line.length() >= 3 && line[0] == '.' && line[1] == 'P' - && (line[2] == 'S' || line[2] == 'E' || line[2] == 'F') - && (line.length() == 3 || line[3] == ' ' || line[3] == '\n' - || compatible_flag))) { - line += '\0'; - ptr = line.contents(); - return 1; - } - } -} - -int file_input::get() -{ - if (*ptr != '\0' || read_line()) - return (unsigned char)*ptr++; - else - return EOF; -} - -int file_input::peek() -{ - if (*ptr != '\0' || read_line()) - return (unsigned char)*ptr; - else - return EOF; -} - -int file_input::get_location(const char **fnp, int *lnp) -{ - *fnp = filename; - *lnp = lineno; - return 1; -} - -macro_input::macro_input(const char *str) -{ - p = s = strsave(str); -} - -macro_input::~macro_input() -{ - a_delete s; -} - -int macro_input::get() -{ - if (p == 0 || *p == '\0') - return EOF; - else - return (unsigned char)*p++; -} - -int macro_input::peek() -{ - if (p == 0 || *p == '\0') - return EOF; - else - return (unsigned char)*p; -} - -// Character representing $1. Must be illegal input character. -#define ARG1 14 - -char *process_body(const char *body) -{ - char *s = strsave(body); - int j = 0; - for (int i = 0; s[i] != '\0'; i++) - if (s[i] == '$' && s[i+1] >= '0' && s[i+1] <= '9') { - if (s[i+1] != '0') - s[j++] = ARG1 + s[++i] - '1'; - } - else - s[j++] = s[i]; - s[j] = '\0'; - return s; -} - - -argument_macro_input::argument_macro_input(const char *body, int ac, char **av) -: argc(ac), ap(0) -{ - for (int i = 0; i < argc; i++) - argv[i] = av[i]; - p = s = process_body(body); -} - - -argument_macro_input::~argument_macro_input() -{ - for (int i = 0; i < argc; i++) - a_delete argv[i]; - a_delete s; -} - -int argument_macro_input::get() -{ - if (ap) { - if (*ap != '\0') - return (unsigned char)*ap++; - ap = 0; - } - if (p == 0) - return EOF; - while (*p >= ARG1 && *p <= ARG1 + 8) { - int i = *p++ - ARG1; - if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { - ap = argv[i]; - return (unsigned char)*ap++; - } - } - if (*p == '\0') - return EOF; - return (unsigned char)*p++; -} - -int argument_macro_input::peek() -{ - if (ap) { - if (*ap != '\0') - return (unsigned char)*ap; - ap = 0; - } - if (p == 0) - return EOF; - while (*p >= ARG1 && *p <= ARG1 + 8) { - int i = *p++ - ARG1; - if (i < argc && argv[i] != 0 && argv[i][0] != '\0') { - ap = argv[i]; - return (unsigned char)*ap; - } - } - if (*p == '\0') - return EOF; - return (unsigned char)*p; -} - -class input_stack { - static input *current_input; - static int bol_flag; -public: - static void push(input *); - static void clear(); - static int get_char(); - static int peek_char(); - static int get_location(const char **fnp, int *lnp); - static void push_back(unsigned char c, int was_bol = 0); - static int bol(); -}; - -input *input_stack::current_input = 0; -int input_stack::bol_flag = 0; - -inline int input_stack::bol() -{ - return bol_flag; -} - -void input_stack::clear() -{ - while (current_input != 0) { - input *tem = current_input; - current_input = current_input->next; - delete tem; - } - bol_flag = 1; -} - -void input_stack::push(input *in) -{ - in->next = current_input; - current_input = in; -} - -void lex_init(input *top) -{ - input_stack::clear(); - input_stack::push(top); -} - -void lex_cleanup() -{ - while (input_stack::get_char() != EOF) - ; -} - -int input_stack::get_char() -{ - while (current_input != 0) { - int c = current_input->get(); - if (c != EOF) { - bol_flag = c == '\n'; - return c; - } - // don't pop the top-level input off the stack - if (current_input->next == 0) - return EOF; - input *tem = current_input; - current_input = current_input->next; - delete tem; - } - return EOF; -} - -int input_stack::peek_char() -{ - while (current_input != 0) { - int c = current_input->peek(); - if (c != EOF) - return c; - if (current_input->next == 0) - return EOF; - input *tem = current_input; - current_input = current_input->next; - delete tem; - } - return EOF; -} - -class char_input : public input { - int c; -public: - char_input(int); - int get(); - int peek(); -}; - -char_input::char_input(int n) : c((unsigned char)n) -{ -} - -int char_input::get() -{ - int n = c; - c = EOF; - return n; -} - -int char_input::peek() -{ - return c; -} - -void input_stack::push_back(unsigned char c, int was_bol) -{ - push(new char_input(c)); - bol_flag = was_bol; -} - -int input_stack::get_location(const char **fnp, int *lnp) -{ - for (input *p = current_input; p; p = p->next) - if (p->get_location(fnp, lnp)) - return 1; - return 0; -} - -string context_buffer; - -string token_buffer; -double token_double; -int token_int; - -void interpolate_macro_with_args(const char *body) -{ - char *argv[9]; - int argc = 0; - int i; - for (i = 0; i < 9; i++) - argv[i] = 0; - int level = 0; - int c; - enum { NORMAL, IN_STRING, IN_STRING_QUOTED } state = NORMAL; - do { - token_buffer.clear(); - for (;;) { - c = input_stack::get_char(); - if (c == EOF) { - lex_error("end of input while scanning macro arguments"); - break; - } - if (state == NORMAL && level == 0 && (c == ',' || c == ')')) { - if (token_buffer.length() > 0) { - token_buffer += '\0'; - argv[argc] = strsave(token_buffer.contents()); - } - // for `foo()', argc = 0 - if (argc > 0 || c != ')' || i > 0) - argc++; - break; - } - token_buffer += char(c); - switch (state) { - case NORMAL: - if (c == '"') - state = IN_STRING; - else if (c == '(') - level++; - else if (c == ')') - level--; - break; - case IN_STRING: - if (c == '"') - state = NORMAL; - else if (c == '\\') - state = IN_STRING_QUOTED; - break; - case IN_STRING_QUOTED: - state = IN_STRING; - break; - } - } - } while (c != ')' && c != EOF); - input_stack::push(new argument_macro_input(body, argc, argv)); -} - -static int docmp(const char *s1, int n1, const char *s2, int n2) -{ - if (n1 < n2) { - int r = memcmp(s1, s2, n1); - return r ? r : -1; - } - else if (n1 > n2) { - int r = memcmp(s1, s2, n2); - return r ? r : 1; - } - else - return memcmp(s1, s2, n1); -} - -int lookup_keyword(const char *str, int len) -{ - static struct keyword { - const char *name; - int token; - } table[] = { - { "Here", HERE }, - { "above", ABOVE }, - { "aligned", ALIGNED }, - { "and", AND }, - { "arc", ARC }, - { "arrow", ARROW }, - { "at", AT }, - { "atan2", ATAN2 }, - { "below", BELOW }, - { "between", BETWEEN }, - { "bottom", BOTTOM }, - { "box", BOX }, - { "by", BY }, - { "ccw", CCW }, - { "center", CENTER }, - { "chop", CHOP }, - { "circle", CIRCLE }, - { "command", COMMAND }, - { "copy", COPY }, - { "cos", COS }, - { "cw", CW }, - { "dashed", DASHED }, - { "define", DEFINE }, - { "diam", DIAMETER }, - { "diameter", DIAMETER }, - { "do", DO }, - { "dotted", DOTTED }, - { "down", DOWN }, - { "ellipse", ELLIPSE }, - { "else", ELSE }, - { "end", END }, - { "exp", EXP }, - { "fill", FILL }, - { "filled", FILL }, - { "for", FOR }, - { "from", FROM }, - { "height", HEIGHT }, - { "ht", HEIGHT }, - { "if", IF }, - { "int", INT }, - { "invis", INVISIBLE }, - { "invisible", INVISIBLE }, - { "last", LAST }, - { "left", LEFT }, - { "line", LINE }, - { "ljust", LJUST }, - { "log", LOG }, - { "lower", LOWER }, - { "max", K_MAX }, - { "min", K_MIN }, - { "move", MOVE }, - { "of", OF }, - { "plot", PLOT }, - { "print", PRINT }, - { "rad", RADIUS }, - { "radius", RADIUS }, - { "rand", RAND }, - { "reset", RESET }, - { "right", RIGHT }, - { "rjust", RJUST }, - { "same", SAME }, - { "sh", SH }, - { "sin", SIN }, - { "spline", SPLINE }, - { "sprintf", SPRINTF }, - { "sqrt", SQRT }, - { "start", START }, - { "the", THE }, - { "then", THEN }, - { "thick", THICKNESS }, - { "thickness", THICKNESS }, - { "thru", THRU }, - { "to", TO }, - { "top", TOP }, - { "undef", UNDEF }, - { "until", UNTIL }, - { "up", UP }, - { "upper", UPPER }, - { "way", WAY }, - { "wid", WIDTH }, - { "width", WIDTH }, - { "with", WITH }, - }; - - const keyword *start = table; - const keyword *end = table + sizeof(table)/sizeof(table[0]); - while (start < end) { - // start <= target < end - const keyword *mid = start + (end - start)/2; - - int cmp = docmp(str, len, mid->name, strlen(mid->name)); - if (cmp == 0) - return mid->token; - if (cmp < 0) - end = mid; - else - start = mid + 1; - } - return 0; -} - -int get_token_after_dot(int c) -{ - // get_token deals with the case where c is a digit - switch (c) { - case 'h': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - context_buffer = ".ht"; - return DOT_HT; - } - else if (c == 'e') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'i') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'g') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'h') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - context_buffer = ".height"; - return DOT_HT; - } - input_stack::push_back('h'); - } - input_stack::push_back('g'); - } - input_stack::push_back('i'); - } - input_stack::push_back('e'); - } - input_stack::push_back('h'); - return '.'; - case 'x': - input_stack::get_char(); - context_buffer = ".x"; - return DOT_X; - case 'y': - input_stack::get_char(); - context_buffer = ".y"; - return DOT_Y; - case 'c': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'e') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'n') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'e') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'r') { - input_stack::get_char(); - context_buffer = ".center"; - return DOT_C; - } - input_stack::push_back('e'); - } - input_stack::push_back('t'); - } - input_stack::push_back('n'); - } - input_stack::push_back('e'); - } - context_buffer = ".c"; - return DOT_C; - case 'n': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'e') { - input_stack::get_char(); - context_buffer = ".ne"; - return DOT_NE; - } - else if (c == 'w') { - input_stack::get_char(); - context_buffer = ".nw"; - return DOT_NW; - } - else { - context_buffer = ".n"; - return DOT_N; - } - break; - case 'e': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'n') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'd') { - input_stack::get_char(); - context_buffer = ".end"; - return DOT_END; - } - input_stack::push_back('n'); - context_buffer = ".e"; - return DOT_E; - } - context_buffer = ".e"; - return DOT_E; - case 'w': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'i') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'd') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'h') { - input_stack::get_char(); - context_buffer = ".width"; - return DOT_WID; - } - input_stack::push_back('t'); - } - context_buffer = ".wid"; - return DOT_WID; - } - input_stack::push_back('i'); - } - context_buffer = ".w"; - return DOT_W; - case 's': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'e') { - input_stack::get_char(); - context_buffer = ".se"; - return DOT_SE; - } - else if (c == 'w') { - input_stack::get_char(); - context_buffer = ".sw"; - return DOT_SW; - } - else { - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'a') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'r') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - context_buffer = ".start"; - return DOT_START; - } - input_stack::push_back('r'); - } - input_stack::push_back('a'); - } - input_stack::push_back('t'); - } - context_buffer = ".s"; - return DOT_S; - } - break; - case 't': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'o') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'p') { - input_stack::get_char(); - context_buffer = ".top"; - return DOT_N; - } - input_stack::push_back('o'); - } - context_buffer = ".t"; - return DOT_N; - case 'l': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'e') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'f') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - context_buffer = ".left"; - return DOT_W; - } - input_stack::push_back('f'); - } - input_stack::push_back('e'); - } - context_buffer = ".l"; - return DOT_W; - case 'r': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'a') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'd') { - input_stack::get_char(); - context_buffer = ".rad"; - return DOT_RAD; - } - input_stack::push_back('a'); - } - else if (c == 'i') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'g') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'h') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - context_buffer = ".right"; - return DOT_E; - } - input_stack::push_back('h'); - } - input_stack::push_back('g'); - } - input_stack::push_back('i'); - } - context_buffer = ".r"; - return DOT_E; - case 'b': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'o') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'o') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'm') { - input_stack::get_char(); - context_buffer = ".bottom"; - return DOT_S; - } - input_stack::push_back('o'); - } - input_stack::push_back('t'); - } - context_buffer = ".bot"; - return DOT_S; - } - input_stack::push_back('o'); - } - context_buffer = ".b"; - return DOT_S; - default: - context_buffer = '.'; - return '.'; - } -} - -int get_token(int lookup_flag) -{ - context_buffer.clear(); - for (;;) { - int n = 0; - int bol = input_stack::bol(); - int c = input_stack::get_char(); - if (bol && c == command_char) { - token_buffer.clear(); - token_buffer += c; - // the newline is not part of the token - for (;;) { - c = input_stack::peek_char(); - if (c == EOF || c == '\n') - break; - input_stack::get_char(); - token_buffer += char(c); - } - context_buffer = token_buffer; - return COMMAND_LINE; - } - switch (c) { - case EOF: - return EOF; - case ' ': - case '\t': - break; - case '\\': - { - int d = input_stack::peek_char(); - if (d != '\n') { - context_buffer = '\\'; - return '\\'; - } - input_stack::get_char(); - break; - } - case '#': - do { - c = input_stack::get_char(); - } while (c != '\n' && c != EOF); - if (c == '\n') - context_buffer = '\n'; - return c; - case '"': - context_buffer = '"'; - token_buffer.clear(); - for (;;) { - c = input_stack::get_char(); - if (c == '\\') { - context_buffer += '\\'; - c = input_stack::peek_char(); - if (c == '"') { - input_stack::get_char(); - token_buffer += '"'; - context_buffer += '"'; - } - else - token_buffer += '\\'; - } - else if (c == '\n') { - error("newline in string"); - break; - } - else if (c == EOF) { - error("missing `\"'"); - break; - } - else if (c == '"') { - context_buffer += '"'; - break; - } - else { - context_buffer += char(c); - token_buffer += char(c); - } - } - return TEXT; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - int overflow = 0; - n = 0; - for (;;) { - if (n > (INT_MAX - 9)/10) { - overflow = 1; - break; - } - n *= 10; - n += c - '0'; - context_buffer += char(c); - c = input_stack::peek_char(); - if (c == EOF || !csdigit(c)) - break; - c = input_stack::get_char(); - } - token_double = n; - if (overflow) { - for (;;) { - token_double *= 10.0; - token_double += c - '0'; - context_buffer += char(c); - c = input_stack::peek_char(); - if (c == EOF || !csdigit(c)) - break; - c = input_stack::get_char(); - } - // if somebody asks for 1000000000000th, we will silently - // give them INT_MAXth - double temp = token_double; // work around gas 1.34/sparc bug - if (token_double > INT_MAX) - n = INT_MAX; - else - n = int(temp); - } - } - switch (c) { - case 'i': - case 'I': - context_buffer += char(c); - input_stack::get_char(); - return NUMBER; - case '.': - { - context_buffer += '.'; - input_stack::get_char(); - got_dot: - double factor = 1.0; - for (;;) { - c = input_stack::peek_char(); - if (!c == EOF || !csdigit(c)) - break; - input_stack::get_char(); - context_buffer += char(c); - factor /= 10.0; - if (c != '0') - token_double += factor*(c - '0'); - } - if (c != 'e' && c != 'E') { - if (c == 'i' || c == 'I') { - context_buffer += char(c); - input_stack::get_char(); - } - return NUMBER; - } - } - // fall through - case 'e': - case 'E': - { - int echar = c; - input_stack::get_char(); - c = input_stack::peek_char(); - int sign = '+'; - if (c == '+' || c == '-') { - sign = c; - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == EOF || !csdigit(c)) { - input_stack::push_back(sign); - input_stack::push_back(echar); - return NUMBER; - } - context_buffer += char(echar); - context_buffer += char(sign); - } - else { - if (c == EOF || !csdigit(c)) { - input_stack::push_back(echar); - return NUMBER; - } - context_buffer += char(echar); - } - input_stack::get_char(); - context_buffer += char(c); - n = c - '0'; - for (;;) { - c = input_stack::peek_char(); - if (c == EOF || !csdigit(c)) - break; - input_stack::get_char(); - context_buffer += char(c); - n = n*10 + (c - '0'); - } - if (sign == '-') - n = -n; - if (c == 'i' || c == 'I') { - context_buffer += char(c); - input_stack::get_char(); - } - token_double *= pow(10.0, n); - return NUMBER; - } - case 'n': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'd') { - input_stack::get_char(); - token_int = n; - context_buffer += "nd"; - return ORDINAL; - } - input_stack::push_back('n'); - return NUMBER; - case 'r': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'd') { - input_stack::get_char(); - token_int = n; - context_buffer += "rd"; - return ORDINAL; - } - input_stack::push_back('r'); - return NUMBER; - case 't': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'h') { - input_stack::get_char(); - token_int = n; - context_buffer += "th"; - return ORDINAL; - } - input_stack::push_back('t'); - return NUMBER; - case 's': - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - token_int = n; - context_buffer += "st"; - return ORDINAL; - } - input_stack::push_back('s'); - return NUMBER; - default: - return NUMBER; - } - break; - case '\'': - { - c = input_stack::peek_char(); - if (c == 't') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == 'h') { - input_stack::get_char(); - context_buffer = "'th"; - return TH; - } - else - input_stack::push_back('t'); - } - context_buffer = "'"; - return '\''; - } - case '.': - { - c = input_stack::peek_char(); - if (c != EOF && csdigit(c)) { - n = 0; - token_double = 0.0; - context_buffer = '.'; - goto got_dot; - } - return get_token_after_dot(c); - } - case '<': - c = input_stack::peek_char(); - if (c == '-') { - input_stack::get_char(); - c = input_stack::peek_char(); - if (c == '>') { - input_stack::get_char(); - context_buffer = "<->"; - return DOUBLE_ARROW_HEAD; - } - context_buffer = "<-"; - return LEFT_ARROW_HEAD; - } - else if (c == '=') { - input_stack::get_char(); - context_buffer = "<="; - return LESSEQUAL; - } - context_buffer = "<"; - return '<'; - case '-': - c = input_stack::peek_char(); - if (c == '>') { - input_stack::get_char(); - context_buffer = "->"; - return RIGHT_ARROW_HEAD; - } - context_buffer = "-"; - return '-'; - case '!': - c = input_stack::peek_char(); - if (c == '=') { - input_stack::get_char(); - context_buffer = "!="; - return NOTEQUAL; - } - context_buffer = "!"; - return '!'; - case '>': - c = input_stack::peek_char(); - if (c == '=') { - input_stack::get_char(); - context_buffer = ">="; - return GREATEREQUAL; - } - context_buffer = ">"; - return '>'; - case '=': - c = input_stack::peek_char(); - if (c == '=') { - input_stack::get_char(); - context_buffer = "=="; - return EQUALEQUAL; - } - context_buffer = "="; - return '='; - case '&': - c = input_stack::peek_char(); - if (c == '&') { - input_stack::get_char(); - context_buffer = "&&"; - return ANDAND; - } - context_buffer = "&"; - return '&'; - case '|': - c = input_stack::peek_char(); - if (c == '|') { - input_stack::get_char(); - context_buffer = "||"; - return OROR; - } - context_buffer = "|"; - return '|'; - default: - if (c != EOF && csalpha(c)) { - token_buffer.clear(); - token_buffer = c; - for (;;) { - c = input_stack::peek_char(); - if (c == EOF || (!csalnum(c) && c != '_')) - break; - input_stack::get_char(); - token_buffer += char(c); - } - int tok = lookup_keyword(token_buffer.contents(), - token_buffer.length()); - if (tok != 0) { - context_buffer = token_buffer; - return tok; - } - char *def = 0; - if (lookup_flag) { - token_buffer += '\0'; - def = macro_table.lookup(token_buffer.contents()); - token_buffer.set_length(token_buffer.length() - 1); - if (def) { - if (c == '(') { - input_stack::get_char(); - interpolate_macro_with_args(def); - } - else - input_stack::push(new macro_input(def)); - } - } - if (!def) { - context_buffer = token_buffer; - if (csupper(token_buffer[0])) - return LABEL; - else - return VARIABLE; - } - } - else { - context_buffer = char(c); - return (unsigned char)c; - } - break; - } - } -} - -int get_delimited() -{ - token_buffer.clear(); - int c = input_stack::get_char(); - while (c == ' ' || c == '\t' || c == '\n') - c = input_stack::get_char(); - if (c == EOF) { - lex_error("missing delimiter"); - return 0; - } - context_buffer = char(c); - int had_newline = 0; - int start = c; - int level = 0; - enum { NORMAL, IN_STRING, IN_STRING_QUOTED, DELIM_END } state = NORMAL; - for (;;) { - c = input_stack::get_char(); - if (c == EOF) { - lex_error("missing closing delimiter"); - return 0; - } - if (c == '\n') - had_newline = 1; - else if (!had_newline) - context_buffer += char(c); - switch (state) { - case NORMAL: - if (start == '{') { - if (c == '{') { - level++; - break; - } - if (c == '}') { - if (--level < 0) - state = DELIM_END; - break; - } - } - else { - if (c == start) { - state = DELIM_END; - break; - } - } - if (c == '"') - state = IN_STRING; - break; - case IN_STRING_QUOTED: - if (c == '\n') - state = NORMAL; - else - state = IN_STRING; - break; - case IN_STRING: - if (c == '"' || c == '\n') - state = NORMAL; - else if (c == '\\') - state = IN_STRING_QUOTED; - break; - case DELIM_END: - // This case it just to shut cfront 2.0 up. - default: - assert(0); - } - if (state == DELIM_END) - break; - token_buffer += c; - } - return 1; -} - -void do_define() -{ - int t = get_token(0); // do not expand what we are defining - if (t != VARIABLE && t != LABEL) { - lex_error("can only define variable or placename"); - return; - } - token_buffer += '\0'; - string nm = token_buffer; - const char *name = nm.contents(); - if (!get_delimited()) - return; - token_buffer += '\0'; - macro_table.define(name, strsave(token_buffer.contents())); -} - -void do_undef() -{ - int t = get_token(0); // do not expand what we are undefining - if (t != VARIABLE && t != LABEL) { - lex_error("can only define variable or placename"); - return; - } - token_buffer += '\0'; - macro_table.define(token_buffer.contents(), 0); -} - - -class for_input : public input { - char *var; - char *body; - double to; - int by_is_multiplicative; - double by; - const char *p; - int done_newline; -public: - for_input(char *, double, int, double, char *); - ~for_input(); - int get(); - int peek(); -}; - -for_input::for_input(char *vr, double t, int bim, double b, char *bd) -: var(vr), to(t), by_is_multiplicative(bim), by(b), body(bd), p(body), - done_newline(0) -{ -} - -for_input::~for_input() -{ - a_delete var; - a_delete body; -} - -int for_input::get() -{ - if (p == 0) - return EOF; - for (;;) { - if (*p != '\0') - return (unsigned char)*p++; - if (!done_newline) { - done_newline = 1; - return '\n'; - } - double val; - if (!lookup_variable(var, &val)) { - lex_error("body of `for' terminated enclosing block"); - return EOF; - } - if (by_is_multiplicative) - val *= by; - else - val += by; - define_variable(var, val); - if (val > to) { - p = 0; - return EOF; - } - p = body; - done_newline = 0; - } -} - -int for_input::peek() -{ - if (p == 0) - return EOF; - if (*p != '\0') - return (unsigned char)*p; - if (!done_newline) - return '\n'; - double val; - if (!lookup_variable(var, &val)) - return EOF; - if (by_is_multiplicative) { - if (val * by > to) - return EOF; - } - else { - if (val + by > to) - return EOF; - } - if (*body == '\0') - return EOF; - return (unsigned char)*body; -} - -void do_for(char *var, double from, double to, int by_is_multiplicative, - double by, char *body) -{ - define_variable(var, from); - if (from <= to) - input_stack::push(new for_input(var, to, by_is_multiplicative, by, body)); -} - - -void do_copy(const char *filename) -{ - errno = 0; - FILE *fp = fopen(filename, "r"); - if (fp == 0) { - lex_error("can't open `%1': %2", filename, strerror(errno)); - return; - } - input_stack::push(new file_input(fp, filename)); -} - -class copy_thru_input : public input { - int done; - char *body; - char *until; - const char *p; - const char *ap; - int argv[9]; - int argc; - string line; - int get_line(); - virtual int inget() = 0; -public: - copy_thru_input(const char *b, const char *u); - ~copy_thru_input(); - int get(); - int peek(); -}; - -class copy_file_thru_input : public copy_thru_input { - input *in; -public: - copy_file_thru_input(input *, const char *b, const char *u); - ~copy_file_thru_input(); - int inget(); -}; - -copy_file_thru_input::copy_file_thru_input(input *i, const char *b, - const char *u) -: in(i), copy_thru_input(b, u) -{ -} - -copy_file_thru_input::~copy_file_thru_input() -{ - delete in; -} - -int copy_file_thru_input::inget() -{ - if (!in) - return EOF; - else - return in->get(); -} - -class copy_rest_thru_input : public copy_thru_input { -public: - copy_rest_thru_input(const char *, const char *u); - int inget(); -}; - -copy_rest_thru_input::copy_rest_thru_input(const char *b, const char *u) -: copy_thru_input(b, u) -{ -} - -int copy_rest_thru_input::inget() -{ - while (next != 0) { - int c = next->get(); - if (c != EOF) - return c; - if (next->next == 0) - return EOF; - input *tem = next; - next = next->next; - delete tem; - } - return EOF; - -} - -copy_thru_input::copy_thru_input(const char *b, const char *u) -: done(0) -{ - ap = 0; - body = process_body(b); - p = 0; - until = strsave(u); -} - - -copy_thru_input::~copy_thru_input() -{ - a_delete body; - a_delete until; -} - -int copy_thru_input::get() -{ - if (ap) { - if (*ap != '\0') - return (unsigned char)*ap++; - ap = 0; - } - for (;;) { - if (p == 0) { - if (!get_line()) - break; - p = body; - } - if (*p == '\0') { - p = 0; - return '\n'; - } - while (*p >= ARG1 && *p <= ARG1 + 8) { - int i = *p++ - ARG1; - if (i < argc && line[argv[i]] != '\0') { - ap = line.contents() + argv[i]; - return (unsigned char)*ap++; - } - } - if (*p != '\0') - return (unsigned char)*p++; - } - return EOF; -} - -int copy_thru_input::peek() -{ - if (ap) { - if (*ap != '\0') - return (unsigned char)*ap; - ap = 0; - } - for (;;) { - if (p == 0) { - if (!get_line()) - break; - p = body; - } - if (*p == '\0') - return '\n'; - while (*p >= ARG1 && *p <= ARG1 + 8) { - int i = *p++ - ARG1; - if (i < argc && line[argv[i]] != '\0') { - ap = line.contents() + argv[i]; - return (unsigned char)*ap; - } - } - if (*p != '\0') - return (unsigned char)*p; - } - return EOF; -} - -int copy_thru_input::get_line() -{ - if (done) - return 0; - line.clear(); - argc = 0; - int c = inget(); - for (;;) { - while (c == ' ') - c = inget(); - if (c == EOF || c == '\n') - break; - if (argc == 9) { - do { - c = inget(); - } while (c != '\n' && c != EOF); - break; - } - argv[argc++] = line.length(); - do { - line += char(c); - c = inget(); - } while (c != ' ' && c != '\n'); - line += '\0'; - } - if (until != 0 && argc > 0 && strcmp(&line[argv[0]], until) == 0) { - done = 1; - return 0; - } - return argc > 0 || c == '\n'; -} - -class simple_file_input : public input { - const char *filename; - int lineno; - FILE *fp; -public: - simple_file_input(FILE *, const char *); - ~simple_file_input(); - int get(); - int peek(); - int get_location(const char **, int *); -}; - -simple_file_input::simple_file_input(FILE *p, const char *s) -: filename(s), fp(p), lineno(1) -{ -} - -simple_file_input::~simple_file_input() -{ - // don't delete the filename - fclose(fp); -} - -int simple_file_input::get() -{ - int c = getc(fp); - while (illegal_input_char(c)) { - error("illegal input character code %1", c); - c = getc(fp); - } - if (c == '\n') - lineno++; - return c; -} - -int simple_file_input::peek() -{ - int c = getc(fp); - while (illegal_input_char(c)) { - error("illegal input character code %1", c); - c = getc(fp); - } - if (c != EOF) - ungetc(c, fp); - return c; -} - -int simple_file_input::get_location(const char **fnp, int *lnp) -{ - *fnp = filename; - *lnp = lineno; - return 1; -} - - -void copy_file_thru(const char *filename, const char *body, const char *until) -{ - errno = 0; - FILE *fp = fopen(filename, "r"); - if (fp == 0) { - lex_error("can't open `%1': %2", filename, strerror(errno)); - return; - } - input *in = new copy_file_thru_input(new simple_file_input(fp, filename), - body, until); - input_stack::push(in); -} - -void copy_rest_thru(const char *body, const char *until) -{ - input_stack::push(new copy_rest_thru_input(body, until)); -} - -void push_body(const char *s) -{ - input_stack::push(new char_input('\n')); - input_stack::push(new macro_input(s)); -} - -int delim_flag = 0; - -char *get_thru_arg() -{ - int c = input_stack::peek_char(); - while (c == ' ') { - input_stack::get_char(); - c = input_stack::peek_char(); - } - if (c != EOF && csalpha(c)) { - // looks like a macro - input_stack::get_char(); - token_buffer = c; - for (;;) { - c = input_stack::peek_char(); - if (c == EOF || (!csalnum(c) && c != '_')) - break; - input_stack::get_char(); - token_buffer += char(c); - } - context_buffer = token_buffer; - token_buffer += '\0'; - char *def = macro_table.lookup(token_buffer.contents()); - if (def) - return strsave(def); - // I guess it wasn't a macro after all; so push the macro name back. - // -2 because we added a '\0' - for (int i = token_buffer.length() - 2; i >= 0; i--) - input_stack::push_back(token_buffer[i]); - } - if (get_delimited()) { - token_buffer += '\0'; - return strsave(token_buffer.contents()); - } - else - return 0; -} - -int lookahead_token = -1; -string old_context_buffer; - -void do_lookahead() -{ - if (lookahead_token == -1) { - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - } -} - -int yylex() -{ - if (delim_flag) { - assert(lookahead_token == -1); - if (delim_flag == 2) { - if ((yylval.str = get_thru_arg()) != 0) - return DELIMITED; - else - return 0; - } - else { - if (get_delimited()) { - token_buffer += '\0'; - yylval.str = strsave(token_buffer.contents()); - return DELIMITED; - } - else - return 0; - } - } - for (;;) { - int t; - if (lookahead_token >= 0) { - t = lookahead_token; - lookahead_token = -1; - } - else - t = get_token(1); - switch (t) { - case '\n': - return ';'; - case EOF: - return 0; - case DEFINE: - do_define(); - break; - case UNDEF: - do_undef(); - break; - case ORDINAL: - yylval.n = token_int; - return t; - case NUMBER: - yylval.x = token_double; - return t; - case COMMAND_LINE: - case TEXT: - token_buffer += '\0'; - if (!input_stack::get_location(&yylval.lstr.filename, - &yylval.lstr.lineno)) { - yylval.lstr.filename = 0; - yylval.lstr.lineno = -1; - } - yylval.lstr.str = strsave(token_buffer.contents()); - return t; - case LABEL: - case VARIABLE: - token_buffer += '\0'; - yylval.str = strsave(token_buffer.contents()); - return t; - case LEFT: - // change LEFT to LEFT_CORNER when followed by OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token == OF) - return LEFT_CORNER; - else - return t; - case RIGHT: - // change RIGHT to RIGHT_CORNER when followed by OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token == OF) - return RIGHT_CORNER; - else - return t; - case UPPER: - // recognise UPPER only before LEFT or RIGHT - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != LEFT && lookahead_token != RIGHT) { - yylval.str = strsave("upper"); - return VARIABLE; - } - else - return t; - case LOWER: - // recognise LOWER only before LEFT or RIGHT - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != LEFT && lookahead_token != RIGHT) { - yylval.str = strsave("lower"); - return VARIABLE; - } - else - return t; - case TOP: - // recognise TOP only before OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != OF) { - yylval.str = strsave("top"); - return VARIABLE; - } - else - return t; - case BOTTOM: - // recognise BOTTOM only before OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != OF) { - yylval.str = strsave("bottom"); - return VARIABLE; - } - else - return t; - case CENTER: - // recognise CENTER only before OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != OF) { - yylval.str = strsave("center"); - return VARIABLE; - } - else - return t; - case START: - // recognise START only before OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != OF) { - yylval.str = strsave("start"); - return VARIABLE; - } - else - return t; - case END: - // recognise END only before OF - old_context_buffer = context_buffer; - lookahead_token = get_token(1); - if (lookahead_token != OF) { - yylval.str = strsave("end"); - return VARIABLE; - } - else - return t; - default: - return t; - } - } -} - -void lex_error(const char *message, - const errarg &arg1, - const errarg &arg2, - const errarg &arg3) -{ - const char *filename; - int lineno; - if (!input_stack::get_location(&filename, &lineno)) - error(message, arg1, arg2, arg3); - else - error_with_file_and_line(filename, lineno, message, arg1, arg2, arg3); -} - -void lex_warning(const char *message, - const errarg &arg1, - const errarg &arg2, - const errarg &arg3) -{ - const char *filename; - int lineno; - if (!input_stack::get_location(&filename, &lineno)) - warning(message, arg1, arg2, arg3); - else - warning_with_file_and_line(filename, lineno, message, arg1, arg2, arg3); -} - -void yyerror(const char *s) -{ - const char *filename; - int lineno; - const char *context = 0; - if (lookahead_token == -1) { - if (context_buffer.length() > 0) { - context_buffer += '\0'; - context = context_buffer.contents(); - } - } - else { - if (old_context_buffer.length() > 0) { - old_context_buffer += '\0'; - context = old_context_buffer.contents(); - } - } - if (!input_stack::get_location(&filename, &lineno)) { - if (context) { - if (context[0] == '\n' && context[1] == '\0') - error("%1 before newline", s); - else - error("%1 before `%2'", s, context); - } - else - error("%1 at end of picture", s); - } - else { - if (context) { - if (context[0] == '\n' && context[1] == '\0') - error_with_file_and_line(filename, lineno, "%1 before newline", s); - else - error_with_file_and_line(filename, lineno, "%1 before `%2'", - s, context); - } - else - error_with_file_and_line(filename, lineno, "%1 at end of picture", s); - } -} - diff --git a/gnu/usr.bin/groff/pic/main.cc b/gnu/usr.bin/groff/pic/main.cc deleted file mode 100644 index 87beb5dc285..00000000000 --- a/gnu/usr.bin/groff/pic/main.cc +++ /dev/null @@ -1,621 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "pic.h" - -extern int yyparse(); - -output *out; - -int flyback_flag; -int zero_length_line_flag = 0; -// Non-zero means we're using a groff driver. -int driver_extension_flag = 1; -int compatible_flag = 0; -int safer_flag = 0; -int command_char = '.'; // the character that introduces lines - // that should be passed through tranparently -static int lf_flag = 1; // non-zero if we should attempt to understand - // lines beginning with `.lf' - -// Non-zero means a parse error was encountered. -static int had_parse_error = 0; - -void do_file(const char *filename); - -class top_input : public input { - FILE *fp; - int bol; - int eof; - int push_back[3]; - int start_lineno; -public: - top_input(FILE *); - int get(); - int peek(); - int get_location(const char **, int *); -}; - -top_input::top_input(FILE *p) : fp(p), bol(1), eof(0) -{ - push_back[0] = push_back[1] = push_back[2] = EOF; - start_lineno = current_lineno; -} - -int top_input::get() -{ - if (eof) - return EOF; - if (push_back[2] != EOF) { - int c = push_back[2]; - push_back[2] = EOF; - return c; - } - else if (push_back[1] != EOF) { - int c = push_back[1]; - push_back[1] = EOF; - return c; - } - else if (push_back[0] != EOF) { - int c = push_back[0]; - push_back[0] = EOF; - return c; - } - int c = getc(fp); - while (illegal_input_char(c)) { - error("illegal input character code %1", int(c)); - c = getc(fp); - bol = 0; - } - if (bol && c == '.') { - c = getc(fp); - if (c == 'P') { - c = getc(fp); - if (c == 'F' || c == 'E') { - int d = getc(fp); - if (d != EOF) - ungetc(d, fp); - if (d == EOF || d == ' ' || d == '\n' || compatible_flag) { - eof = 1; - flyback_flag = c == 'F'; - return EOF; - } - push_back[0] = c; - push_back[1] = 'P'; - return '.'; - } - if (c == 'S') { - c = getc(fp); - if (c != EOF) - ungetc(c, fp); - if (c == EOF || c == ' ' || c == '\n' || compatible_flag) { - error("nested .PS"); - eof = 1; - return EOF; - } - push_back[0] = 'S'; - push_back[1] = 'P'; - return '.'; - } - if (c != EOF) - ungetc(c, fp); - push_back[0] = 'P'; - return '.'; - } - else { - if (c != EOF) - ungetc(c, fp); - return '.'; - } - } - if (c == '\n') { - bol = 1; - current_lineno++; - return '\n'; - } - bol = 0; - if (c == EOF) { - eof = 1; - error("end of file before .PE or .PF"); - error_with_file_and_line(current_filename, start_lineno - 1, - ".PS was here"); - } - return c; -} - -int top_input::peek() -{ - if (eof) - return EOF; - if (push_back[2] != EOF) - return push_back[2]; - if (push_back[1] != EOF) - return push_back[1]; - if (push_back[0] != EOF) - return push_back[0]; - int c = getc(fp); - while (illegal_input_char(c)) { - error("illegal input character code %1", int(c)); - c = getc(fp); - bol = 0; - } - if (bol && c == '.') { - c = getc(fp); - if (c == 'P') { - c = getc(fp); - if (c == 'F' || c == 'E') { - int d = getc(fp); - if (d != EOF) - ungetc(d, fp); - if (d == EOF || d == ' ' || d == '\n' || compatible_flag) { - eof = 1; - flyback_flag = c == 'F'; - return EOF; - } - push_back[0] = c; - push_back[1] = 'P'; - push_back[2] = '.'; - return '.'; - } - if (c == 'S') { - c = getc(fp); - if (c != EOF) - ungetc(c, fp); - if (c == EOF || c == ' ' || c == '\n' || compatible_flag) { - error("nested .PS"); - eof = 1; - return EOF; - } - push_back[0] = 'S'; - push_back[1] = 'P'; - push_back[2] = '.'; - return '.'; - } - if (c != EOF) - ungetc(c, fp); - push_back[0] = 'P'; - push_back[1] = '.'; - return '.'; - } - else { - if (c != EOF) - ungetc(c, fp); - push_back[0] = '.'; - return '.'; - } - } - if (c != EOF) - ungetc(c, fp); - if (c == '\n') - return '\n'; - return c; -} - -int top_input::get_location(const char **filenamep, int *linenop) -{ - *filenamep = current_filename; - *linenop = current_lineno; - return 1; -} - -void do_picture(FILE *fp) -{ - flyback_flag = 0; - int c; - while ((c = getc(fp)) == ' ') - ; - if (c == '<') { - string filename; - while ((c = getc(fp)) == ' ') - ; - while (c != EOF && c != ' ' && c != '\n') { - filename += char(c); - c = getc(fp); - } - if (c == ' ') { - do { - c = getc(fp); - } while (c != EOF && c != '\n'); - } - if (c == '\n') - current_lineno++; - if (filename.length() == 0) - error("missing filename after `<'"); - else { - filename += '\0'; - const char *old_filename = current_filename; - int old_lineno = current_lineno; - // filenames must be permanent - do_file(strsave(filename.contents())); - current_filename = old_filename; - current_lineno = old_lineno; - } - out->set_location(current_filename, current_lineno); - } - else { - out->set_location(current_filename, current_lineno); - string start_line; - while (c != EOF) { - if (c == '\n') { - current_lineno++; - break; - } - start_line += c; - c = getc(fp); - } - if (c == EOF) - return; - start_line += '\0'; - double wid, ht; - switch (sscanf(&start_line[0], "%lf %lf", &wid, &ht)) { - case 1: - ht = 0.0; - break; - case 2: - break; - default: - ht = wid = 0.0; - break; - } - out->set_desired_width_height(wid, ht); - out->set_args(start_line.contents()); - lex_init(new top_input(fp)); - if (yyparse()) { - had_parse_error = 1; - lex_error("giving up on this picture"); - } - parse_cleanup(); - lex_cleanup(); - - // skip the rest of the .PF/.PE line - while ((c = getc(fp)) != EOF && c != '\n') - ; - if (c == '\n') - current_lineno++; - out->set_location(current_filename, current_lineno); - } -} - -void do_file(const char *filename) -{ - FILE *fp; - if (strcmp(filename, "-") == 0) - fp = stdin; - else { - errno = 0; - fp = fopen(filename, "r"); - if (fp == 0) - fatal("can't open `%1': %2", filename, strerror(errno)); - } - out->set_location(filename, 1); - current_filename = filename; - current_lineno = 1; - enum { START, MIDDLE, HAD_DOT, HAD_P, HAD_PS, HAD_l, HAD_lf } state = START; - for (;;) { - int c = getc(fp); - if (c == EOF) - break; - switch (state) { - case START: - if (c == '.') - state = HAD_DOT; - else { - putchar(c); - if (c == '\n') { - current_lineno++; - state = START; - } - else - state = MIDDLE; - } - break; - case MIDDLE: - putchar(c); - if (c == '\n') { - current_lineno++; - state = START; - } - break; - case HAD_DOT: - if (c == 'P') - state = HAD_P; - else if (lf_flag && c == 'l') - state = HAD_l; - else { - putchar('.'); - putchar(c); - if (c == '\n') { - current_lineno++; - state = START; - } - else - state = MIDDLE; - } - break; - case HAD_P: - if (c == 'S') - state = HAD_PS; - else { - putchar('.'); - putchar('P'); - putchar(c); - if (c == '\n') { - current_lineno++; - state = START; - } - else - state = MIDDLE; - } - break; - case HAD_PS: - if (c == ' ' || c == '\n' || compatible_flag) { - ungetc(c, fp); - do_picture(fp); - state = START; - } - else { - fputs(".PS", stdout); - putchar(c); - state = MIDDLE; - } - break; - case HAD_l: - if (c == 'f') - state = HAD_lf; - else { - putchar('.'); - putchar('l'); - putchar(c); - if (c == '\n') { - current_lineno++; - state = START; - } - else - state = MIDDLE; - } - break; - case HAD_lf: - if (c == ' ' || c == '\n' || compatible_flag) { - string line; - while (c != EOF) { - line += c; - if (c == '\n') { - current_lineno++; - break; - } - c = getc(fp); - } - line += '\0'; - interpret_lf_args(line.contents()); - printf(".lf%s", line.contents()); - state = START; - } - else { - fputs(".lf", stdout); - putchar(c); - state = MIDDLE; - } - break; - default: - assert(0); - } - } - switch (state) { - case START: - break; - case MIDDLE: - putchar('\n'); - break; - case HAD_DOT: - fputs(".\n", stdout); - break; - case HAD_P: - fputs(".P\n", stdout); - break; - case HAD_PS: - fputs(".PS\n", stdout); - break; - case HAD_l: - fputs(".l\n", stdout); - break; - case HAD_lf: - fputs(".lf\n", stdout); - break; - } - if (fp != stdin) - fclose(fp); -} - -#ifdef FIG_SUPPORT -void do_whole_file(const char *filename) -{ - // Do not set current_filename. - FILE *fp; - if (strcmp(filename, "-") == 0) - fp = stdin; - else { - errno = 0; - fp = fopen(filename, "r"); - if (fp == 0) - fatal("can't open `%1': %2", filename, strerror(errno)); - } - lex_init(new file_input(fp, filename)); - if (yyparse()) - had_parse_error = 1; - parse_cleanup(); - lex_cleanup(); -} -#endif - -void usage() -{ - fprintf(stderr, "usage: %s [ -nvC ] [ filename ... ]\n", program_name); -#ifdef TEX_SUPPORT - fprintf(stderr, " %s -t [ -cvzC ] [ filename ... ]\n", program_name); -#endif -#ifdef FIG_SUPPORT - fprintf(stderr, " %s -f [ -v ] [ filename ]\n", program_name); -#endif - exit(1); -} - -#ifdef __MSDOS__ -static char *fix_program_name(char *arg, char *dflt) -{ - if (!arg) - return dflt; - char *prog = strchr(arg, '\0'); - for (;;) { - if (prog == arg) - break; - --prog; - if (strchr("\\/:", *prog)) { - prog++; - break; - } - } - char *ext = strchr(prog, '.'); - if (ext) - *ext = '\0'; - for (char *p = prog; *p; p++) - if ('A' <= *p && *p <= 'Z') - *p = 'a' + (*p - 'A'); - return prog; -} -#endif /* __MSDOS__ */ - -int main(int argc, char **argv) -{ -#ifdef __MSDOS__ - argv[0] = fix_program_name(argv[0], "pic"); -#endif /* __MSDOS__ */ - program_name = argv[0]; - static char stderr_buf[BUFSIZ]; - setbuf(stderr, stderr_buf); - int opt; -#ifdef TEX_SUPPORT - int tex_flag = 0; - int tpic_flag = 0; -#endif -#ifdef FIG_SUPPORT - int whole_file_flag = 0; - int fig_flag = 0; -#endif - while ((opt = getopt(argc, argv, "T:CDStcvnxzpf")) != EOF) - switch (opt) { - case 'C': - compatible_flag = 1; - break; - case 'D': - case 'T': - break; - case 'S': - safer_flag = 1; - break; - case 'f': -#ifdef FIG_SUPPORT - whole_file_flag++; - fig_flag++; -#else - fatal("fig support not included"); -#endif - break; - case 'n': - driver_extension_flag = 0; - break; - case 'p': - case 'x': - warning("-%1 option is obsolete", char(opt)); - break; - case 't': -#ifdef TEX_SUPPORT - tex_flag++; -#else - fatal("TeX support not included"); -#endif - break; - case 'c': -#ifdef TEX_SUPPORT - tpic_flag++; -#else - fatal("TeX support not included"); -#endif - break; - case 'v': - { - extern const char *version_string; - fprintf(stderr, "GNU pic version %s\n", version_string); - fflush(stderr); - break; - } - case 'z': - // zero length lines will be printed as dots - zero_length_line_flag++; - break; - case '?': - usage(); - break; - default: - assert(0); - } - parse_init(); -#ifdef TEX_SUPPORT - if (tpic_flag) { - out = make_tpic_output(); - lf_flag = 0; - } - else if (tex_flag) { - out = make_tex_output(); - command_char = '\\'; - lf_flag = 0; - } - else -#endif -#ifdef FIG_SUPPORT - if (fig_flag) - out = make_fig_output(); - else -#endif - out = make_troff_output(); -#ifdef FIG_SUPPORT - if (whole_file_flag) { - if (optind >= argc) - do_whole_file("-"); - else if (argc - optind > 1) - usage(); - else - do_whole_file(argv[optind]); - } - else { -#endif - if (optind >= argc) - do_file("-"); - else - for (int i = optind; i < argc; i++) - do_file(argv[i]); -#ifdef FIG_SUPPORT - } -#endif - delete out; - if (ferror(stdout) || fflush(stdout) < 0) - fatal("output error"); - return had_parse_error; -} - diff --git a/gnu/usr.bin/groff/pic/object.cc b/gnu/usr.bin/groff/pic/object.cc deleted file mode 100644 index b5ff195daed..00000000000 --- a/gnu/usr.bin/groff/pic/object.cc +++ /dev/null @@ -1,1833 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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) -{ -} - - -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 product - -double 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) -{ - object *p; - for (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; - text_item *p; - for (p = t; p; p = p->next) - len++; - if (len == 0) - text = 0; - else { - text = new text_piece[len]; - 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 success - -int 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(); -}; - -circle_object::circle_object(double diam) -: ellipse_object(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; - arrow_at_end = at_end; - aht = a; -} - -line_object::line_object(const position &s, const position &e, - position *p, int i) -: v(p), n(i), linear_object(s, e) -{ -} - -void line_object::print() -{ - if (lt.type == line_type::invisible) - return; - out->line(strt, v, n, lt); - if (arrow_at_start) - draw_arrow(strt, strt-v[0], aht, lt); - if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt); -} - -void line_object::update_bounding_box(bounding_box *p) -{ - p->encompass(strt); - for (int i = 0; i < n; i++) - p->encompass(v[i]); -} - -void line_object::move_by(const position &pos) -{ - linear_object::move_by(pos); - for (int i = 0; i < n; i++) - v[i] += pos; -} - -void spline_object::update_bounding_box(bounding_box *p) -{ - p->encompass(strt); - p->encompass(en); - /* - - If - - p1 = q1/2 + q2/2 - p2 = q1/6 + q2*5/6 - p3 = q2*5/6 + q3/6 - p4 = q2/2 + q3/2 - [ the points for the Bezier cubic ] - - and - - t = .5 - - then - - (1-t)^3*p1 + 3*t*(t - 1)^2*p2 + 3*t^2*(1-t)*p3 + t^3*p4 - [ the equation for the Bezier cubic ] - - = .125*q1 + .75*q2 + .125*q3 - - */ - for (int i = 1; i < n; i++) - p->encompass((i == 1 ? strt : v[i-2])*.125 + v[i-1]*.75 + v[i]*.125); -} - -arrow_object::arrow_object(const position &s, const position &e, - position *p, int i) -: line_object(s, e, p, i) -{ -} - -spline_object::spline_object(const position &s, const position &e, - position *p, int i) -: line_object(s, e, p, i) -{ -} - -void spline_object::print() -{ - if (lt.type == line_type::invisible) - return; - out->spline(strt, v, n, lt); - if (arrow_at_start) - draw_arrow(strt, strt-v[0], aht, lt); - if (arrow_at_end) - draw_arrow(en, v[n-1] - (n > 1 ? v[n - 2] : strt), aht, lt); -} - -line_object::~line_object() -{ - a_delete v; -} - -linear_object *object_spec::make_line(position *curpos, direction *dirp) -{ - static position last_line; - static int have_last_line = 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) && (type == LINE_OBJECT || type == ARROW_OBJECT) - && have_last_line) - segment_pos = last_line; - 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; - } - // Absolutise all movements - position endpos = startpos; - int nsegments = 0; - segment *s; - for (s = segment_list; s; s = s->next, nsegments++) - if (s->is_absolute) - endpos = s->pos; - else { - endpos += s->pos; - s->pos = endpos; - s->is_absolute = 1; // to avoid confusion - } - // handle chop - line_object *p = 0; - position *v = new position[nsegments]; - int i = 0; - for (s = segment_list; s; s = s->next, i++) - v[i] = s->pos; - if (flags & IS_DEFAULT_CHOPPED) { - lookup_variable("circlerad", &start_chop); - end_chop = start_chop; - flags |= IS_CHOPPED; - } - if (flags & IS_CHOPPED) { - position start_chop_vec, end_chop_vec; - if (start_chop != 0.0) { - start_chop_vec = v[0] - startpos; - start_chop_vec *= start_chop / hypot(start_chop_vec); - } - if (end_chop != 0.0) { - end_chop_vec = (v[nsegments - 1] - - (nsegments > 1 ? v[nsegments - 2] : startpos)); - end_chop_vec *= end_chop / hypot(end_chop_vec); - } - startpos += start_chop_vec; - v[nsegments - 1] -= end_chop_vec; - endpos -= end_chop_vec; - } - switch (type) { - case SPLINE_OBJECT: - p = new spline_object(startpos, endpos, v, nsegments); - break; - case ARROW_OBJECT: - p = new arrow_object(startpos, endpos, v, nsegments); - break; - case LINE_OBJECT: - p = new line_object(startpos, endpos, v, nsegments); - break; - default: - assert(0); - } - have_last_line = 1; - last_line = endpos - startpos; - *curpos = endpos; - return p; -} - -class arc_object : public linear_object { - int clockwise; - position cent; - double rad; -public: - arc_object(int, const position &, const position &, const position &); - position origin() { return cent; } - position center() { return cent; } - double radius() { return rad; } - position north(); - position south(); - position east(); - position west(); - position north_east(); - position north_west(); - position south_east(); - position south_west(); - void update_bounding_box(bounding_box *); - object_type type() { return ARC_OBJECT; } - void print(); - void move_by(const position &pos); -}; - -arc_object::arc_object(int cw, const position &s, const position &e, - const position &c) -: linear_object(s, e), clockwise(cw), cent(c) -{ - rad = hypot(c - s); -} - -void arc_object::move_by(const position &pos) -{ - linear_object::move_by(pos); - cent += pos; -} - -// we get arc corners from the corresponding circle - -position arc_object::north() -{ - position result(cent); - result.y += rad; - return result; -} - -position arc_object::south() -{ - position result(cent); - result.y -= rad; - return result; -} - -position arc_object::east() -{ - position result(cent); - result.x += rad; - return result; -} - -position arc_object::west() -{ - position result(cent); - result.x -= rad; - return result; -} - -position arc_object::north_east() -{ - position result(cent); - result.x += rad/M_SQRT2; - result.y += rad/M_SQRT2; - return result; -} - -position arc_object::north_west() -{ - position result(cent); - result.x -= rad/M_SQRT2; - result.y += rad/M_SQRT2; - return result; -} - -position arc_object::south_east() -{ - position result(cent); - result.x += rad/M_SQRT2; - result.y -= rad/M_SQRT2; - return result; -} - -position arc_object::south_west() -{ - position result(cent); - result.x -= rad/M_SQRT2; - result.y -= rad/M_SQRT2; - return result; -} - - -void arc_object::print() -{ - if (lt.type == line_type::invisible) - return; - if (clockwise) - out->arc(en, cent, strt, lt); - else - out->arc(strt, cent, en, lt); - if (arrow_at_start) { - position c = cent - strt; - draw_arrow(strt, - (clockwise ? position(c.y, -c.x) : position(-c.y, c.x)), - aht, 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); - } -} - -inline double max(double a, double b) -{ - return a > b ? a : b; -} - -void arc_object::update_bounding_box(bounding_box *p) -{ - p->encompass(strt); - p->encompass(en); - position start_offset = strt - cent; - if (start_offset.x == 0.0 && start_offset.y == 0.0) - return; - position end_offset = en - cent; - if (end_offset.x == 0.0 && end_offset.y == 0.0) - return; - double start_quad = atan2(start_offset.y, start_offset.x)/(M_PI/2.0); - double end_quad = atan2(end_offset.y, end_offset.x)/(M_PI/2.0); - if (clockwise) { - double temp = start_quad; - start_quad = end_quad; - end_quad = temp; - } - if (start_quad < 0.0) - start_quad += 4.0; - while (end_quad <= start_quad) - end_quad += 4.0; - double radius = max(hypot(start_offset), hypot(end_offset)); - for (int q = int(start_quad) + 1; q < end_quad; q++) { - position offset; - switch (q % 4) { - case 0: - offset.x = radius; - break; - case 1: - offset.y = radius; - break; - case 2: - offset.x = -radius; - break; - case 3: - offset.y = -radius; - break; - } - p->encompass(cent + offset); - } -} - -// We ignore the with attribute. The at attribute always refers to the center. - -linear_object *object_spec::make_arc(position *curpos, direction *dirp) -{ - *dirp = dir; - int cw = (flags & IS_CLOCKWISE) != 0; - // compute the start - position startpos; - if (flags & HAS_FROM) - startpos = from; - else - startpos = *curpos; - if (!(flags & HAS_RADIUS)) - lookup_variable("arcrad", &radius); - // compute the end - position endpos; - if (flags & HAS_TO) - endpos = to; - else { - position m(radius, radius); - // Adjust the signs. - if (cw) { - if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION) - m.x = -m.x; - if (dir == DOWN_DIRECTION || dir == RIGHT_DIRECTION) - m.y = -m.y; - *dirp = direction((dir + 3) % 4); - } - else { - if (dir == UP_DIRECTION || dir == LEFT_DIRECTION) - m.x = -m.x; - if (dir == DOWN_DIRECTION || dir == LEFT_DIRECTION) - m.y = -m.y; - *dirp = direction((dir + 1) % 4); - } - endpos = startpos + m; - } - // compute the center - position centerpos; - if (flags & HAS_AT) - centerpos = at; - else if (startpos == endpos) - centerpos = startpos; - else { - position h = (endpos - startpos)/2.0; - double d = hypot(h); - if (radius <= 0) - radius = .25; - // make the radius big enough - while (radius < d) - radius *= 2.0; - double alpha = acos(d/radius); - double theta = atan2(h.y, h.x); - if (cw) - theta -= alpha; - else - theta += alpha; - centerpos = position(cos(theta), sin(theta))*radius + startpos; - } - arc_object *p = new arc_object(cw, startpos, endpos, centerpos); - *curpos = endpos; - return p; -} - -graphic_object *object_spec::make_linear(position *curpos, direction *dirp) -{ - linear_object *obj; - if (type == ARC_OBJECT) - obj = make_arc(curpos, dirp); - else - obj = make_line(curpos, dirp); - if (type == ARROW_OBJECT - && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD)) == 0) - flags |= HAS_RIGHT_ARROW_HEAD; - if (obj && (flags & (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD))) { - arrow_head_type a; - int at_start = (flags & HAS_LEFT_ARROW_HEAD) != 0; - int at_end = (flags & HAS_RIGHT_ARROW_HEAD) != 0; - if (flags & HAS_HEIGHT) - a.height = height; - else - lookup_variable("arrowht", &a.height); - if (flags & HAS_WIDTH) - a.width = width; - else - lookup_variable("arrowwid", &a.width); - double solid; - lookup_variable("arrowhead", &solid); - a.solid = solid != 0.0; - obj->add_arrows(at_start, at_end, a); - } - return obj; -} - -object *object_spec::make_object(position *curpos, direction *dirp) -{ - graphic_object *obj = 0; - switch (type) { - case BLOCK_OBJECT: - obj = make_block(curpos, dirp); - break; - case BOX_OBJECT: - obj = make_box(curpos, dirp); - break; - case TEXT_OBJECT: - obj = make_text(curpos, dirp); - break; - case ELLIPSE_OBJECT: - obj = make_ellipse(curpos, dirp); - break; - case CIRCLE_OBJECT: - obj = make_circle(curpos, dirp); - break; - case MOVE_OBJECT: - obj = make_move(curpos, dirp); - break; - case ARC_OBJECT: - case LINE_OBJECT: - case SPLINE_OBJECT: - case ARROW_OBJECT: - obj = make_linear(curpos, dirp); - break; - case MARK_OBJECT: - case OTHER_OBJECT: - default: - assert(0); - break; - } - if (obj) { - if (flags & IS_INVISIBLE) - obj->set_invisible(); - if (text != 0) - obj->add_text(text, (flags & IS_ALIGNED) != 0); - if (flags & IS_DOTTED) - obj->set_dotted(dash_width); - else if (flags & IS_DASHED) - obj->set_dashed(dash_width); - double th; - if (flags & HAS_THICKNESS) - th = thickness; - else - lookup_variable("linethick", &th); - obj->set_thickness(th); - 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); - } - } - return obj; -} - -struct string_list { - string_list *next; - char *str; - string_list(char *); - ~string_list(); -}; - -string_list::string_list(char *s) -: next(0), str(s) -{ -} - -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. */ - -path::path(corner c) -: label_list(0), crn(c), ypath(0) -{ -} - -path::path(char *l, corner c) -: crn(c), ypath(0) -{ - label_list = new string_list(l); -} - -path::~path() -{ - while (label_list) { - string_list *tem = label_list; - label_list = label_list->next; - delete tem; - } - delete ypath; -} - -void path::append(corner c) -{ - assert(crn == 0); - crn = c; -} - -void path::append(char *s) -{ - string_list **p; - for (p = &label_list; *p; p = &(*p)->next) - ; - *p = new string_list(s); -} - -void path::set_ypath(path *p) -{ - ypath = p; -} - -// return non-zero for success - -int path::follow(const place &pl, place *result) const -{ - 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) { - lex_error("object does not contain a place `%1'", lb->str); - return 0; - } - if (crn == 0 || p->obj == 0) - *result = *p; - else { - position pos = ((p->obj)->*(crn))(); - result->x = pos.x; - result->y = pos.y; - result->obj = 0; - } - if (ypath) { - place tem; - if (!ypath->follow(pl, &tem)) - return 0; - result->y = tem.y; - if (result->obj != tem.obj) - result->obj = 0; - } - return 1; -} - -void print_object_list(object *p) -{ - for (; p; p = p->next) { - p->print(); - p->print_text(); - } -} - -void print_picture(object *obj) -{ - bounding_box bb; - for (object *p = obj; p; p = p->next) - p->update_bounding_box(&bb); - double scale; - lookup_variable("scale", &scale); - out->start_picture(scale, bb.ll, bb.ur); - print_object_list(obj); - out->finish_picture(); -} - diff --git a/gnu/usr.bin/groff/pic/object.h b/gnu/usr.bin/groff/pic/object.h deleted file mode 100644 index 2748e81e846..00000000000 --- a/gnu/usr.bin/groff/pic/object.h +++ /dev/null @@ -1,217 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct place; - -enum object_type { - OTHER_OBJECT, - BOX_OBJECT, - CIRCLE_OBJECT, - ELLIPSE_OBJECT, - ARC_OBJECT, - SPLINE_OBJECT, - LINE_OBJECT, - ARROW_OBJECT, - MOVE_OBJECT, - TEXT_OBJECT, - BLOCK_OBJECT, - MARK_OBJECT - }; - -struct bounding_box; - -struct object { - object *prev; - object *next; - object(); - virtual ~object(); - virtual position origin(); - virtual double width(); - virtual double radius(); - virtual double height(); - virtual position north(); - virtual position south(); - virtual position east(); - virtual position west(); - virtual position north_east(); - virtual position north_west(); - virtual position south_east(); - virtual position south_west(); - virtual position start(); - virtual position end(); - virtual position center(); - virtual place *find_label(const char *); - virtual void move_by(const position &); - virtual int blank(); - virtual void update_bounding_box(bounding_box *); - virtual object_type type() = 0; - virtual void print(); - virtual void print_text(); -}; - -typedef position (object::*corner)(); - -struct place { - object *obj; - double x, y; -}; - -struct string_list; - -class path { - corner crn; - string_list *label_list; - path *ypath; -public: - path(corner = 0); - path(char *, corner = 0); - ~path(); - void append(corner); - void append(char *); - void set_ypath(path *); - int follow(const place &, place *) const; -}; - -struct object_list { - object *head; - object *tail; - object_list(); - void append(object *); - void wrap_up_block(object_list *); -}; - -declare_ptable(place) - -// these go counterclockwise -enum direction { - RIGHT_DIRECTION, - UP_DIRECTION, - LEFT_DIRECTION, - DOWN_DIRECTION - }; - -struct graphics_state { - double x, y; - direction dir; -}; - -struct saved_state : public graphics_state { - saved_state *prev; - PTABLE(place) *tbl; -}; - - -struct text_item { - text_item *next; - char *text; - adjustment adj; - const char *filename; - int lineno; - - text_item(char *, const char *, int); - ~text_item(); -}; - -const unsigned long IS_DOTTED = 01; -const unsigned long IS_DASHED = 02; -const unsigned long IS_CLOCKWISE = 04; -const unsigned long IS_INVISIBLE = 020; -const unsigned long HAS_LEFT_ARROW_HEAD = 040; -const unsigned long HAS_RIGHT_ARROW_HEAD = 0100; -const unsigned long HAS_SEGMENT = 0200; -const unsigned long IS_SAME = 0400; -const unsigned long HAS_FROM = 01000; -const unsigned long HAS_AT = 02000; -const unsigned long HAS_WITH = 04000; -const unsigned long HAS_HEIGHT = 010000; -const unsigned long HAS_WIDTH = 020000; -const unsigned long HAS_RADIUS = 040000; -const unsigned long HAS_TO = 0100000; -const unsigned long IS_CHOPPED = 0200000; -const unsigned long IS_DEFAULT_CHOPPED = 0400000; -const unsigned long HAS_THICKNESS = 01000000; -const unsigned long IS_FILLED = 02000000; -const unsigned long IS_DEFAULT_FILLED = 04000000; -const unsigned long IS_ALIGNED = 010000000; - -struct segment { - int is_absolute; - position pos; - segment *next; - segment(const position &, int, segment *); -}; - -struct rectangle_object; -struct graphic_object; -struct linear_object; - -struct object_spec { - unsigned long flags; - object_type type; - object_list oblist; - PTABLE(place) *tbl; - double dash_width; - position from; - position to; - position at; - position by; - path *with; - text_item *text; - double height; - double radius; - double width; - double segment_width; - double segment_height; - double start_chop; - double end_chop; - double thickness; - double fill; - direction dir; - segment *segment_list; - position segment_pos; - int segment_is_absolute; - - object_spec(object_type); - ~object_spec(); - object *make_object(position *, direction *); - graphic_object *make_box(position *, direction *); - graphic_object *make_block(position *, direction *); - graphic_object *make_text(position *, direction *); - graphic_object *make_ellipse(position *, direction *); - graphic_object *make_circle(position *, direction *); - linear_object *make_line(position *, direction *); - linear_object *make_arc(position *, direction *); - graphic_object *make_linear(position *, direction *); - graphic_object *make_move(position *, direction *); - int position_rectangle(rectangle_object *p, position *curpos, - direction *dirp); -}; - - -object *make_object(object_spec *, position *, direction *); - -object *make_mark_object(); -object *make_command_object(char *, const char *, int); - -int lookup_variable(const char *name, double *val); -void define_variable(const char *name, double val); - -void print_picture(object *); - diff --git a/gnu/usr.bin/groff/pic/output.h b/gnu/usr.bin/groff/pic/output.h deleted file mode 100644 index ac490db463e..00000000000 --- a/gnu/usr.bin/groff/pic/output.h +++ /dev/null @@ -1,79 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct line_type { - enum { invisible, solid, dotted, dashed } type; - double dash_width; - double thickness; // the thickness is in points - - line_type(); -}; - - -class output { -protected: - char *args; - double desired_height; // zero if no height specified - double desired_width; // zero if no depth specified - double compute_scale(double, const position &, const position &); -public: - output(); - virtual ~output(); - void set_desired_width_height(double wid, double ht); - void set_args(const char *); - virtual void start_picture(double sc, const position &ll, const position &ur) = 0; - virtual void finish_picture() = 0; - virtual void circle(const position &, double rad, - const line_type &, double) = 0; - virtual void text(const position &, text_piece *, int, double) = 0; - virtual void line(const position &, const position *, int n, - const line_type &) = 0; - virtual void polygon(const position *, int n, - const line_type &, double) = 0; - virtual void spline(const position &, const position *, int n, - const line_type &) = 0; - virtual void arc(const position &, const position &, const position &, - const line_type &) = 0; - virtual void ellipse(const position &, const distance &, - const line_type &, double) = 0; - virtual void rounded_box(const position &, const distance &, double, - const line_type &, double) = 0; - virtual void command(const char *, const char *, int); - virtual void set_location(const char *, int); - virtual int supports_filled_polygons(); - virtual void begin_block(const position &ll, const position &ur); - virtual void end_block(); -}; - -extern output *out; - -/* #define FIG_SUPPORT 1 */ -#define TEX_SUPPORT 1 - -output *make_troff_output(); - -#ifdef TEX_SUPPORT -output *make_tex_output(); -output *make_tpic_output(); -#endif /* TEX_SUPPORT */ - -#ifdef FIG_SUPPORT -output *make_fig_output(); -#endif /* FIG_SUPPORT */ diff --git a/gnu/usr.bin/groff/pic/pic.1_in b/gnu/usr.bin/groff/pic/pic.1_in deleted file mode 100644 index 70ab94631bb..00000000000 --- a/gnu/usr.bin/groff/pic/pic.1_in +++ /dev/null @@ -1,759 +0,0 @@ -.ig \"-*- nroff -*- -Copyright (C) 1989-1999 Free Software Foundation, Inc. - -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the Free Software Foundation instead of in -the original English. -.. -.\" Like TP, but if specified indent is more than half -.\" the current line-length - indent, use the default indent. -.de Tp -.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP -.el .TP "\\$1" -.. -.ie t .ds tx T\h'-.1667m'\v'.224m'E\v'-.224m'\h'-.125m'X -.el .ds tx TeX -.ie \n(.g .ds ic \/ -.el .ds ic \^ -.\" The BSD man macros can't handle " in arguments to font change macros, -.\" so use \(ts instead of ". -.tr \(ts" -.TH @G@PIC @MAN1EXT@ "@MDATE@" "Groff Version @VERSION@" -.SH NAME -@g@pic \- compile pictures for troff or TeX -.SH SYNOPSIS -.B @g@pic -[ -.B \-nvCSU -] -[ -.I filename -\&.\|.\|. -] -.br -.B @g@pic -.B \-t -[ -.B \-cvzCSU -] -[ -.I filename -\&.\|.\|. -] -.SH DESCRIPTION -.LP -This manual page describes the GNU version of -.BR pic , -which is part of the groff document formatting system. -.B pic -compiles descriptions of pictures embedded within -.B troff -or \*(tx input files into commands that are understood by \*(tx or -.BR troff . -Each picture starts with a line beginning with -.B .PS -and ends with a line beginning with -.BR .PE . -Anything outside of -.B .PS -and -.B .PE -is passed through without change. -.LP -It is the user's responsibility to provide appropriate definitions of the -.B PS -and -.B PE -macros. -When the macro package being used does not supply such definitions -(for example, old versions of \-ms), -appropriate definitions can be obtained with -.BR \-mpic : -these will center each picture. -.SH OPTIONS -.LP -Options that do not take arguments may be grouped behind a single -.BR \- . -The special option -.B \-\^\- -can be used to mark the end of the options. -A filename of -.B \- -refers to the standard input. -.TP -.B \-C -Recognize -.B .PS -and -.B .PE -even when followed by a character other than space or newline. -.TP -.B \-S -Safer mode; do not execute -.B sh -commands. -This can be useful when operating on untrustworthy input. -(enabled by default) -.TP -.B \-U -Unsafe mode; revert the default option -.BR \-S . -.TP -.B \-n -Don't use the groff extensions to the troff drawing commands. -You should use this if you are using a postprocessor that doesn't support -these extensions. -The extensions are described in -.BR groff_out (@MAN5EXT@). -The -.B \-n -option also causes pic -not to use zero-length lines to draw dots in troff mode. -.TP -.B \-t -\*(tx mode. -.TP -.B \-c -Be more compatible with -.BR tpic . -Implies -.BR \-t . -Lines beginning with -.B \e -are not passed through transparently. -Lines beginning with -.B . -are passed through with the initial -.B . -changed to -.BR \e . -A line beginning with -.B .ps -is given special treatment: -it takes an optional integer argument specifying -the line thickness (pen size) in milliinches; -a missing argument restores the previous line thickness; -the default line thickness is 8 milliinches. -The line thickness thus specified takes effect only -when a non-negative line thickness has not been -specified by use of the -.B thickness -attribute or by setting the -.B linethick -variable. -.TP -.B \-v -Print the version number. -.TP -.B \-z -In \*(tx mode draw dots using zero-length lines. -.LP -The following options supported by other versions of -.B pic -are ignored: -.TP -.B \-D -Draw all lines using the \eD escape sequence. -.B pic -always does this. -.TP -.BI \-T \ dev -Generate output for the -.B troff -device -.IR dev . -This is unnecessary because the -.B troff -output generated by -.B pic -is device-independent. -.SH USAGE -This section describes only the differences between GNU pic and the original -version of pic. -Many of these differences also apply to newer versions of Unix pic. -.SS \*(tx mode -.LP -\*(tx mode is enabled by the -.B \-t -option. -In \*(tx mode, pic will define a vbox called -.B \egraph -for each picture. -You must yourself print that vbox using, for example, the command -.RS -.LP -.B -\ecenterline{\ebox\egraph} -.RE -.LP -Actually, since the vbox has a height of zero this will produce -slightly more vertical space above the picture than below it; -.RS -.LP -.B -\ecenterline{\eraise 1em\ebox\egraph} -.RE -.LP -would avoid this. -.LP -You must use a \*(tx driver that supports the -.B tpic -specials, version 2. -.LP -Lines beginning with -.B \e -are passed through transparently; a -.B % -is added to the end of the line to avoid unwanted spaces. -You can safely use this feature to change fonts or to -change the value of -.BR \ebaselineskip . -Anything else may well produce undesirable results; use at your own risk. -Lines beginning with a period are not given any special treatment. -.SS Commands -.TP -\fBfor\fR \fIvariable\fR \fB=\fR \fIexpr1\fR \fBto\fR \fIexpr2\fR \ -[\fBby\fR [\fB*\fR]\fIexpr3\fR] \fBdo\fR \fIX\fR \fIbody\fR \fIX\fR -Set -.I variable -to -.IR expr1 . -While the value of -.I variable -is less than or equal to -.IR expr2 , -do -.I body -and increment -.I variable -by -.IR expr3 ; -if -.B by -is not given, increment -.I variable -by 1. -If -.I expr3 -is prefixed by -.B * -then -.I variable -will instead be multiplied by -.IR expr3 . -.I X -can be any character not occurring in -.IR body . -.TP -\fBif\fR \fIexpr\fR \fBthen\fR \fIX\fR \fIif-true\fR \fIX\fR \ -[\fBelse\fR \fIY\fR \fIif-false\fR \fIY\fR] -Evaluate -.IR expr ; -if it is non-zero then do -.IR if-true , -otherwise do -.IR if-false . -.I X -can be any character not occurring in -.IR if-true . -.I Y -can be any character not occurring in -.IR if-false . -.TP -\fBprint\fR \fIarg\fR\|.\|.\|. -Concatenate the arguments and print as a line on stderr. -Each -.I arg -must be an expression, a position, or text. -This is useful for debugging. -.TP -\fBcommand\fR \fIarg\fR\|.\|.\|. -Concatenate the arguments -and pass them through as a line to troff or\*(tx. -Each -.I arg -must be an expression, a position, or text. -This has a similar effect to a line beginning with -.B . -or -.BR \e , -but allows the values of variables to be passed through. -.TP -\fBsh\fR \fIX\fR \fIcommand\fR \fIX\fR -Pass -.I command -to a shell. -.I X -can be any character not occurring in -.IR command . -.TP -\fBcopy\fR \fB"\fIfilename\fB"\fR -Include -.I filename -at this point in the file. -.TP -\fBcopy\fR [\fB"\fIfilename\fB"\fR] \fBthru\fR \fIX\fR \fIbody\fR \fIX\fR \ -[\fBuntil\fR \fB"\fIword\*(ic\fB"\fR] -.ns -.TP -\fBcopy\fR [\fB"\fIfilename\fB"\fR] \fBthru\fR \fImacro\fR \ -[\fBuntil\fR \fB"\fIword\*(ic\fB"\fR] -This construct does -.I body -once for each line of -.IR filename ; -the line is split into blank-delimited words, -and occurrences of -.BI $ i -in -.IR body , -for -.I i -between 1 and 9, -are replaced by the -.IR i -th -word of the line. -If -.I filename -is not given, lines are taken from the current input up to -.BR .PE . -If an -.B until -clause is specified, -lines will be read only until a line the first word of which is -.IR word ; -that line will then be discarded. -.I X -can be any character not occurring in -.IR body . -For example, -.RS -.IP -.ft B -.nf -\&.PS -copy thru % circle at ($1,$2) % until "END" -1 2 -3 4 -5 6 -END -box -\&.PE -.ft -.fi -.RE -.IP -is equivalent to -.RS -.IP -.ft B -.nf -\&.PS -circle at (1,2) -circle at (3,4) -circle at (5,6) -box -\&.PE -.ft -.fi -.RE -.IP -The commands to be performed for each line can also be taken -from a macro defined earlier by giving the name of the macro -as the argument to -.BR thru . -.LP -.B reset -.br -.ns -.TP -\fBreset\fI variable1\fB,\fI variable2 .\^.\^. -Reset pre-defined variables -.IR variable1 , -.I variable2 -\&.\^.\^. to their default values. -If no arguments are given, reset all pre-defined variables -to their default values. -Note that assigning a value to -.B scale -also causes all pre-defined variables that control dimensions -to be reset to their default values times the new value of scale. -.TP -\fBplot\fR \fIexpr\fR [\fB"\fItext\*(ic\fB"\fR] -This is a text object which is constructed by using -.I text -as a format string for sprintf -with an argument of -.IR expr . -If -.I text -is omitted a format string of -.B "\(ts%g\(ts" -is used. -Attributes can be specified in the same way as for a normal text -object. -Be very careful that you specify an appropriate format string; -pic does only very limited checking of the string. -This is deprecated in favour of -.BR sprintf . -.TP -.IB variable := expr -This is similar to -.B = -except -.I variable -must already be defined, -and the value of -.I variable -will be changed only in the innermost block in which it is defined. -(By contrast, -.B = -defines the variable in the current block if it is not already defined there, -and then changes the value in the current block.) -.LP -Arguments of the form -.IP -.IR X\ anything\ X -.LP -are also allowed to be of the form -.IP -.BI {\ anything\ } -.LP -In this case -.I anything -can contain balanced occurrences of -.B { -and -.BR } . -Strings may contain -.I X -or imbalanced occurrences of -.B { -and -.BR } . -.SS Expressions -The syntax for expressions has been significantly extended: -.LP -.IB x\ ^\ y -(exponentiation) -.br -.BI sin( x ) -.br -.BI cos( x ) -.br -.BI atan2( y , \ x ) -.br -.BI log( x ) -(base 10) -.br -.BI exp( x ) -(base 10, ie 10\v'-.4m'\fIx\*(ic\fR\v'.4m') -.br -.BI sqrt( x ) -.br -.BI int( x ) -.br -.B rand() -(return a random number between 0 and 1) -.br -.BI rand( x ) -(return a random number between 1 and -.IR x ; -deprecated) -.br -.BI max( e1 , \ e2 ) -.br -.BI min( e1 , \ e2 ) -.br -.BI ! e -.br -\fIe1\fB && \fIe2\fR -.br -\fIe1\fB || \fIe2\fR -.br -\fIe1\fB == \fIe2\fR -.br -\fIe1\fB != \fIe2\fR -.br -\fIe1\fB >= \fIe2\fR -.br -\fIe1\fB > \fIe2\fR -.br -\fIe1\fB <= \fIe2\fR -.br -\fIe1\fB < \fIe2\fR -.br -\fB"\fIstr1\*(ic\fB" == "\fIstr2\*(ic\fB"\fR -.br -\fB"\fIstr1\*(ic\fB" != "\fIstr2\*(ic\fB"\fR -.br -.LP -String comparison expressions must be parenthesised in some contexts -to avoid ambiguity. -.SS Other Changes -.LP -A bare expression, -.IR expr , -is acceptable as an attribute; -it is equivalent to -.IR dir\ expr , -where -.I dir -is the current direction. -For example -.IP -.B line 2i -.LP -means draw a line 2 inches long in the current direction. -.LP -The maximum width and height of the picture are taken from the variables -.B maxpswid -and -.BR maxpsht . -Initially these have values 8.5 and 11. -.LP -Scientific notation is allowed for numbers. -For example -.RS -.B -x = 5e\-2 -.RE -.LP -Text attributes can be compounded. -For example, -.RS -.B -"foo" above ljust -.RE -is legal. -.LP -There is no limit to the depth to which blocks can be examined. -For example, -.RS -.B -[A: [B: [C: box ]]] with .A.B.C.sw at 1,2 -.br -.B -circle at last [\^].A.B.C -.RE -is acceptable. -.LP -Arcs now have compass points -determined by the circle of which the arc is a part. -.LP -Circles and arcs can be dotted or dashed. -In \*(tx mode splines can be dotted or dashed. -.LP -Boxes can have rounded corners. -The -.B rad -attribute specifies the radius of the quarter-circles at each corner. -If no -.B rad -or -.B diam -attribute is given, a radius of -.B boxrad -is used. -Initially, -.B boxrad -has a value of 0. -A box with rounded corners can be dotted or dashed. -.LP -The -.B .PS -line can have a second argument specifying a maximum height for -the picture. -If the width of zero is specified the width will be ignored in computing -the scaling factor for the picture. -Note that GNU pic will always scale a picture by the same amount -vertically as horizontally. -This is different from the -.SM DWB -2.0 pic which may scale a picture by a -different amount vertically than horizontally if a height is -specified. -.LP -Each text object has an invisible box associated with it. -The compass points of a text object are determined by this box. -The implicit motion associated with the object is also determined -by this box. -The dimensions of this box are taken from the width and height attributes; -if the width attribute is not supplied then the width will be taken to be -.BR textwid ; -if the height attribute is not supplied then the height will be taken to be -the number of text strings associated with the object -times -.BR textht . -Initially -.B textwid -and -.B textht -have a value of 0. -.LP -In places where a quoted text string can be used, -an expression of the form -.IP -.BI sprintf(\(ts format \(ts,\ arg ,\fR.\|.\|.\fB) -.LP -can also be used; -this will produce the arguments formatted according to -.IR format , -which should be a string as described in -.BR printf (3) -appropriate for the number of arguments supplied, -using only the -.BR e , -.BR f , -.B g -or -.B % -format characters. -.LP -The thickness of the lines used to draw objects is controlled by the -.B linethick -variable. -This gives the thickness of lines in points. -A negative value means use the default thickness: -in \*(tx output mode, this means use a thickness of 8 milliinches; -in \*(tx output mode with the -.B -c -option, this means use the line thickness specified by -.B .ps -lines; -in troff output mode, this means use a thickness proportional -to the pointsize. -A zero value means draw the thinnest possible line supported by -the output device. -Initially it has a value of -1. -There is also a -.BR thick [ ness ] -attribute. -For example, -.RS -.LP -.B circle thickness 1.5 -.RE -.LP -would draw a circle using a line with a thickness of 1.5 points. -The thickness of lines is not affected by the -value of the -.B scale -variable, nor by the width or height given in the -.B .PS -line. -.LP -Boxes (including boxes with rounded corners), -circles and ellipses can be filled by giving then an attribute of -.BR fill [ ed ]. -This takes an optional argument of an expression with a value between -0 and 1; 0 will fill it with white, 1 with black, values in between -with a proportionally gray shade. -A value greater than 1 can also be used: -this means fill with the -shade of gray that is currently being used for text and lines. -Normally this will be black, but output devices may provide -a mechanism for changing this. -Without an argument, then the value of the variable -.B fillval -will be used. -Initially this has a value of 0.5. -The invisible attribute does not affect the filling of objects. -Any text associated with a filled object will be added after the -object has been filled, so that the text will not be obscured -by the filling. -.LP -Arrow heads will be drawn as solid triangles if the variable -.B arrowhead -is non-zero and either \*(tx mode is enabled or -the -.B \-x -option has been given. -Initially -.B arrowhead -has a value of 1. -.LP -The troff output of pic is device-independent. -The -.B \-T -option is therefore redundant. -All numbers are taken to be in inches; numbers are never interpreted -to be in troff machine units. -.LP -Objects can have an -.B aligned -attribute. -This will only work when the postprocessor is -.BR grops . -Any text associated with an object having the -.B aligned -attribute will be rotated about the center of the object -so that it is aligned in the direction from the start point -to the end point of the object. -Note that this attribute will have no effect for objects whose start and -end points are coincident. -.LP -In places where -.IB n th -is allowed -.BI ` expr 'th -is also allowed. -Note that -.B 'th -is a single token: no space is allowed between the -.B ' -and the -.BR th . -For example, -.IP -.B -.nf -for i = 1 to 4 do { - line from `i'th box.nw to `i+1'th box.se -} -.fi -.SH FILES -.Tp \w'\fB@MACRODIR@/tmac.pic'u+3n -.B -@MACRODIR@/tmac.pic -Example definitions of the -.B PS -and -.B PE -macros. -.SH "SEE ALSO" -.BR @g@troff (@MAN1EXT@), -.BR groff_out (@MAN5EXT@), -.BR tex (1) -.br -Tpic: Pic for \*(tx -.br -Brian W. Kernighan, -PIC \(em A Graphics Language for Typesetting (User Manual). -AT&T Bell Laboratories, Computing Science Technical Report No.\ 116 -<URL:http://cm.bell-labs.com/cm/cs/cstr/116.ps.gz> -(revised May, 1991). -.SH BUGS -.LP -Input characters that are illegal for -.B groff -(ie those with -.SM ASCII -code 0 or between 013 and 037 octal or between 0200 and 0237 octal) -are rejected even in \*(tx mode. -.LP -The interpretation of -.B fillval -is incompatible with the pic in 10th edition Unix, -which interprets 0 as black and 1 as white. diff --git a/gnu/usr.bin/groff/pic/pic.h b/gnu/usr.bin/groff/pic/pic.h deleted file mode 100644 index 70e95676e9f..00000000000 --- a/gnu/usr.bin/groff/pic/pic.h +++ /dev/null @@ -1,102 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include <stdio.h> -#include <string.h> -#include <math.h> -#include <stdlib.h> -#include <errno.h> - -extern "C" { - double hypot(double, double); -} - -#include "assert.h" -#include "cset.h" -#include "lib.h" -#include "stringclass.h" -#include "errarg.h" -#include "error.h" -#include "position.h" -#include "text.h" -#include "output.h" - -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -class input { - input *next; -public: - input(); - virtual ~input(); - virtual int get() = 0; - virtual int peek() = 0; - virtual int get_location(const char **, int *); - friend class input_stack; - friend class copy_rest_thru_input; -}; - -class file_input : public input { - FILE *fp; - const char *filename; - int lineno; - string line; - const char *ptr; - int read_line(); -public: - file_input(FILE *, const char *); - ~file_input(); - int get(); - int peek(); - int get_location(const char **, int *); -}; - -void lex_init(input *); -int get_location(char **, int *); - -void do_copy(const char *file); -void parse_init(); -void parse_cleanup(); - -void lex_error(const char *message, - const errarg &arg1 = empty_errarg, - const errarg &arg2 = empty_errarg, - const errarg &arg3 = empty_errarg); - -void lex_warning(const char *message, - const errarg &arg1 = empty_errarg, - const errarg &arg2 = empty_errarg, - const errarg &arg3 = empty_errarg); - -void lex_cleanup(); - -extern int flyback_flag; -extern int command_char; -// zero_length_line_flag is non-zero if zero-length lines are drawn -// as dots by the output device -extern int zero_length_line_flag; -extern int driver_extension_flag; -extern int compatible_flag; -extern int safer_flag; diff --git a/gnu/usr.bin/groff/pic/pic.y b/gnu/usr.bin/groff/pic/pic.y deleted file mode 100644 index d0420acd793..00000000000 --- a/gnu/usr.bin/groff/pic/pic.y +++ /dev/null @@ -1,1784 +0,0 @@ -/* 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -%{ -#include "pic.h" -#include "ptable.h" -#include "object.h" - -extern int delim_flag; -extern void do_copy(const char *); -extern void copy_rest_thru(const char *, const char *); -extern void copy_file_thru(const char *, const char *, const char *); -extern void push_body(const char *); -extern void do_for(char *var, double from, double to, - int by_is_multiplicative, double by, char *body); -extern void do_lookahead(); - -#ifndef HAVE_FMOD -extern "C" { - double fmod(double, double); -} -#endif - -#undef rand -extern "C" { - int rand(); -} - -/* Maximum number of characters produced by printf("%g") */ -#define GDIGITS 14 - -int yylex(); -void yyerror(const char *); - -void reset(const char *nm); -void reset_all(); - -place *lookup_label(const char *); -void define_label(const char *label, const place *pl); - -direction current_direction; -position current_position; - -implement_ptable(place) - -PTABLE(place) top_table; - -PTABLE(place) *current_table = &top_table; -saved_state *current_saved_state = 0; - -object_list olist; - -const char *ordinal_postfix(int n); -const char *object_type_name(object_type type); -char *format_number(const char *form, double n); -char *do_sprintf(const char *form, const double *v, int nv); - -%} - - -%union { - char *str; - int n; - double x; - struct { double x, y; } pair; - struct { double x; char *body; } if_data; - struct { char *str; const char *filename; int lineno; } lstr; - struct { double *v; int nv; int maxv; } dv; - struct { double val; int is_multiplicative; } by; - place pl; - object *obj; - corner crn; - path *pth; - object_spec *spec; - saved_state *pstate; - graphics_state state; - object_type obtype; -} - -%token <str> LABEL -%token <str> VARIABLE -%token <x> NUMBER -%token <lstr> TEXT -%token <lstr> COMMAND_LINE -%token <str> DELIMITED -%token <n> ORDINAL -%token TH -%token LEFT_ARROW_HEAD -%token RIGHT_ARROW_HEAD -%token DOUBLE_ARROW_HEAD -%token LAST -%token UP -%token DOWN -%token LEFT -%token RIGHT -%token BOX -%token CIRCLE -%token ELLIPSE -%token ARC -%token LINE -%token ARROW -%token MOVE -%token SPLINE -%token HEIGHT -%token RADIUS -%token WIDTH -%token DIAMETER -%token UP -%token DOWN -%token RIGHT -%token LEFT -%token FROM -%token TO -%token AT -%token WITH -%token BY -%token THEN -%token DOTTED -%token DASHED -%token CHOP -%token SAME -%token INVISIBLE -%token LJUST -%token RJUST -%token ABOVE -%token BELOW -%token OF -%token THE -%token WAY -%token BETWEEN -%token AND -%token HERE -%token DOT_N -%token DOT_E -%token DOT_W -%token DOT_S -%token DOT_NE -%token DOT_SE -%token DOT_NW -%token DOT_SW -%token DOT_C -%token DOT_START -%token DOT_END -%token DOT_X -%token DOT_Y -%token DOT_HT -%token DOT_WID -%token DOT_RAD -%token SIN -%token COS -%token ATAN2 -%token LOG -%token EXP -%token SQRT -%token K_MAX -%token K_MIN -%token INT -%token RAND -%token COPY -%token THRU -%token TOP -%token BOTTOM -%token UPPER -%token LOWER -%token SH -%token PRINT -%token CW -%token CCW -%token FOR -%token DO -%token IF -%token ELSE -%token ANDAND -%token OROR -%token NOTEQUAL -%token EQUALEQUAL -%token LESSEQUAL -%token GREATEREQUAL -%token LEFT_CORNER -%token RIGHT_CORNER -%token CENTER -%token END -%token START -%token RESET -%token UNTIL -%token PLOT -%token THICKNESS -%token FILL -%token ALIGNED -%token SPRINTF -%token COMMAND - -%token DEFINE -%token UNDEF - -/* this ensures that plot 17 "%g" parses as (plot 17 "%g") */ -%left PLOT -%left TEXT SPRINTF - -/* give text adjustments higher precedence than TEXT, so that -box "foo" above ljust == box ("foo" above ljust) -*/ - -%left LJUST RJUST ABOVE BELOW - -%left LEFT RIGHT -/* Give attributes that take an optional expression a higher -precedence than left and right, so that eg `line chop left' -parses properly. */ -%left CHOP DASHED DOTTED UP DOWN FILL -%left LABEL - -%left VARIABLE NUMBER '(' SIN COS ATAN2 LOG EXP SQRT K_MAX K_MIN INT RAND LAST -%left ORDINAL HERE '`' - -/* these need to be lower than '-' */ -%left HEIGHT RADIUS WIDTH DIAMETER FROM TO AT THICKNESS - -/* these must have higher precedence than CHOP so that `label %prec CHOP' -works */ -%left DOT_N DOT_E DOT_W DOT_S DOT_NE DOT_SE DOT_NW DOT_SW DOT_C -%left DOT_START DOT_END TOP BOTTOM LEFT_CORNER RIGHT_CORNER -%left UPPER LOWER CENTER START END - -%left ',' -%left OROR -%left ANDAND -%left EQUALEQUAL NOTEQUAL -%left '<' '>' LESSEQUAL GREATEREQUAL - -%left BETWEEN OF -%left AND - -%left '+' '-' -%left '*' '/' '%' -%right '!' -%right '^' - -%type <x> expr any_expr text_expr -%type <by> optional_by -%type <pair> expr_pair position_not_place -%type <if_data> simple_if -%type <obj> nth_primitive -%type <crn> corner -%type <pth> path label_path relative_path -%type <pl> place label element element_list middle_element_list -%type <spec> object_spec -%type <pair> position -%type <obtype> object_type -%type <n> optional_ordinal_last ordinal -%type <str> until -%type <dv> sprintf_args -%type <lstr> text print_args print_arg - -%% - -top: - optional_separator - | element_list - { - if (olist.head) - print_picture(olist.head); - } - ; - - -element_list: - optional_separator middle_element_list optional_separator - { $$ = $2; } - ; - -middle_element_list: - element - { $$ = $1; } - | middle_element_list separator element - { $$ = $1; } - ; - -optional_separator: - /* empty */ - | separator - ; - -separator: - ';' - | separator ';' - ; - -placeless_element: - VARIABLE '=' any_expr - { - define_variable($1, $3); - a_delete $1; - } - | VARIABLE ':' '=' any_expr - { - place *p = lookup_label($1); - if (!p) { - lex_error("variable `%1' not defined", $1); - YYABORT; - } - p->obj = 0; - p->x = $4; - p->y = 0.0; - a_delete $1; - } - | UP - { current_direction = UP_DIRECTION; } - | DOWN - { current_direction = DOWN_DIRECTION; } - | LEFT - { current_direction = LEFT_DIRECTION; } - | RIGHT - { current_direction = RIGHT_DIRECTION; } - | COMMAND_LINE - { - olist.append(make_command_object($1.str, $1.filename, - $1.lineno)); - } - | COMMAND print_args - { - olist.append(make_command_object($2.str, $2.filename, - $2.lineno)); - } - | PRINT print_args - { - fprintf(stderr, "%s\n", $2.str); - a_delete $2.str; - fflush(stderr); - } - | SH - { delim_flag = 1; } - DELIMITED - { - delim_flag = 0; - if (safer_flag) - lex_error("unsafe to run command `%1'", $3); - else - system($3); - a_delete $3; - } - | COPY TEXT - { - if (yychar < 0) - do_lookahead(); - do_copy($2.str); - // do not delete the filename - } - | COPY TEXT THRU - { delim_flag = 2; } - DELIMITED - { delim_flag = 0; } - until - { - if (yychar < 0) - do_lookahead(); - copy_file_thru($2.str, $5, $7); - // do not delete the filename - a_delete $5; - a_delete $7; - } - | COPY THRU - { delim_flag = 2; } - DELIMITED - { delim_flag = 0; } - until - { - if (yychar < 0) - do_lookahead(); - copy_rest_thru($4, $6); - a_delete $4; - a_delete $6; - } - | FOR VARIABLE '=' expr TO expr optional_by DO - { delim_flag = 1; } - DELIMITED - { - delim_flag = 0; - if (yychar < 0) - do_lookahead(); - do_for($2, $4, $6, $7.is_multiplicative, $7.val, $10); - } - | simple_if - { - if (yychar < 0) - do_lookahead(); - if ($1.x != 0.0) - push_body($1.body); - a_delete $1.body; - } - | simple_if ELSE - { delim_flag = 1; } - DELIMITED - { - delim_flag = 0; - if (yychar < 0) - do_lookahead(); - if ($1.x != 0.0) - push_body($1.body); - else - push_body($4); - a_delete $1.body; - a_delete $4; - } - | reset_variables - | RESET - { define_variable("scale", 1.0); } - ; - -reset_variables: - RESET VARIABLE - { reset($2); a_delete $2; } - | reset_variables VARIABLE - { reset($2); a_delete $2; } - | reset_variables ',' VARIABLE - { reset($3); a_delete $3; } - ; - -print_args: - print_arg - { $$ = $1; } - | print_args print_arg - { - $$.str = new char[strlen($1.str) + strlen($2.str) + 1]; - strcpy($$.str, $1.str); - strcat($$.str, $2.str); - a_delete $1.str; - a_delete $2.str; - if ($1.filename) { - $$.filename = $1.filename; - $$.lineno = $1.lineno; - } - else if ($2.filename) { - $$.filename = $2.filename; - $$.lineno = $2.lineno; - } - } - ; - -print_arg: - expr %prec ',' - { - $$.str = new char[GDIGITS + 1]; - sprintf($$.str, "%g", $1); - $$.filename = 0; - $$.lineno = 0; - } - | text - { $$ = $1; } - | position %prec ',' - { - $$.str = new char[GDIGITS + 2 + GDIGITS + 1]; - sprintf($$.str, "%g, %g", $1.x, $1.y); - $$.filename = 0; - $$.lineno = 0; - } - -simple_if: - IF any_expr THEN - { delim_flag = 1; } - DELIMITED - { delim_flag = 0; $$.x = $2; $$.body = $5; } - ; - -until: - /* empty */ - { $$ = 0; } - | UNTIL TEXT - { $$ = $2.str; } - ; - -any_expr: - expr - { $$ = $1; } - | text_expr - { $$ = $1; } - ; - -text_expr: - text EQUALEQUAL text - { - $$ = strcmp($1.str, $3.str) == 0; - a_delete $1.str; - a_delete $3.str; - } - | text NOTEQUAL text - { - $$ = strcmp($1.str, $3.str) != 0; - a_delete $1.str; - a_delete $3.str; - } - | text_expr ANDAND text_expr - { $$ = ($1 != 0.0 && $3 != 0.0); } - | text_expr ANDAND expr - { $$ = ($1 != 0.0 && $3 != 0.0); } - | expr ANDAND text_expr - { $$ = ($1 != 0.0 && $3 != 0.0); } - | text_expr OROR text_expr - { $$ = ($1 != 0.0 || $3 != 0.0); } - | text_expr OROR expr - { $$ = ($1 != 0.0 || $3 != 0.0); } - | expr OROR text_expr - { $$ = ($1 != 0.0 || $3 != 0.0); } - | '!' text_expr - { $$ = ($2 == 0.0); } - ; - - -optional_by: - /* empty */ - { $$.val = 1.0; $$.is_multiplicative = 0; } - | BY expr - { $$.val = $2; $$.is_multiplicative = 0; } - | BY '*' expr - { $$.val = $3; $$.is_multiplicative = 1; } - ; - -element: - object_spec - { - $$.obj = $1->make_object(¤t_position, - ¤t_direction); - if ($$.obj == 0) - YYABORT; - delete $1; - if ($$.obj) - olist.append($$.obj); - else { - $$.x = current_position.x; - $$.y = current_position.y; - } - } - | LABEL ':' optional_separator element - { $$ = $4; define_label($1, & $$); a_delete $1; } - | LABEL ':' optional_separator position_not_place - { - $$.obj = 0; - $$.x = $4.x; - $$.y = $4.y; - define_label($1, & $$); - a_delete $1; - } - | LABEL ':' optional_separator place - { - $$ = $4; - define_label($1, & $$); - a_delete $1; - } - | '{' - { - $<state>$.x = current_position.x; - $<state>$.y = current_position.y; - $<state>$.dir = current_direction; - } - element_list '}' - { - current_position.x = $<state>2.x; - current_position.y = $<state>2.y; - current_direction = $<state>2.dir; - } - optional_element - { - $$ = $3; - } - | placeless_element - { - $$.obj = 0; - $$.x = current_position.x; - $$.y = current_position.y; - } - ; - -optional_element: - /* empty */ - {} - | element - {} - ; - -object_spec: - BOX - { - $$ = new object_spec(BOX_OBJECT); - } - | CIRCLE - { - $$ = new object_spec(CIRCLE_OBJECT); - } - | ELLIPSE - { - $$ = new object_spec(ELLIPSE_OBJECT); - } - | ARC - { - $$ = new object_spec(ARC_OBJECT); - $$->dir = current_direction; - } - | LINE - { - $$ = new object_spec(LINE_OBJECT); - lookup_variable("lineht", & $$->segment_height); - lookup_variable("linewid", & $$->segment_width); - $$->dir = current_direction; - } - | ARROW - { - $$ = new object_spec(ARROW_OBJECT); - lookup_variable("lineht", & $$->segment_height); - lookup_variable("linewid", & $$->segment_width); - $$->dir = current_direction; - } - | MOVE - { - $$ = new object_spec(MOVE_OBJECT); - lookup_variable("moveht", & $$->segment_height); - lookup_variable("movewid", & $$->segment_width); - $$->dir = current_direction; - } - | SPLINE - { - $$ = new object_spec(SPLINE_OBJECT); - lookup_variable("lineht", & $$->segment_height); - lookup_variable("linewid", & $$->segment_width); - $$->dir = current_direction; - } - | text %prec TEXT - { - $$ = new object_spec(TEXT_OBJECT); - $$->text = new text_item($1.str, $1.filename, $1.lineno); - } - | PLOT expr - { - $$ = new object_spec(TEXT_OBJECT); - $$->text = new text_item(format_number(0, $2), 0, -1); - } - | PLOT expr text - { - $$ = new object_spec(TEXT_OBJECT); - $$->text = new text_item(format_number($3.str, $2), - $3.filename, $3.lineno); - a_delete $3.str; - } - | '[' - { - saved_state *p = new saved_state; - $<pstate>$ = p; - p->x = current_position.x; - p->y = current_position.y; - p->dir = current_direction; - p->tbl = current_table; - p->prev = current_saved_state; - current_position.x = 0.0; - current_position.y = 0.0; - current_table = new PTABLE(place); - current_saved_state = p; - olist.append(make_mark_object()); - } - element_list ']' - { - current_position.x = $<pstate>2->x; - current_position.y = $<pstate>2->y; - current_direction = $<pstate>2->dir; - $$ = new object_spec(BLOCK_OBJECT); - olist.wrap_up_block(& $$->oblist); - $$->tbl = current_table; - current_table = $<pstate>2->tbl; - current_saved_state = $<pstate>2->prev; - delete $<pstate>2; - } - | object_spec HEIGHT expr - { - $$ = $1; - $$->height = $3; - $$->flags |= HAS_HEIGHT; - } - | object_spec RADIUS expr - { - $$ = $1; - $$->radius = $3; - $$->flags |= HAS_RADIUS; - } - | object_spec WIDTH expr - { - $$ = $1; - $$->width = $3; - $$->flags |= HAS_WIDTH; - } - | object_spec DIAMETER expr - { - $$ = $1; - $$->radius = $3/2.0; - $$->flags |= HAS_RADIUS; - } - | object_spec expr %prec HEIGHT - { - $$ = $1; - $$->flags |= HAS_SEGMENT; - switch ($$->dir) { - case UP_DIRECTION: - $$->segment_pos.y += $2; - break; - case DOWN_DIRECTION: - $$->segment_pos.y -= $2; - break; - case RIGHT_DIRECTION: - $$->segment_pos.x += $2; - break; - case LEFT_DIRECTION: - $$->segment_pos.x -= $2; - break; - } - } - | object_spec UP - { - $$ = $1; - $$->dir = UP_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.y += $$->segment_height; - } - | object_spec UP expr - { - $$ = $1; - $$->dir = UP_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.y += $3; - } - | object_spec DOWN - { - $$ = $1; - $$->dir = DOWN_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.y -= $$->segment_height; - } - | object_spec DOWN expr - { - $$ = $1; - $$->dir = DOWN_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.y -= $3; - } - | object_spec RIGHT - { - $$ = $1; - $$->dir = RIGHT_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x += $$->segment_width; - } - | object_spec RIGHT expr - { - $$ = $1; - $$->dir = RIGHT_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x += $3; - } - | object_spec LEFT - { - $$ = $1; - $$->dir = LEFT_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x -= $$->segment_width; - } - | object_spec LEFT expr - { - $$ = $1; - $$->dir = LEFT_DIRECTION; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x -= $3; - } - | object_spec FROM position - { - $$ = $1; - $$->flags |= HAS_FROM; - $$->from.x = $3.x; - $$->from.y = $3.y; - } - | object_spec TO position - { - $$ = $1; - if ($$->flags & HAS_SEGMENT) - $$->segment_list = new segment($$->segment_pos, - $$->segment_is_absolute, - $$->segment_list); - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x = $3.x; - $$->segment_pos.y = $3.y; - $$->segment_is_absolute = 1; - $$->flags |= HAS_TO; - $$->to.x = $3.x; - $$->to.y = $3.y; - } - | object_spec AT position - { - $$ = $1; - $$->flags |= HAS_AT; - $$->at.x = $3.x; - $$->at.y = $3.y; - if ($$->type != ARC_OBJECT) { - $$->flags |= HAS_FROM; - $$->from.x = $3.x; - $$->from.y = $3.y; - } - } - | object_spec WITH path - { - $$ = $1; - $$->flags |= HAS_WITH; - $$->with = $3; - } - | object_spec BY expr_pair - { - $$ = $1; - $$->flags |= HAS_SEGMENT; - $$->segment_pos.x += $3.x; - $$->segment_pos.y += $3.y; - } - | object_spec THEN - { - $$ = $1; - if ($$->flags & HAS_SEGMENT) { - $$->segment_list = new segment($$->segment_pos, - $$->segment_is_absolute, - $$->segment_list); - $$->flags &= ~HAS_SEGMENT; - $$->segment_pos.x = $$->segment_pos.y = 0.0; - $$->segment_is_absolute = 0; - } - } - | object_spec DOTTED - { - $$ = $1; - $$->flags |= IS_DOTTED; - lookup_variable("dashwid", & $$->dash_width); - } - | object_spec DOTTED expr - { - $$ = $1; - $$->flags |= IS_DOTTED; - $$->dash_width = $3; - } - | object_spec DASHED - { - $$ = $1; - $$->flags |= IS_DASHED; - lookup_variable("dashwid", & $$->dash_width); - } - | object_spec DASHED expr - { - $$ = $1; - $$->flags |= IS_DASHED; - $$->dash_width = $3; - } - | object_spec FILL - { - $$ = $1; - $$->flags |= IS_DEFAULT_FILLED; - } - | object_spec FILL expr - { - $$ = $1; - $$->flags |= IS_FILLED; - $$->fill = $3; - } - | object_spec CHOP - { - $$ = $1; - // line chop chop means line chop 0 chop 0 - if ($$->flags & IS_DEFAULT_CHOPPED) { - $$->flags |= IS_CHOPPED; - $$->flags &= ~IS_DEFAULT_CHOPPED; - $$->start_chop = $$->end_chop = 0.0; - } - else if ($$->flags & IS_CHOPPED) { - $$->end_chop = 0.0; - } - else { - $$->flags |= IS_DEFAULT_CHOPPED; - } - } - | object_spec CHOP expr - { - $$ = $1; - if ($$->flags & IS_DEFAULT_CHOPPED) { - $$->flags |= IS_CHOPPED; - $$->flags &= ~IS_DEFAULT_CHOPPED; - $$->start_chop = 0.0; - $$->end_chop = $3; - } - else if ($$->flags & IS_CHOPPED) { - $$->end_chop = $3; - } - else { - $$->start_chop = $$->end_chop = $3; - $$->flags |= IS_CHOPPED; - } - } - | object_spec SAME - { - $$ = $1; - $$->flags |= IS_SAME; - } - | object_spec INVISIBLE - { - $$ = $1; - $$->flags |= IS_INVISIBLE; - } - | object_spec LEFT_ARROW_HEAD - { - $$ = $1; - $$->flags |= HAS_LEFT_ARROW_HEAD; - } - | object_spec RIGHT_ARROW_HEAD - { - $$ = $1; - $$->flags |= HAS_RIGHT_ARROW_HEAD; - } - | object_spec DOUBLE_ARROW_HEAD - { - $$ = $1; - $$->flags |= (HAS_LEFT_ARROW_HEAD|HAS_RIGHT_ARROW_HEAD); - } - | object_spec CW - { - $$ = $1; - $$->flags |= IS_CLOCKWISE; - } - | object_spec CCW - { - $$ = $1; - $$->flags &= ~IS_CLOCKWISE; - } - | object_spec text %prec TEXT - { - $$ = $1; - text_item **p; - for (p = & $$->text; *p; p = &(*p)->next) - ; - *p = new text_item($2.str, $2.filename, $2.lineno); - } - | object_spec LJUST - { - $$ = $1; - if ($$->text) { - text_item *p; - for (p = $$->text; p->next; p = p->next) - ; - p->adj.h = LEFT_ADJUST; - } - } - | object_spec RJUST - { - $$ = $1; - if ($$->text) { - text_item *p; - for (p = $$->text; p->next; p = p->next) - ; - p->adj.h = RIGHT_ADJUST; - } - } - | object_spec ABOVE - { - $$ = $1; - if ($$->text) { - text_item *p; - for (p = $$->text; p->next; p = p->next) - ; - p->adj.v = ABOVE_ADJUST; - } - } - | object_spec BELOW - { - $$ = $1; - if ($$->text) { - text_item *p; - for (p = $$->text; p->next; p = p->next) - ; - p->adj.v = BELOW_ADJUST; - } - } - | object_spec THICKNESS expr - { - $$ = $1; - $$->flags |= HAS_THICKNESS; - $$->thickness = $3; - } - | object_spec ALIGNED - { - $$ = $1; - $$->flags |= IS_ALIGNED; - } - ; - -text: - TEXT - { - $$ = $1; - } - | SPRINTF '(' TEXT sprintf_args ')' - { - $$.filename = $3.filename; - $$.lineno = $3.lineno; - $$.str = do_sprintf($3.str, $4.v, $4.nv); - a_delete $4.v; - a_delete $3.str; - } - ; - -sprintf_args: - /* empty */ - { - $$.v = 0; - $$.nv = 0; - $$.maxv = 0; - } - | sprintf_args ',' expr - { - $$ = $1; - if ($$.nv >= $$.maxv) { - if ($$.nv == 0) { - $$.v = new double[4]; - $$.maxv = 4; - } - else { - double *oldv = $$.v; - $$.maxv *= 2; - $$.v = new double[$$.maxv]; - memcpy($$.v, oldv, $$.nv*sizeof(double)); - a_delete oldv; - } - } - $$.v[$$.nv] = $3; - $$.nv += 1; - } - ; - -position: - position_not_place - { $$ = $1; } - | place - { - position pos = $1; - $$.x = pos.x; - $$.y = pos.y; - } - ; - -position_not_place: - expr_pair - { $$ = $1; } - | position '+' expr_pair - { - $$.x = $1.x + $3.x; - $$.y = $1.y + $3.y; - } - | position '-' expr_pair - { - $$.x = $1.x - $3.x; - $$.y = $1.y - $3.y; - } - | '(' position ',' position ')' - { - $$.x = $2.x; - $$.y = $4.y; - } - | expr between position AND position - { - $$.x = (1.0 - $1)*$3.x + $1*$5.x; - $$.y = (1.0 - $1)*$3.y + $1*$5.y; - } - | expr '<' position ',' position '>' - { - $$.x = (1.0 - $1)*$3.x + $1*$5.x; - $$.y = (1.0 - $1)*$3.y + $1*$5.y; - } - ; - -between: - BETWEEN - | OF THE WAY BETWEEN - ; - -expr_pair: - expr ',' expr - { $$.x = $1; $$.y = $3; } - | '(' expr_pair ')' - { $$ = $2; } - ; - -place: - label %prec CHOP /* line at A left == line (at A) left */ - { $$ = $1; } - | label corner - { - path pth($2); - if (!pth.follow($1, & $$)) - YYABORT; - } - | corner label - { - path pth($1); - if (!pth.follow($2, & $$)) - YYABORT; - } - | corner OF label - { - path pth($1); - if (!pth.follow($3, & $$)) - YYABORT; - } - | HERE - { - $$.x = current_position.x; - $$.y = current_position.y; - $$.obj = 0; - } - ; - -label: - LABEL - { - place *p = lookup_label($1); - if (!p) { - lex_error("there is no place `%1'", $1); - YYABORT; - } - $$ = *p; - a_delete $1; - } - | nth_primitive - { - $$.obj = $1; - } - | label '.' LABEL - { - path pth($3); - if (!pth.follow($1, & $$)) - YYABORT; - } - ; - -ordinal: - ORDINAL - { $$ = $1; } - | '`' any_expr TH - { - // XXX Check for overflow (and non-integers?). - $$ = (int)$2; - } - ; - -optional_ordinal_last: - LAST - { $$ = 1; } - | ordinal LAST - { $$ = $1; } - ; - -nth_primitive: - ordinal object_type - { - int count = 0; - object *p; - for (p = olist.head; p != 0; p = p->next) - if (p->type() == $2 && ++count == $1) { - $$ = p; - break; - } - if (p == 0) { - lex_error("there is no %1%2 %3", $1, ordinal_postfix($1), - object_type_name($2)); - YYABORT; - } - } - | optional_ordinal_last object_type - { - int count = 0; - object *p; - for (p = olist.tail; p != 0; p = p->prev) - if (p->type() == $2 && ++count == $1) { - $$ = p; - break; - } - if (p == 0) { - lex_error("there is no %1%2 last %3", $1, - ordinal_postfix($1), object_type_name($2)); - YYABORT; - } - } - ; - -object_type: - BOX - { $$ = BOX_OBJECT; } - | CIRCLE - { $$ = CIRCLE_OBJECT; } - | ELLIPSE - { $$ = ELLIPSE_OBJECT; } - | ARC - { $$ = ARC_OBJECT; } - | LINE - { $$ = LINE_OBJECT; } - | ARROW - { $$ = ARROW_OBJECT; } - | SPLINE - { $$ = SPLINE_OBJECT; } - | '[' ']' - { $$ = BLOCK_OBJECT; } - | TEXT - { $$ = TEXT_OBJECT; } - ; - -label_path: - '.' LABEL - { - $$ = new path($2); - } - | label_path '.' LABEL - { - $$ = $1; - $$->append($3); - } - ; - -relative_path: - corner - { - $$ = new path($1); - } - /* give this a lower precedence than LEFT and RIGHT so that - [A: box] with .A left == [A: box] with (.A left) */ - - | label_path %prec TEXT - { - $$ = $1; - } - | label_path corner - { - $$ = $1; - $$->append($2); - } - ; - -path: - relative_path - { - $$ = $1; - } - | '(' relative_path ',' relative_path ')' - { - $$ = $2; - $$->set_ypath($4); - } - /* The rest of these rules are a compatibility sop. */ - | ORDINAL LAST object_type relative_path - { - lex_warning("`%1%2 last %3' in `with' argument ignored", - $1, ordinal_postfix($1), object_type_name($3)); - $$ = $4; - } - | LAST object_type relative_path - { - lex_warning("`last %1' in `with' argument ignored", - object_type_name($2)); - $$ = $3; - } - | ORDINAL object_type relative_path - { - lex_warning("`%1%2 %3' in `with' argument ignored", - $1, ordinal_postfix($1), object_type_name($2)); - $$ = $3; - } - | LABEL relative_path - { - lex_warning("initial `%1' in `with' argument ignored", $1); - a_delete $1; - $$ = $2; - } - ; - -corner: - DOT_N - { $$ = &object::north; } - | DOT_E - { $$ = &object::east; } - | DOT_W - { $$ = &object::west; } - | DOT_S - { $$ = &object::south; } - | DOT_NE - { $$ = &object::north_east; } - | DOT_SE - { $$ = &object:: south_east; } - | DOT_NW - { $$ = &object::north_west; } - | DOT_SW - { $$ = &object::south_west; } - | DOT_C - { $$ = &object::center; } - | DOT_START - { $$ = &object::start; } - | DOT_END - { $$ = &object::end; } - | TOP - { $$ = &object::north; } - | BOTTOM - { $$ = &object::south; } - | LEFT - { $$ = &object::west; } - | RIGHT - { $$ = &object::east; } - | UPPER LEFT - { $$ = &object::north_west; } - | LOWER LEFT - { $$ = &object::south_west; } - | UPPER RIGHT - { $$ = &object::north_east; } - | LOWER RIGHT - { $$ = &object::south_east; } - | LEFT_CORNER - { $$ = &object::west; } - | RIGHT_CORNER - { $$ = &object::east; } - | UPPER LEFT_CORNER - { $$ = &object::north_west; } - | LOWER LEFT_CORNER - { $$ = &object::south_west; } - | UPPER RIGHT_CORNER - { $$ = &object::north_east; } - | LOWER RIGHT_CORNER - { $$ = &object::south_east; } - | CENTER - { $$ = &object::center; } - | START - { $$ = &object::start; } - | END - { $$ = &object::end; } - ; - -expr: - VARIABLE - { - if (!lookup_variable($1, & $$)) { - lex_error("there is no variable `%1'", $1); - YYABORT; - } - a_delete $1; - } - | NUMBER - { $$ = $1; } - | place DOT_X - { - if ($1.obj != 0) - $$ = $1.obj->origin().x; - else - $$ = $1.x; - } - | place DOT_Y - { - if ($1.obj != 0) - $$ = $1.obj->origin().y; - else - $$ = $1.y; - } - | place DOT_HT - { - if ($1.obj != 0) - $$ = $1.obj->height(); - else - $$ = 0.0; - } - | place DOT_WID - { - if ($1.obj != 0) - $$ = $1.obj->width(); - else - $$ = 0.0; - } - | place DOT_RAD - { - if ($1.obj != 0) - $$ = $1.obj->radius(); - else - $$ = 0.0; - } - | expr '+' expr - { $$ = $1 + $3; } - | expr '-' expr - { $$ = $1 - $3; } - | expr '*' expr - { $$ = $1 * $3; } - | expr '/' expr - { - if ($3 == 0.0) { - lex_error("division by zero"); - YYABORT; - } - $$ = $1/$3; - } - | expr '%' expr - { - if ($3 == 0.0) { - lex_error("modulus by zero"); - YYABORT; - } - $$ = fmod($1, $3); - } - | expr '^' expr - { - errno = 0; - $$ = pow($1, $3); - if (errno == EDOM) { - lex_error("arguments to `^' operator out of domain"); - YYABORT; - } - if (errno == ERANGE) { - lex_error("result of `^' operator out of range"); - YYABORT; - } - } - | '-' expr %prec '!' - { $$ = -$2; } - | '(' any_expr ')' - { $$ = $2; } - | SIN '(' any_expr ')' - { - errno = 0; - $$ = sin($3); - if (errno == ERANGE) { - lex_error("sin result out of range"); - YYABORT; - } - } - | COS '(' any_expr ')' - { - errno = 0; - $$ = cos($3); - if (errno == ERANGE) { - lex_error("cos result out of range"); - YYABORT; - } - } - | ATAN2 '(' any_expr ',' any_expr ')' - { - errno = 0; - $$ = atan2($3, $5); - if (errno == EDOM) { - lex_error("atan2 argument out of domain"); - YYABORT; - } - if (errno == ERANGE) { - lex_error("atan2 result out of range"); - YYABORT; - } - } - | LOG '(' any_expr ')' - { - errno = 0; - $$ = log10($3); - if (errno == ERANGE) { - lex_error("log result out of range"); - YYABORT; - } - } - | EXP '(' any_expr ')' - { - errno = 0; - $$ = pow(10.0, $3); - if (errno == ERANGE) { - lex_error("exp result out of range"); - YYABORT; - } - } - | SQRT '(' any_expr ')' - { - errno = 0; - $$ = sqrt($3); - if (errno == EDOM) { - lex_error("sqrt argument out of domain"); - YYABORT; - } - } - | K_MAX '(' any_expr ',' any_expr ')' - { $$ = $3 > $5 ? $3 : $5; } - | K_MIN '(' any_expr ',' any_expr ')' - { $$ = $3 < $5 ? $3 : $5; } - | INT '(' any_expr ')' - { $$ = floor($3); } - | RAND '(' any_expr ')' - { $$ = 1.0 + floor(((rand()&0x7fff)/double(0x7fff))*$3); } - | RAND '(' ')' - { - /* return a random number in the range [0,1) */ - /* portable, but not very random */ - $$ = (rand() & 0x7fff) / double(0x8000); - } - | expr '<' expr - { $$ = ($1 < $3); } - | expr LESSEQUAL expr - { $$ = ($1 <= $3); } - | expr '>' expr - { $$ = ($1 > $3); } - | expr GREATEREQUAL expr - { $$ = ($1 >= $3); } - | expr EQUALEQUAL expr - { $$ = ($1 == $3); } - | expr NOTEQUAL expr - { $$ = ($1 != $3); } - | expr ANDAND expr - { $$ = ($1 != 0.0 && $3 != 0.0); } - | expr OROR expr - { $$ = ($1 != 0.0 || $3 != 0.0); } - | '!' expr - { $$ = ($2 == 0.0); } - - ; - -%% - -/* bison defines const to be empty unless __STDC__ is defined, which it -isn't under cfront */ - -#ifdef const -#undef const -#endif - -static struct { - const char *name; - double val; - int scaled; // non-zero if val should be multiplied by scale -} defaults_table[] = { - { "arcrad", .25, 1 }, - { "arrowht", .1, 1 }, - { "arrowwid", .05, 1 }, - { "circlerad", .25, 1 }, - { "boxht", .5, 1 }, - { "boxwid", .75, 1 }, - { "boxrad", 0.0, 1 }, - { "dashwid", .05, 1 }, - { "ellipseht", .5, 1 }, - { "ellipsewid", .75, 1 }, - { "moveht", .5, 1 }, - { "movewid", .5, 1 }, - { "lineht", .5, 1 }, - { "linewid", .5, 1 }, - { "textht", 0.0, 1 }, - { "textwid", 0.0, 1 }, - { "scale", 1.0, 0 }, - { "linethick", -1.0, 0 }, // in points - { "fillval", .5, 0 }, - { "arrowhead", 1.0, 0 }, - { "maxpswid", 8.5, 0 }, - { "maxpsht", 11.0, 0 }, -}; - -place *lookup_label(const char *label) -{ - saved_state *state = current_saved_state; - PTABLE(place) *tbl = current_table; - for (;;) { - place *pl = tbl->lookup(label); - if (pl) - return pl; - if (!state) - return 0; - tbl = state->tbl; - state = state->prev; - } -} - -void define_label(const char *label, const place *pl) -{ - place *p = new place; - *p = *pl; - current_table->define(label, p); -} - -int lookup_variable(const char *name, double *val) -{ - place *pl = lookup_label(name); - if (pl) { - *val = pl->x; - return 1; - } - return 0; -} - -void define_variable(const char *name, double val) -{ - place *p = new place; - p->obj = 0; - p->x = val; - p->y = 0.0; - current_table->define(name, p); - if (strcmp(name, "scale") == 0) { - // When the scale changes, reset all scaled pre-defined variables to - // their default values. - for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) - if (defaults_table[i].scaled) - define_variable(defaults_table[i].name, val*defaults_table[i].val); - } -} - -// called once only (not once per parse) - -void parse_init() -{ - current_direction = RIGHT_DIRECTION; - current_position.x = 0.0; - current_position.y = 0.0; - // This resets everything to its default value. - reset_all(); -} - -void reset(const char *nm) -{ - for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) - if (strcmp(nm, defaults_table[i].name) == 0) { - double val = defaults_table[i].val; - if (defaults_table[i].scaled) { - double scale; - lookup_variable("scale", &scale); - val *= scale; - } - define_variable(defaults_table[i].name, val); - return; - } - lex_error("`%1' is not a predefined variable", nm); -} - -void reset_all() -{ - // We only have to explicitly reset the pre-defined variables that - // aren't scaled because `scale' is not scaled, and changing the - // value of `scale' will reset all the pre-defined variables that - // are scaled. - for (int i = 0; i < sizeof(defaults_table)/sizeof(defaults_table[0]); i++) - if (!defaults_table[i].scaled) - define_variable(defaults_table[i].name, defaults_table[i].val); -} - -// called after each parse - -void parse_cleanup() -{ - while (current_saved_state != 0) { - delete current_table; - current_table = current_saved_state->tbl; - saved_state *tem = current_saved_state; - current_saved_state = current_saved_state->prev; - delete tem; - } - assert(current_table == &top_table); - PTABLE_ITERATOR(place) iter(current_table); - const char *key; - place *pl; - while (iter.next(&key, &pl)) - if (pl->obj != 0) { - position pos = pl->obj->origin(); - pl->obj = 0; - pl->x = pos.x; - pl->y = pos.y; - } - while (olist.head != 0) { - object *tem = olist.head; - olist.head = olist.head->next; - delete tem; - } - olist.tail = 0; - current_direction = RIGHT_DIRECTION; - current_position.x = 0.0; - current_position.y = 0.0; -} - -const char *ordinal_postfix(int n) -{ - if (n < 10 || n > 20) - switch (n % 10) { - case 1: - return "st"; - case 2: - return "nd"; - case 3: - return "rd"; - } - return "th"; -} - -const char *object_type_name(object_type type) -{ - switch (type) { - case BOX_OBJECT: - return "box"; - case CIRCLE_OBJECT: - return "circle"; - case ELLIPSE_OBJECT: - return "ellipse"; - case ARC_OBJECT: - return "arc"; - case SPLINE_OBJECT: - return "spline"; - case LINE_OBJECT: - return "line"; - case ARROW_OBJECT: - return "arrow"; - case MOVE_OBJECT: - return "move"; - case TEXT_OBJECT: - return "\"\""; - case BLOCK_OBJECT: - return "[]"; - case OTHER_OBJECT: - case MARK_OBJECT: - default: - break; - } - return "object"; -} - -static char sprintf_buf[1024]; - -char *format_number(const char *form, double n) -{ - if (form == 0) - form = "%g"; - return do_sprintf(form, &n, 1); -} - -char *do_sprintf(const char *form, const double *v, int nv) -{ - string result; - int i = 0; - string one_format; - while (*form) { - if (*form == '%') { - one_format += *form++; - for (; *form != '\0' && strchr("#-+ 0123456789.", *form) != 0; form++) - one_format += *form; - if (*form == '\0' || strchr("eEfgG%", *form) == 0) { - lex_error("bad sprintf format"); - result += one_format; - result += form; - break; - } - if (*form == '%') { - one_format += *form++; - one_format += '\0'; - snprintf(sprintf_buf, sizeof(sprintf_buf), - "%s", one_format.contents()); - } - else { - if (i >= nv) { - lex_error("too few arguments to snprintf"); - result += one_format; - result += form; - break; - } - one_format += *form++; - one_format += '\0'; - snprintf(sprintf_buf, sizeof(sprintf_buf), - one_format.contents(), v[i++]); - } - one_format.clear(); - result += sprintf_buf; - } - else - result += *form++; - } - result += '\0'; - return strsave(result.contents()); -} diff --git a/gnu/usr.bin/groff/pic/position.h b/gnu/usr.bin/groff/pic/position.h deleted file mode 100644 index ab7d5469c00..00000000000 --- a/gnu/usr.bin/groff/pic/position.h +++ /dev/null @@ -1,47 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -struct place; -struct position { - double x; - double y; - position(double, double ); - position(); - position(const place &); - position &operator+=(const position &); - position &operator-=(const position &); - position &operator*=(double); - position &operator/=(double); -}; - -position operator-(const position &); -position operator+(const position &, const position &); -position operator-(const position &, const position &); -position operator/(const position &, double); -position operator*(const position &, double); -// dot product -double operator*(const position &, const position &); -int operator==(const position &, const position &); -int operator!=(const position &, const position &); - -double hypot(const position &a); - -typedef position distance; - diff --git a/gnu/usr.bin/groff/pic/tex.cc b/gnu/usr.bin/groff/pic/tex.cc deleted file mode 100644 index 53107826092..00000000000 --- a/gnu/usr.bin/groff/pic/tex.cc +++ /dev/null @@ -1,411 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "pic.h" - -#ifdef TEX_SUPPORT - -#include "common.h" - -class tex_output : public common_output { -public: - tex_output(); - ~tex_output(); - void start_picture(double, const position &ll, const position &ur); - void finish_picture(); - void text(const position &, text_piece *, int, double); - void line(const position &, const position *, int n, - const line_type &); - void polygon(const position *, int n, - const line_type &, double); - void spline(const position &, const position *, int n, - const line_type &); - void arc(const position &, const position &, const position &, - const line_type &); - void circle(const position &, double rad, const line_type &, double); - void ellipse(const position &, const distance &, const line_type &, double); - void command(const char *, const char *, int); - int supports_filled_polygons(); -private: - position upper_left; - double height; - double width; - double scale; - double pen_size; - - void point(const position &); - void dot(const position &, const line_type &); - void solid_arc(const position ¢, double rad, double start_angle, - double end_angle, const line_type <); - position transform(const position &); -protected: - virtual void set_pen_size(double ps); -}; - -// convert inches to milliinches - -inline int milliinches(double x) -{ - return int(x*1000.0 + .5); -} - -inline position tex_output::transform(const position &pos) -{ - return position((pos.x - upper_left.x)/scale, - (upper_left.y - pos.y)/scale); -} - -output *make_tex_output() -{ - return new tex_output; -} - -tex_output::tex_output() -{ -} - -tex_output::~tex_output() -{ -} - -const int DEFAULT_PEN_SIZE = 8; - -void tex_output::set_pen_size(double ps) -{ - if (ps < 0.0) - ps = -1.0; - if (ps != pen_size) { - pen_size = ps; - printf(" \\special{pn %d}%%\n", - ps < 0.0 ? DEFAULT_PEN_SIZE : int(ps*(1000.0/72.0) + .5)); - } -} - -void tex_output::start_picture(double sc, const position &ll, - const position &ur) -{ - upper_left.x = ll.x; - upper_left.y = ur.y; - scale = compute_scale(sc, ll, ur); - height = (ur.y - ll.y)/scale; - width = (ur.x - ll.x)/scale; - /* the point of \vskip 0pt is to ensure that the vtop gets - a height of 0 rather than the height of the hbox; this - might be non-zero if text from text attributes lies outside pic's - idea of the bounding box of the picture. */ - fputs("\\expandafter\\ifx\\csname graph\\endcsname\\relax \\csname newbox\\endcsname\\graph\\fi\n" - "\\expandafter\\ifx\\csname graphtemp\\endcsname\\relax \\csname newdimen\\endcsname\\graphtemp\\fi\n" - "\\setbox\\graph=\\vtop{\\vskip 0pt\\hbox{%\n", - stdout); - pen_size = -2.0; -} - -void tex_output::finish_picture() -{ - printf(" \\hbox{\\vrule depth%.3fin width0pt height 0pt}%%\n" - " \\kern %.3fin\n" - " }%%\n" - "}%%\n", - height, width); -} - -void tex_output::text(const position ¢er, text_piece *v, int n, double) -{ - position c = transform(center); - for (int i = 0; i < n; i++) - if (v[i].text != 0 && *v[i].text != '\0') { - int j = 2*i - n + 1; - if (v[i].adj.v == ABOVE_ADJUST) - j--; - else if (v[i].adj.v == BELOW_ADJUST) - j++; - if (j == 0) { - printf(" \\graphtemp=.5ex\\advance\\graphtemp by %.3fin\n", c.y); - } - else { - printf(" \\graphtemp=\\baselineskip" - "\\multiply\\graphtemp by %d" - "\\divide\\graphtemp by 2\n" - " \\advance\\graphtemp by .5ex" - "\\advance\\graphtemp by %.3fin\n", - j, c.y); - } - printf(" \\rlap{\\kern %.3fin\\lower\\graphtemp", c.x); - fputs("\\hbox to 0pt{", stdout); - if (v[i].adj.h != LEFT_ADJUST) - fputs("\\hss ", stdout); - fputs(v[i].text, stdout); - if (v[i].adj.h != RIGHT_ADJUST) - fputs("\\hss", stdout); - fputs("}}%\n", stdout); - } -} - -void tex_output::point(const position &pos) -{ - position p = transform(pos); - printf(" \\special{pa %d %d}%%\n", milliinches(p.x), milliinches(p.y)); -} - -void tex_output::line(const position &start, const position *v, int n, - const line_type <) -{ - set_pen_size(lt.thickness); - point(start); - for (int i = 0; i < n; i++) - point(v[i]); - fputs(" \\special{", stdout); - switch(lt.type) { - case line_type::invisible: - fputs("ip", stdout); - break; - case line_type::solid: - fputs("fp", stdout); - break; - case line_type::dotted: - printf("dt %.3f", lt.dash_width/scale); - break; - case line_type::dashed: - printf("da %.3f", lt.dash_width/scale); - break; - } - fputs("}%\n", stdout); -} - -void tex_output::polygon(const position *v, int n, - const line_type <, double fill) -{ - if (fill >= 0.0) { - if (fill > 1.0) - fill = 1.0; - printf(" \\special{sh %.3f}%%\n", fill); - } - line(v[n-1], v, n, lt); -} - -void tex_output::spline(const position &start, const position *v, int n, - const line_type <) -{ - if (lt.type == line_type::invisible) - return; - set_pen_size(lt.thickness); - point(start); - for (int i = 0; i < n; i++) - point(v[i]); - fputs(" \\special{sp", stdout); - switch(lt.type) { - case line_type::solid: - break; - case line_type::dotted: - printf(" %.3f", -lt.dash_width/scale); - break; - case line_type::dashed: - printf(" %.3f", lt.dash_width/scale); - break; - case line_type::invisible: - assert(0); - } - fputs("}%\n", stdout); -} - -void tex_output::solid_arc(const position ¢, double rad, - double start_angle, double end_angle, - const line_type <) -{ - set_pen_size(lt.thickness); - position c = transform(cent); - printf(" \\special{ar %d %d %d %d %f %f}%%\n", - milliinches(c.x), - milliinches(c.y), - milliinches(rad/scale), - milliinches(rad/scale), - -end_angle, - (-end_angle > -start_angle) ? M_PI * 2 - start_angle : -start_angle); -} - -void tex_output::arc(const position &start, const position ¢, - const position &end, const line_type <) -{ - switch (lt.type) { - case line_type::invisible: - break; - case line_type::dashed: - dashed_arc(start, cent, end, lt); - break; - case line_type::dotted: - dotted_arc(start, cent, end, lt); - break; - case line_type::solid: - { - position c; - if (!compute_arc_center(start, cent, end, &c)) { - line(start, &end, 1, lt); - break; - } - solid_arc(c, - hypot(cent - start), - atan2(start.y - c.y, start.x - c.x), - atan2(end.y - c.y, end.x - c.x), - lt); - break; - } - } -} - -void tex_output::circle(const position ¢, double rad, - const line_type <, double fill) -{ - if (fill >= 0.0 && lt.type != line_type::solid) { - if (fill > 1.0) - fill = 1.0; - line_type ilt; - ilt.type = line_type::invisible; - ellipse(cent, position(rad*2.0, rad*2.0), ilt, fill); - } - switch (lt.type) { - case line_type::dashed: - dashed_circle(cent, rad, lt); - break; - case line_type::invisible: - break; - case line_type::solid: - ellipse(cent, position(rad*2.0,rad*2.0), lt, fill); - break; - case line_type::dotted: - dotted_circle(cent, rad, lt); - break; - default: - assert(0); - } -} - -void tex_output::ellipse(const position ¢, const distance &dim, - const line_type <, double fill) -{ - if (lt.type == line_type::invisible) { - if (fill < 0.0) - return; - } - else - set_pen_size(lt.thickness); - if (fill >= 0.0) { - if (fill > 1.0) - fill = 1.0; - printf(" \\special{sh %.3f}%%\n", fill); - } - position c = transform(cent); - printf(" \\special{%s %d %d %d %d 0 6.28319}%%\n", - (lt.type == line_type::invisible ? "ia" : "ar"), - milliinches(c.x), - milliinches(c.y), - milliinches(dim.x/(2.0*scale)), - milliinches(dim.y/(2.0*scale))); -} - -void tex_output::command(const char *s, const char *, int) -{ - fputs(s, stdout); - putchar('%'); // avoid unwanted spaces - putchar('\n'); -} - -int tex_output::supports_filled_polygons() -{ - return 1; -} - -void tex_output::dot(const position &pos, const line_type <) -{ - if (zero_length_line_flag) { - line_type slt = lt; - slt.type = line_type::solid; - line(pos, &pos, 1, slt); - } - else { - int dot_rad = int(lt.thickness*(1000.0/(72.0*2)) + .5); - if (dot_rad == 0) - dot_rad = 1; - position p = transform(pos); - printf(" \\special{sh 1}%%\n" - " \\special{ia %d %d %d %d 0 6.28319}%%\n", - milliinches(p.x), milliinches(p.y), dot_rad, dot_rad); - } -} - -class tpic_output : public tex_output { -public: - tpic_output(); - void command(const char *, const char *, int); -private: - void set_pen_size(double ps); - int default_pen_size; - int prev_default_pen_size; -}; - -tpic_output::tpic_output() -: default_pen_size(DEFAULT_PEN_SIZE), prev_default_pen_size(DEFAULT_PEN_SIZE) -{ -} - -void tpic_output::command(const char *s, const char *filename, int lineno) -{ - assert(s[0] == '.'); - if (s[1] == 'p' && s[2] == 's' && (s[3] == '\0' || !csalpha(s[3]))) { - const char *p = s + 3; - while (csspace(*p)) - p++; - if (*p == '\0') { - int temp = default_pen_size; - default_pen_size = prev_default_pen_size; - prev_default_pen_size = temp; - } - else { - char *ptr; - int temp = (int)strtol(p, &ptr, 10); - if (temp == 0 && ptr == p) - error_with_file_and_line(filename, lineno, - "argument to `.ps' not an integer"); - else if (temp < 0) - error_with_file_and_line(filename, lineno, - "negative pen size"); - else { - prev_default_pen_size = default_pen_size; - default_pen_size = temp; - } - } - } - else - printf("\\%s%%\n", s + 1); -} - -void tpic_output::set_pen_size(double ps) -{ - if (ps < 0.0) - printf(" \\special{pn %d}%%\n", default_pen_size); - else - tex_output::set_pen_size(ps); -} - -output *make_tpic_output() -{ - return new tpic_output; -} - -#endif diff --git a/gnu/usr.bin/groff/pic/text.h b/gnu/usr.bin/groff/pic/text.h deleted file mode 100644 index f9d34875075..00000000000 --- a/gnu/usr.bin/groff/pic/text.h +++ /dev/null @@ -1,28 +0,0 @@ -// -*- C++ -*- - -enum hadjustment { - CENTER_ADJUST, - LEFT_ADJUST, - RIGHT_ADJUST - }; - -enum vadjustment { - NONE_ADJUST, - ABOVE_ADJUST, - BELOW_ADJUST - }; - -struct adjustment { - hadjustment h; - vadjustment v; -}; - -struct text_piece { - char *text; - adjustment adj; - const char *filename; - int lineno; - - text_piece(); - ~text_piece(); -}; diff --git a/gnu/usr.bin/groff/pic/troff.cc b/gnu/usr.bin/groff/pic/troff.cc deleted file mode 100644 index 71444cdbf7e..00000000000 --- a/gnu/usr.bin/groff/pic/troff.cc +++ /dev/null @@ -1,500 +0,0 @@ -// -*- 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 under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -groff is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with groff; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#include "pic.h" -#include "common.h" - - -const double RELATIVE_THICKNESS = -1.0; -const double BAD_THICKNESS = -2.0; - -class simple_output : public common_output { - virtual void simple_line(const position &, const position &) = 0; - virtual void simple_spline(const position &, const position *, int n) = 0; - virtual void simple_arc(const position &, const position &, - const position &) = 0; - virtual void simple_circle(int, const position &, double rad) = 0; - virtual void simple_ellipse(int, const position &, const distance &) = 0; - virtual void simple_polygon(int, const position *, int) = 0; - virtual void line_thickness(double) = 0; - virtual void set_fill(double) = 0; - void dot(const position &, const line_type &) = 0; -public: - void start_picture(double sc, const position &ll, const position &ur) = 0; - void finish_picture() = 0; - void text(const position &, text_piece *, int, double) = 0; - void line(const position &, const position *, int n, - const line_type &); - void polygon(const position *, int n, - const line_type &, double); - void spline(const position &, const position *, int n, - const line_type &); - void arc(const position &, const position &, const position &, - const line_type &); - void circle(const position &, double rad, const line_type &, double); - void ellipse(const position &, const distance &, const line_type &, double); - int supports_filled_polygons(); -}; - -int simple_output::supports_filled_polygons() -{ - return driver_extension_flag != 0; -} - -void simple_output::arc(const position &start, const position ¢, - const position &end, const line_type <) -{ - switch (lt.type) { - case line_type::solid: - line_thickness(lt.thickness); - simple_arc(start, cent, end); - break; - case line_type::invisible: - break; - case line_type::dashed: - dashed_arc(start, cent, end, lt); - break; - case line_type::dotted: - dotted_arc(start, cent, end, lt); - break; - } -} - -void simple_output::line(const position &start, const position *v, int n, - const line_type <) -{ - position pos = start; - line_thickness(lt.thickness); - for (int i = 0; i < n; i++) { - switch (lt.type) { - case line_type::solid: - simple_line(pos, v[i]); - break; - case line_type::dotted: - { - distance vec(v[i] - pos); - double dist = hypot(vec); - int ndots = int(dist/lt.dash_width + .5); - if (ndots == 0) - dot(pos, lt); - else { - vec /= double(ndots); - for (int j = 0; j <= ndots; j++) - dot(pos + vec*j, lt); - } - } - break; - case line_type::dashed: - { - distance vec(v[i] - pos); - double dist = hypot(vec); - if (dist <= lt.dash_width*2.0) - simple_line(pos, v[i]); - else { - int ndashes = int((dist - lt.dash_width)/(lt.dash_width*2.0) + .5); - distance dash_vec = vec*(lt.dash_width/dist); - double dash_gap = (dist - lt.dash_width)/ndashes; - distance dash_gap_vec = vec*(dash_gap/dist); - for (int j = 0; j <= ndashes; j++) { - position s(pos + dash_gap_vec*j); - simple_line(s, s + dash_vec); - } - } - } - break; - case line_type::invisible: - break; - default: - assert(0); - } - pos = v[i]; - } -} - -void simple_output::spline(const position &start, const position *v, int n, - const line_type <) -{ - line_thickness(lt.thickness); - simple_spline(start, v, n); -} - -void simple_output::polygon(const position *v, int n, - const line_type <, double fill) -{ - if (driver_extension_flag) { - if (fill >= 0.0) { - set_fill(fill); - simple_polygon(1, v, n); - } - } - if (lt.type == line_type::solid && driver_extension_flag) { - line_thickness(lt.thickness); - simple_polygon(0, v, n); - } - else if (lt.type != line_type::invisible) { - line_thickness(lt.thickness); - line(v[n - 1], v, n, lt); - } -} - -void simple_output::circle(const position ¢, double rad, - const line_type <, double fill) -{ - if (driver_extension_flag && fill >= 0.0) { - set_fill(fill); - simple_circle(1, cent, rad); - } - line_thickness(lt.thickness); - switch (lt.type) { - case line_type::invisible: - break; - case line_type::dashed: - dashed_circle(cent, rad, lt); - break; - case line_type::dotted: - dotted_circle(cent, rad, lt); - break; - case line_type::solid: - simple_circle(0, cent, rad); - break; - default: - assert(0); - } -} - -void simple_output::ellipse(const position ¢, const distance &dim, - const line_type <, double fill) -{ - if (driver_extension_flag && fill >= 0.0) { - set_fill(fill); - simple_ellipse(1, cent, dim); - } - if (lt.type != line_type::invisible) - line_thickness(lt.thickness); - switch (lt.type) { - case line_type::invisible: - break; - case line_type::dotted: - case line_type::dashed: - case line_type::solid: - simple_ellipse(0, cent, dim); - break; - default: - assert(0); - } -} - -#define FILL_MAX 1000 - -class troff_output : public simple_output { - const char *last_filename; - position upper_left; - double height; - double scale; - double last_line_thickness; - double last_fill; -public: - troff_output(); - ~troff_output(); - void start_picture(double, const position &ll, const position &ur); - void finish_picture(); - void text(const position &, text_piece *, int, double); - void dot(const position &, const line_type &); - void command(const char *, const char *, int); - void set_location(const char *, int); - void simple_line(const position &, const position &); - void simple_spline(const position &, const position *, int n); - void simple_arc(const position &, const position &, const position &); - void simple_circle(int, const position &, double rad); - void simple_ellipse(int, const position &, const distance &); - void simple_polygon(int, const position *, int); - void line_thickness(double p); - void set_fill(double); - position transform(const position &); -}; - -output *make_troff_output() -{ - return new troff_output; -} - -troff_output::troff_output() -: last_filename(0), last_line_thickness(BAD_THICKNESS), last_fill(-1.0) -{ -} - -troff_output::~troff_output() -{ -} - -inline position troff_output::transform(const position &pos) -{ - return position((pos.x - upper_left.x)/scale, - (upper_left.y - pos.y)/scale); -} - -#define FILL_REG "00" - -// If this register > 0, then pic will generate \X'ps: ...' commands -// if the aligned attribute is used. -#define GROPS_REG "0p" - -// If this register is defined, geqn won't produce `\x's. -#define EQN_NO_EXTRA_SPACE_REG "0x" - -void troff_output::start_picture(double sc, - const position &ll, const position &ur) -{ - upper_left.x = ll.x; - upper_left.y = ur.y; - scale = compute_scale(sc, ll, ur); - height = (ur.y - ll.y)/scale; - double width = (ur.x - ll.x)/scale; - printf(".PS %.3fi %.3fi", height, width); - if (args) - printf(" %s\n", args); - else - putchar('\n'); - printf(".\\\" %g %g %g %g\n", ll.x, ll.y, ur.x, ur.y); - printf(".\\\" %.3fi %.3fi %.3fi %.3fi\n", 0.0, height, width, 0.0); - printf(".nr " FILL_REG " \\n(.u\n.nf\n"); - printf(".nr " EQN_NO_EXTRA_SPACE_REG " 1\n"); - // This guarantees that if the picture is used in a diversion it will - // have the right width. - printf("\\h'%.3fi'\n.sp -1\n", width); -} - -void troff_output::finish_picture() -{ - line_thickness(BAD_THICKNESS); - last_fill = -1.0; // force it to be reset for each picture - if (!flyback_flag) - printf(".sp %.3fi+1\n", height); - printf(".if \\n(" FILL_REG " .fi\n"); - printf(".br\n"); - printf(".nr " EQN_NO_EXTRA_SPACE_REG " 0\n"); - // this is a little gross - set_location(current_filename, current_lineno); - fputs(flyback_flag ? ".PF\n" : ".PE\n", stdout); -} - -void troff_output::command(const char *s, - const char *filename, int lineno) -{ - if (filename != 0) - set_location(filename, lineno); - fputs(s, stdout); - putchar('\n'); -} - -void troff_output::simple_circle(int filled, const position ¢, double rad) -{ - position c = transform(cent); - printf("\\h'%.3fi'" - "\\v'%.3fi'" - "\\D'%c%.3fi'" - "\n.sp -1\n", - c.x - rad/scale, - c.y, - (filled ? 'C' : 'c'), - rad*2.0/scale); -} - -void troff_output::simple_ellipse(int filled, const position ¢, - const distance &dim) -{ - position c = transform(cent); - printf("\\h'%.3fi'" - "\\v'%.3fi'" - "\\D'%c%.3fi %.3fi'" - "\n.sp -1\n", - c.x - dim.x/(2.0*scale), - c.y, - (filled ? 'E' : 'e'), - dim.x/scale, dim.y/scale); -} - -void troff_output::simple_arc(const position &start, const distance ¢, - const distance &end) -{ - position s = transform(start); - position c = transform(cent); - distance cv = c - s; - distance ev = transform(end) - c; - printf("\\h'%.3fi'" - "\\v'%.3fi'" - "\\D'a%.3fi %.3fi %.3fi %.3fi'" - "\n.sp -1\n", - s.x, s.y, cv.x, cv.y, ev.x, ev.y); -} - -void troff_output::simple_line(const position &start, const position &end) -{ - position s = transform(start); - distance ev = transform(end) - s; - printf("\\h'%.3fi'" - "\\v'%.3fi'" - "\\D'l%.3fi %.3fi'" - "\n.sp -1\n", - s.x, s.y, ev.x, ev.y); -} - -void troff_output::simple_spline(const position &start, - const position *v, int n) -{ - position pos = transform(start); - printf("\\h'%.3fi'" - "\\v'%.3fi'", - pos.x, pos.y); - fputs("\\D'~", stdout); - for (int i = 0; i < n; i++) { - position temp = transform(v[i]); - distance d = temp - pos; - pos = temp; - if (i != 0) - putchar(' '); - printf("%.3fi %.3fi", d.x, d.y); - } - printf("'\n.sp -1\n"); -} - -// a solid polygon - -void troff_output::simple_polygon(int filled, const position *v, int n) -{ - position pos = transform(v[0]); - printf("\\h'%.3fi'" - "\\v'%.3fi'", - pos.x, pos.y); - printf("\\D'%c", (filled ? 'P' : 'p')); - for (int i = 1; i < n; i++) { - position temp = transform(v[i]); - distance d = temp - pos; - pos = temp; - if (i != 1) - putchar(' '); - printf("%.3fi %.3fi", d.x, d.y); - } - printf("'\n.sp -1\n"); -} - -const double TEXT_AXIS = 0.22; // in ems - -static const char *choose_delimiter(const char *text) -{ - if (strchr(text, '\'') == 0) - return "'"; - else - return "\\(ts"; -} - -void troff_output::text(const position ¢er, text_piece *v, int n, - double ang) -{ - line_thickness(BAD_THICKNESS); // the text might use lines (eg in equations) - int rotate_flag = 0; - if (driver_extension_flag && ang != 0.0) { - rotate_flag = 1; - position c = transform(center); - printf(".if \\n(" GROPS_REG " \\{\\\n" - "\\h'%.3fi'" - "\\v'%.3fi'" - "\\X'ps: exec gsave currentpoint 2 copy translate %.4f rotate neg exch neg exch translate'" - "\n.sp -1\n" - ".\\}\n", - c.x, c.y, -ang*180.0/M_PI); - } - for (int i = 0; i < n; i++) - if (v[i].text != 0 && *v[i].text != '\0') { - position c = transform(center); - if (v[i].filename != 0) - set_location(v[i].filename, v[i].lineno); - printf("\\h'%.3fi", c.x); - const char *delim = choose_delimiter(v[i].text); - if (v[i].adj.h == RIGHT_ADJUST) - printf("-\\w%s%s%su", delim, v[i].text, delim); - else if (v[i].adj.h != LEFT_ADJUST) - printf("-(\\w%s%s%su/2u)", delim, v[i].text, delim); - putchar('\''); - printf("\\v'%.3fi-(%dv/2u)+%dv+%.2fm", - c.y, - n - 1, - i, - TEXT_AXIS); - if (v[i].adj.v == ABOVE_ADJUST) - printf("-.5v"); - else if (v[i].adj.v == BELOW_ADJUST) - printf("+.5v"); - putchar('\''); - fputs(v[i].text, stdout); - fputs("\n.sp -1\n", stdout); - } - if (rotate_flag) - printf(".if '\\*(.T'ps' \\{\\\n" - "\\X'ps: exec grestore'\n.sp -1\n" - ".\\}\n"); -} - -void troff_output::line_thickness(double p) -{ - if (p < 0.0) - p = RELATIVE_THICKNESS; - if (driver_extension_flag && p != last_line_thickness) { - printf("\\D't %.3fp'\\h'%.3fp'\n.sp -1\n", p, -p); - last_line_thickness = p; - } -} - -void troff_output::set_fill(double f) -{ - if (driver_extension_flag && f != last_fill) { - printf("\\D'f %du'\\h'%du'\n.sp -1\n", int(f*FILL_MAX), -int(f*FILL_MAX)); - last_fill = f; - } -} - -const double DOT_AXIS = .044; - -void troff_output::dot(const position ¢, const line_type <) -{ - if (driver_extension_flag) { - line_thickness(lt.thickness); - simple_line(cent, cent); - } - else { - position c = transform(cent); - printf("\\h'%.3fi-(\\w'.'u/2u)'" - "\\v'%.3fi+%.2fm'" - ".\n.sp -1\n", - c.x, - c.y, - DOT_AXIS); - } -} - -void troff_output::set_location(const char *s, int n) -{ - if (last_filename != 0 && strcmp(s, last_filename) == 0) - printf(".lf %d\n", n); - else { - printf(".lf %d %s\n", n, s); - last_filename = s; - } -} |