BSD 4_3_Net_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 5 Aug 1991 04:14:22 +0000 (20:14 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Mon, 5 Aug 1991 04:14:22 +0000 (20:14 -0800)
Work on file usr/src/usr.bin/groff/macros/tmac.tty
Work on file usr/src/usr.bin/groff/grotty/grotty.cc

Synthesized-from: CSRG/cd2/net.2

usr/src/usr.bin/groff/grotty/grotty.cc [new file with mode: 0644]
usr/src/usr.bin/groff/macros/tmac.tty [new file with mode: 0644]

diff --git a/usr/src/usr.bin/groff/grotty/grotty.cc b/usr/src/usr.bin/groff/grotty/grotty.cc
new file mode 100644 (file)
index 0000000..05555ad
--- /dev/null
@@ -0,0 +1,361 @@
+// -*- C++ -*-
+/* Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+     Written by James Clark (jjc@jclark.uucp)
+
+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 1, 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 LICENSE.  If not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "driver.h"
+
+#ifndef USHRT_MAX
+#define USHRT_MAX 65535
+#endif
+
+#define DEFAULT_LINES_PER_PAGE 66
+
+#define TAB_WIDTH 8
+
+static int horizontal_tab_flag = 0;
+static int form_feed_flag = 0;
+static int bold_flag = 1;
+static int underline_flag = 1;
+static int overstrike_flag = 1;
+
+enum { UNDERLINE_MODE = 01, BOLD_MODE = 02 };
+
+// Mode to use for bold-underlining.
+static unsigned char bold_underline_mode = BOLD_MODE|UNDERLINE_MODE;
+
+class tty_font : public font {
+  tty_font(const char *);
+  unsigned char mode;
+public:
+  ~tty_font();
+  unsigned char get_mode() { return mode; }
+#if 0
+  void handle_x_command(int argc, const char **argv);
+#endif
+  static tty_font *load_tty_font(const char *);
+};
+
+tty_font *tty_font::load_tty_font(const char *s)
+{
+  tty_font *f = new tty_font(s);
+  if (!f->load()) {
+    delete f;
+    return 0;
+  }
+  const char *s = f->get_internal_name();
+  long n;
+  if (s != 0 && (n = strtol(s, 0, 0)) != 0)
+    f->mode = int(n & (BOLD_MODE|UNDERLINE_MODE));
+  if (!underline_flag)
+    f->mode &= ~UNDERLINE_MODE;
+  if (!bold_flag)
+    f->mode &= ~BOLD_MODE;
+  if ((f->mode & (BOLD_MODE|UNDERLINE_MODE)) == (BOLD_MODE|UNDERLINE_MODE))
+    f->mode = (f->mode & ~(BOLD_MODE|UNDERLINE_MODE)) | bold_underline_mode;
+  return f;
+}
+
+tty_font::tty_font(const char *nm)
+: font(nm), mode(0)
+{
+}
+
+tty_font::~tty_font()
+{
+}
+
+#if 0
+void tty_font::handle_x_command(int argc, const char **argv)
+{
+  if (argc >= 1 && strcmp(argv[0], "bold") == 0)
+    mode |= BOLD_MODE;
+  else if (argc >= 1 && strcmp(argv[0], "underline") == 0)
+    mode |= UNDERLINE_MODE;
+}
+#endif
+
+// hpos and vpos must be non-adjacent, to work round a bug in g++ 1.37.1
+
+struct glyph {
+  unsigned short hpos;
+  unsigned short serial;
+  unsigned short vpos;
+  unsigned char code;
+  unsigned char mode;
+};
+
+class tty_printer : public printer {
+  enum { INITIAL_VEC_SIZE = 32 };
+  glyph *vec;
+  int vec_used;
+  int vec_size;
+  int lines_per_page;
+  int columns_per_page;
+public:
+  tty_printer();
+  ~tty_printer();
+  void set_char(int, font *, const environment *, int);
+  void begin_page(int) { }
+  void end_page();
+  font *make_font(const char *);
+};
+
+tty_printer::tty_printer()
+: vec_used(0), vec_size(0), vec(0)
+{
+  if (font::paperlength == 0)
+    lines_per_page = DEFAULT_LINES_PER_PAGE;
+  else if (font::paperlength % font::vert != 0)
+    fatal("paperlength not a multiple of vertical resolution");
+  else
+    lines_per_page = font::paperlength/font::vert;
+  if (lines_per_page > USHRT_MAX || lines_per_page <= 0)
+    fatal("ridiculous paperlength");
+  columns_per_page = font::paperwidth/font::hor;
+  // If columns_per_page is zero, we won't truncate.
+  if (columns_per_page < 0)
+    columns_per_page = 0;
+}
+
+tty_printer::~tty_printer()
+{
+  delete vec;
+}
+
+void tty_printer::set_char(int i, font *f, const environment *env, int w)
+{
+  int h = env->hpos;
+  if (h % font::hor != 0)
+    fatal("horizontal position not a multiple of horizontal resolution");
+  h /= font::hor;
+  if (h < 0) {
+    error("character to the left of first column discarded");
+    return;
+  }
+  if (columns_per_page != 0 && h >= columns_per_page) {
+    error("character to the right of last column discarded");
+    return;
+  }
+  if (h > USHRT_MAX) {
+    error("character with ridiculously large horizontal position discarded");
+    return;
+  }
+  int v = env->vpos;
+  if (v % font::vert != 0)
+    fatal("vertical position not a multiple of vertical resolution");
+  v /= font::vert;
+  // Note that the first output line corresponds to groff position font::vert.
+  if (v <= 0) {
+    error("character above first line discarded");
+    return;
+  }
+  if (v > lines_per_page) {
+    error("character below last line discarded");
+    return;
+  }
+  if (w != font::hor)
+    fatal("width of character not equal to horizontal resolution");
+  if (vec_used >= vec_size) {
+    if (vec_size == 0)
+      vec_size = INITIAL_VEC_SIZE;
+    else {
+      if (vec_size > USHRT_MAX/2) {
+       if (vec_size >= USHRT_MAX)
+         fatal("too many characters on the page");
+       vec_size = USHRT_MAX;
+      }
+      else
+       vec_size *= 2;
+    }
+    glyph *old_vec = vec;
+    vec = new glyph [vec_size];
+    if (vec_used)
+      memcpy(vec, old_vec, vec_used*sizeof(glyph));
+    delete old_vec;
+  }
+  // We need a stable sort, but qsort is not stable, so we fake it.
+  vec[vec_used].serial = vec_used;
+  vec[vec_used].hpos = h;
+  vec[vec_used].vpos = v;
+  vec[vec_used].code = f->get_code(i);
+  vec[vec_used].mode = ((tty_font *)f)->get_mode();
+  vec_used++;
+}
+
+extern "C" {
+static int compare_glyph(void *p1, void *p2)
+{
+  int v1 = ((glyph *)p1)->vpos;
+  int v2 = ((glyph *)p2)->vpos;
+  if (v1 < v2)
+    return -1;
+  if (v1 > v2)
+    return 1;
+  int h1 = ((glyph *)p1)->hpos;
+  int h2 = ((glyph *)p2)->hpos;
+  if (h1 < h2)
+    return -1;
+  if (h1 > h2)
+    return 1;
+  if (((glyph *)p1)->serial < ((glyph *)p2)->serial)
+    return -1;
+  return 1;
+}
+}
+
+void tty_printer::end_page()
+{
+  qsort(vec, vec_used, sizeof(glyph), compare_glyph);
+  int hpos = 0;
+  int vpos = 1;
+  // We have already discarded characters with vpos < 1 or > lines_per_page.
+  for (int i = 0; i < vec_used; i++) {
+    assert(vpos <= vec[i].vpos);
+    if (!overstrike_flag
+       && i + 1 < vec_used
+       && vec[i].hpos == vec[i + 1].hpos
+       && vec[i].vpos == vec[i + 1].vpos)
+      continue;
+    for (; vpos < vec[i].vpos; vpos++) {
+      putchar('\n');
+      hpos = 0;
+    }
+    if (hpos > vec[i].hpos) {
+      putchar('\b');
+      hpos--;
+    }
+    else {
+      if (horizontal_tab_flag) {
+       for (;;) {
+         int next_tab_pos = ((hpos + TAB_WIDTH) / TAB_WIDTH) * TAB_WIDTH;
+         if (next_tab_pos > vec[i].hpos)
+           break;
+         putchar('\t');
+         hpos = next_tab_pos;
+       }
+      }
+      for (; hpos < vec[i].hpos; hpos++)
+       putchar(' ');
+    }
+    assert(hpos == vec[i].hpos && vpos == vec[i].vpos);
+    if (isalnum(vec[i].code) && vec[i].mode & UNDERLINE_MODE) {
+      putchar('_');
+      putchar('\b');
+    }
+    if (vec[i].mode & BOLD_MODE) {
+      putchar(vec[i].code);
+      putchar('\b');
+    }
+    putchar(vec[i].code);
+    hpos++;
+  }
+  if (form_feed_flag) {
+    if (hpos != 0) {
+      putchar('\n');
+      vpos++;
+    }
+    if (vpos <= lines_per_page)
+      putchar('\f');
+  }
+  else {
+    for (; vpos <= lines_per_page; vpos++)
+      putchar('\n');
+  }
+  vec_used = 0;
+}
+
+font *tty_printer::make_font(const char *nm)
+{
+  return tty_font::load_tty_font(nm);
+}
+
+printer *make_printer()
+{
+  return new tty_printer;
+}
+
+static void usage();
+
+int main(int argc, char **argv)
+{
+  program_name = argv[0];
+  static char stderr_buf[BUFSIZ];
+  setbuf(stderr, stderr_buf);
+  int c;
+  while ((c = getopt(argc, argv, "F:vhfbuoBU")) != EOF)
+    switch(c) {
+    case 'v':
+      {
+       extern const char *version_string;
+       fprintf(stderr, "grotty version %s\n", version_string);
+       fflush(stderr);
+       break;
+      }
+    case 'b':
+      // Do not embolden by overstriking.
+      bold_flag = 0;
+      break;
+    case 'u':
+      // Do not underline.
+      underline_flag = 0;
+      break;
+    case 'o':
+      // Do not overstrike (other than emboldening and underlining).
+      overstrike_flag = 0;
+      break;
+    case 'B':
+      // Do bold-underlining as bold.
+      bold_underline_mode = BOLD_MODE;
+      break;
+    case 'U':
+      // Do bold-underlining as underlining.
+      bold_underline_mode = UNDERLINE_MODE;
+      break;
+    case 'h':
+      // Use horizontal tabs.
+      horizontal_tab_flag = 1;
+      break;
+    case 'f':
+      form_feed_flag = 1;
+      break;
+    case 'F':
+      font::command_line_font_dir(optarg);
+      break;
+    case '?':
+      usage();
+      break;
+    default:
+      assert(0);
+    }
+  if (optind >= argc)
+    do_file("-");
+  else {
+    for (int i = optind; i < argc; i++)
+      do_file(argv[i]);
+  }
+  delete pr;
+  exit(0);
+}
+
+static void usage()
+{
+  fprintf(stderr, "usage: %s [-hfvbuoBU] [-F dir] [files ...]\n",
+         program_name);
+  exit(1);
+}
diff --git a/usr/src/usr.bin/groff/macros/tmac.tty b/usr/src/usr.bin/groff/macros/tmac.tty
new file mode 100644 (file)
index 0000000..755761b
--- /dev/null
@@ -0,0 +1,44 @@
+.\"
+.\"
+.nr _C \n(.C
+.cp 0
+.nroff
+.ftr CW B
+.ftr C B
+.ftr CR B
+.po 0
+.de tty-char
+.if !c\\$1 .char \\$1 \\$2
+..
+.tty-char \(14 1/4
+.tty-char \(12 1/2
+.tty-char \(34 1/4
+.tty-char \(fi fi
+.tty-char \(fl fl
+.tty-char \(Fi ffi
+.tty-char \(Fl ffl
+.tty-char \(<- <-
+.tty-char \(-> ->
+.tty-char \(<> <->
+.tty-char \(lA <=
+.tty-char \(rA =>
+.tty-char \(<= <=
+.tty-char \(>= =>
+.tty-char \(hA <=>
+.tty-char \(ua ^
+.tty-char \(da v
+.tty-char \(uA ^
+.tty-char \(dA v
+.tty-char \(em --
+.tty-char \(en -
+.tty-char \(ru _
+.tty-char \(ul _
+.tty-char \(br |
+.tty-char \(bv |
+.tty-char \(sl /
+.tty-char \(+- +-
+.tty-char \(co (C)
+.tty-char \(co (C)
+.tty-char \(*G gamma
+.tty-char \(*E epsilon
+.cp \n(_C