summaryrefslogtreecommitdiff
path: root/contrib/groff/src/roff/troff/column.cc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/groff/src/roff/troff/column.cc')
-rw-r--r--contrib/groff/src/roff/troff/column.cc732
1 files changed, 0 insertions, 732 deletions
diff --git a/contrib/groff/src/roff/troff/column.cc b/contrib/groff/src/roff/troff/column.cc
deleted file mode 100644
index 8d6a6ebe5976d..0000000000000
--- a/contrib/groff/src/roff/troff/column.cc
+++ /dev/null
@@ -1,732 +0,0 @@
-// -*- C++ -*-
-/* Copyright (C) 1989, 1990, 1991, 1992, 2000 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. */
-
-#ifdef COLUMN
-
-#include "troff.h"
-#include "symbol.h"
-#include "dictionary.h"
-#include "hvunits.h"
-#include "env.h"
-#include "request.h"
-#include "node.h"
-#include "token.h"
-#include "div.h"
-#include "reg.h"
-#include "stringclass.h"
-
-void output_file::vjustify(vunits, symbol)
-{
- // do nothing
-}
-
-struct justification_spec;
-struct output_line;
-
-class column : public output_file {
-private:
- output_file *out;
- vunits bottom;
- output_line *col;
- output_line **tail;
- void add_output_line(output_line *);
- void begin_page(int pageno, vunits page_length);
- void flush();
- void print_line(hunits, vunits, node *, vunits, vunits);
- void vjustify(vunits, symbol);
- void transparent_char(unsigned char c);
- void copy_file(hunits, vunits, const char *);
- int is_printing();
- void check_bottom();
-public:
- column();
- ~column();
- void start();
- void output();
- void justify(const justification_spec &);
- void trim();
- void reset();
- vunits get_bottom();
- vunits get_last_extra_space();
- int is_active() { return out != 0; }
-};
-
-column *the_column = 0;
-
-struct transparent_output_line;
-struct vjustify_output_line;
-
-class output_line {
- output_line *next;
-public:
- output_line();
- virtual ~output_line();
- virtual void output(output_file *, vunits);
- virtual transparent_output_line *as_transparent_output_line();
- virtual vjustify_output_line *as_vjustify_output_line();
- virtual vunits distance();
- virtual vunits height();
- virtual void reset();
- virtual vunits extra_space(); // post line
- friend class column;
- friend class justification_spec;
-};
-
-class position_output_line : public output_line {
- vunits dist;
-public:
- position_output_line(vunits);
- vunits distance();
-};
-
-class node_output_line : public position_output_line {
- node *nd;
- hunits page_offset;
- vunits before;
- vunits after;
-public:
- node_output_line(vunits, node *, hunits, vunits, vunits);
- ~node_output_line();
- void output(output_file *, vunits);
- vunits height();
- vunits extra_space();
-};
-
-class vjustify_output_line : public position_output_line {
- vunits current;
- symbol typ;
-public:
- vjustify_output_line(vunits dist, symbol);
- vunits height();
- vjustify_output_line *as_vjustify_output_line();
- void vary(vunits amount);
- void reset();
- symbol type();
-};
-
-inline symbol vjustify_output_line::type()
-{
- return typ;
-}
-
-class copy_file_output_line : public position_output_line {
- symbol filename;
- hunits hpos;
-public:
- copy_file_output_line(vunits, const char *, hunits);
- void output(output_file *, vunits);
-};
-
-class transparent_output_line : public output_line {
- string buf;
-public:
- transparent_output_line();
- void output(output_file *, vunits);
- void append_char(unsigned char c);
- transparent_output_line *as_transparent_output_line();
-};
-
-output_line::output_line() : next(0)
-{
-}
-
-output_line::~output_line()
-{
-}
-
-void output_line::reset()
-{
-}
-
-transparent_output_line *output_line::as_transparent_output_line()
-{
- return 0;
-}
-
-vjustify_output_line *output_line::as_vjustify_output_line()
-{
- return 0;
-}
-
-void output_line::output(output_file *, vunits)
-{
-}
-
-vunits output_line::distance()
-{
- return V0;
-}
-
-vunits output_line::height()
-{
- return V0;
-}
-
-vunits output_line::extra_space()
-{
- return V0;
-}
-
-position_output_line::position_output_line(vunits d)
-: dist(d)
-{
-}
-
-vunits position_output_line::distance()
-{
- return dist;
-}
-
-node_output_line::node_output_line(vunits d, node *n, hunits po, vunits b, vunits a)
-: position_output_line(d), nd(n), page_offset(po), before(b), after(a)
-{
-}
-
-node_output_line::~node_output_line()
-{
- delete_node_list(nd);
-}
-
-void node_output_line::output(output_file *out, vunits pos)
-{
- out->print_line(page_offset, pos, nd, before, after);
- nd = 0;
-}
-
-vunits node_output_line::height()
-{
- return after;
-}
-
-vunits node_output_line::extra_space()
-{
- return after;
-}
-
-vjustify_output_line::vjustify_output_line(vunits d, symbol t)
-: position_output_line(d), typ(t)
-{
-}
-
-void vjustify_output_line::reset()
-{
- current = V0;
-}
-
-vunits vjustify_output_line::height()
-{
- return current;
-}
-
-vjustify_output_line *vjustify_output_line::as_vjustify_output_line()
-{
- return this;
-}
-
-inline void vjustify_output_line::vary(vunits amount)
-{
- current += amount;
-}
-
-transparent_output_line::transparent_output_line()
-{
-}
-
-transparent_output_line *transparent_output_line::as_transparent_output_line()
-{
- return this;
-}
-
-void transparent_output_line::append_char(unsigned char c)
-{
- assert(c != 0);
- buf += c;
-}
-
-void transparent_output_line::output(output_file *out, vunits)
-{
- int len = buf.length();
- for (int i = 0; i < len; i++)
- out->transparent_char(buf[i]);
-}
-
-copy_file_output_line::copy_file_output_line(vunits d, const char *f, hunits h)
-: position_output_line(d), hpos(h), filename(f)
-{
-}
-
-void copy_file_output_line::output(output_file *out, vunits pos)
-{
- out->copy_file(hpos, pos, filename.contents());
-}
-
-column::column()
-: bottom(V0), col(0), tail(&col), out(0)
-{
-}
-
-column::~column()
-{
- assert(out != 0);
- error("automatically outputting column before exiting");
- output();
- delete the_output;
-}
-
-void column::start()
-{
- assert(out == 0);
- if (!the_output)
- init_output();
- assert(the_output != 0);
- out = the_output;
- the_output = this;
-}
-
-void column::begin_page(int pageno, vunits page_length)
-{
- assert(out != 0);
- if (col) {
- error("automatically outputting column before beginning next page");
- output();
- the_output->begin_page(pageno, page_length);
- }
- else
- out->begin_page(pageno, page_length);
-
-}
-
-void column::flush()
-{
- assert(out != 0);
- out->flush();
-}
-
-int column::is_printing()
-{
- assert(out != 0);
- return out->is_printing();
-}
-
-vunits column::get_bottom()
-{
- return bottom;
-}
-
-void column::add_output_line(output_line *ln)
-{
- *tail = ln;
- bottom += ln->distance();
- bottom += ln->height();
- ln->next = 0;
- tail = &(*tail)->next;
-}
-
-void column::print_line(hunits page_offset, vunits pos, node *nd,
- vunits before, vunits after)
-{
- assert(out != 0);
- add_output_line(new node_output_line(pos - bottom, nd, page_offset, before, after));
-}
-
-void column::vjustify(vunits pos, symbol typ)
-{
- assert(out != 0);
- add_output_line(new vjustify_output_line(pos - bottom, typ));
-}
-
-void column::transparent_char(unsigned char c)
-{
- assert(out != 0);
- transparent_output_line *tl = 0;
- if (*tail)
- tl = (*tail)->as_transparent_output_line();
- if (!tl) {
- tl = new transparent_output_line;
- add_output_line(tl);
- }
- tl->append_char(c);
-}
-
-void column::copy_file(hunits page_offset, vunits pos, const char *filename)
-{
- assert(out != 0);
- add_output_line(new copy_file_output_line(pos - bottom, filename, page_offset));
-}
-
-void column::trim()
-{
- output_line **spp = 0;
- for (output_line **pp = &col; *pp; pp = &(*pp)->next)
- if ((*pp)->as_vjustify_output_line() == 0)
- spp = 0;
- else if (!spp)
- spp = pp;
- if (spp) {
- output_line *ln = *spp;
- *spp = 0;
- tail = spp;
- while (ln) {
- output_line *tem = ln->next;
- bottom -= ln->distance();
- bottom -= ln->height();
- delete ln;
- ln = tem;
- }
- }
-}
-
-void column::reset()
-{
- bottom = V0;
- for (output_line *ln = col; ln; ln = ln->next) {
- bottom += ln->distance();
- ln->reset();
- bottom += ln->height();
- }
-}
-
-void column::check_bottom()
-{
- vunits b;
- for (output_line *ln = col; ln; ln = ln->next) {
- b += ln->distance();
- b += ln->height();
- }
- assert(b == bottom);
-}
-
-void column::output()
-{
- assert(out != 0);
- vunits vpos(V0);
- output_line *ln = col;
- while (ln) {
- vpos += ln->distance();
- ln->output(out, vpos);
- vpos += ln->height();
- output_line *tem = ln->next;
- delete ln;
- ln = tem;
- }
- tail = &col;
- bottom = V0;
- col = 0;
- the_output = out;
- out = 0;
-}
-
-vunits column::get_last_extra_space()
-{
- if (!col)
- return V0;
- for (output_line *p = col; p->next; p = p->next)
- ;
- return p->extra_space();
-}
-
-class justification_spec {
- vunits height;
- symbol *type;
- vunits *amount;
- int n;
- int maxn;
-public:
- justification_spec(vunits);
- ~justification_spec();
- void append(symbol t, vunits v);
- void justify(output_line *, vunits *bottomp) const;
-};
-
-justification_spec::justification_spec(vunits h)
-: height(h), n(0), maxn(10)
-{
- type = new symbol[maxn];
- amount = new vunits[maxn];
-}
-
-justification_spec::~justification_spec()
-{
- a_delete type;
- a_delete amount;
-}
-
-void justification_spec::append(symbol t, vunits v)
-{
- if (v <= V0) {
- if (v < V0)
- warning(WARN_RANGE,
- "maximum space for vertical justification must not be negative");
- else
- warning(WARN_RANGE,
- "maximum space for vertical justification must not be zero");
- return;
- }
- if (n >= maxn) {
- maxn *= 2;
- symbol *old_type = type;
- type = new symbol[maxn];
- int i;
- for (i = 0; i < n; i++)
- type[i] = old_type[i];
- a_delete old_type;
- vunits *old_amount = amount;
- amount = new vunits[maxn];
- for (i = 0; i < n; i++)
- amount[i] = old_amount[i];
- a_delete old_amount;
- }
- assert(n < maxn);
- type[n] = t;
- amount[n] = v;
- n++;
-}
-
-void justification_spec::justify(output_line *col, vunits *bottomp) const
-{
- if (*bottomp >= height)
- return;
- vunits total;
- output_line *p;
- for (p = col; p; p = p->next) {
- vjustify_output_line *sp = p->as_vjustify_output_line();
- if (sp) {
- symbol t = sp->type();
- for (int i = 0; i < n; i++) {
- if (t == type[i])
- total += amount[i];
- }
- }
- }
- vunits gap = height - *bottomp;
- for (p = col; p; p = p->next) {
- vjustify_output_line *sp = p->as_vjustify_output_line();
- if (sp) {
- symbol t = sp->type();
- for (int i = 0; i < n; i++) {
- if (t == type[i]) {
- if (total <= gap) {
- sp->vary(amount[i]);
- gap -= amount[i];
- }
- else {
- // gap < total
- vunits v = scale(amount[i], gap, total);
- sp->vary(v);
- gap -= v;
- }
- total -= amount[i];
- }
- }
- }
- }
- assert(total == V0);
- *bottomp = height - gap;
-}
-
-void column::justify(const justification_spec &js)
-{
- check_bottom();
- js.justify(col, &bottom);
- check_bottom();
-}
-
-void column_justify()
-{
- vunits height;
- if (!the_column->is_active())
- error("can't justify column - column not active");
- else if (get_vunits(&height, 'v')) {
- justification_spec js(height);
- symbol nm = get_long_name(1);
- if (!nm.is_null()) {
- vunits v;
- if (get_vunits(&v, 'v')) {
- js.append(nm, v);
- int err = 0;
- while (has_arg()) {
- nm = get_long_name(1);
- if (nm.is_null()) {
- err = 1;
- break;
- }
- if (!get_vunits(&v, 'v')) {
- err = 1;
- break;
- }
- js.append(nm, v);
- }
- if (!err)
- the_column->justify(js);
- }
- }
- }
- skip_line();
-}
-
-void column_start()
-{
- if (the_column->is_active())
- error("can't start column - column already active");
- else
- the_column->start();
- skip_line();
-}
-
-void column_output()
-{
- if (!the_column->is_active())
- error("can't output column - column not active");
- else
- the_column->output();
- skip_line();
-}
-
-void column_trim()
-{
- if (!the_column->is_active())
- error("can't trim column - column not active");
- else
- the_column->trim();
- skip_line();
-}
-
-void column_reset()
-{
- if (!the_column->is_active())
- error("can't reset column - column not active");
- else
- the_column->reset();
- skip_line();
-}
-
-class column_bottom_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *column_bottom_reg::get_string()
-{
- return i_to_a(the_column->get_bottom().to_units());
-}
-
-class column_extra_space_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *column_extra_space_reg::get_string()
-{
- return i_to_a(the_column->get_last_extra_space().to_units());
-}
-
-class column_active_reg : public reg {
-public:
- const char *get_string();
-};
-
-const char *column_active_reg::get_string()
-{
- return the_column->is_active() ? "1" : "0";
-}
-
-static int no_vjustify_mode = 0;
-
-class vjustify_node : public node {
- symbol typ;
-public:
- vjustify_node(symbol);
- int reread(int *);
- const char *type();
- int same(node *);
- node *copy();
-};
-
-vjustify_node::vjustify_node(symbol t)
-: typ(t)
-{
-}
-
-node *vjustify_node::copy()
-{
- return new vjustify_node(typ);
-}
-
-const char *vjustify_node::type()
-{
- return "vjustify_node";
-}
-
-int vjustify_node::same(node *nd)
-{
- return typ == ((vjustify_node *)nd)->typ;
-}
-
-int vjustify_node::reread(int *bolp)
-{
- curdiv->vjustify(typ);
- *bolp = 1;
- return 1;
-}
-
-void macro_diversion::vjustify(symbol type)
-{
- if (!no_vjustify_mode)
- mac->append(new vjustify_node(type));
-}
-
-void top_level_diversion::vjustify(symbol type)
-{
- if (no_space_mode || no_vjustify_mode)
- return;
- assert(first_page_begun); // I'm not sure about this.
- the_output->vjustify(vertical_position, type);
-}
-
-void no_vjustify()
-{
- skip_line();
- no_vjustify_mode = 1;
-}
-
-void restore_vjustify()
-{
- skip_line();
- no_vjustify_mode = 0;
-}
-
-void init_column_requests()
-{
- the_column = new column;
- init_request("cols", column_start);
- init_request("colo", column_output);
- init_request("colj", column_justify);
- init_request("colr", column_reset);
- init_request("colt", column_trim);
- init_request("nvj", no_vjustify);
- init_request("rvj", restore_vjustify);
- number_reg_dictionary.define(".colb", new column_bottom_reg);
- number_reg_dictionary.define(".colx", new column_extra_space_reg);
- number_reg_dictionary.define(".cola", new column_active_reg);
- number_reg_dictionary.define(".nvj",
- new constant_int_reg(&no_vjustify_mode));
-}
-
-#endif /* COLUMN */