From bfbdfe00b3a7278899603d226f338d4bd1c1339a Mon Sep 17 00:00:00 2001 From: ru Date: Thu, 1 May 2003 13:15:22 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r114405, which included commits to RCS files with non-trunk default branches. --- contrib/groff/src/devices/grotty/tty.cc | 776 -------------------------------- 1 file changed, 776 deletions(-) delete mode 100644 contrib/groff/src/devices/grotty/tty.cc (limited to 'contrib/groff/src/devices/grotty') diff --git a/contrib/groff/src/devices/grotty/tty.cc b/contrib/groff/src/devices/grotty/tty.cc deleted file mode 100644 index 7cfb658..0000000 --- a/contrib/groff/src/devices/grotty/tty.cc +++ /dev/null @@ -1,776 +0,0 @@ -// -*- C++ -*- -/* Copyright (C) 1989-2000, 2001, 2002 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 "driver.h" -#include "device.h" - -extern "C" const char *Version_string; - -#define putstring(s) fputs(s, stdout) - -#ifndef SHRT_MIN -#define SHRT_MIN (-32768) -#endif - -#ifndef SHRT_MAX -#define SHRT_MAX 32767 -#endif - -#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; -static int draw_flag = 1; -static int italic_flag = 0; -static int reverse_flag = 0; -static int old_drawing_scheme = 0; - -enum { - UNDERLINE_MODE = 0x01, - BOLD_MODE = 0x02, - VDRAW_MODE = 0x04, - HDRAW_MODE = 0x08, - CU_MODE = 0x10, - COLOR_CHANGE = 0x20 -}; - -// Mode to use for bold-underlining. -static unsigned char bold_underline_mode = BOLD_MODE|UNDERLINE_MODE; - -#ifndef IS_EBCDIC_HOST -#define CSI "\033[" -#else -#define CSI "\047[" -#endif - -// SGR handling (ISO 6429) -#define SGR_BOLD CSI "1m" -#define SGR_NO_BOLD CSI "22m" -#define SGR_ITALIC CSI "3m" -#define SGR_NO_ITALIC CSI "23m" -#define SGR_UNDERLINE CSI "4m" -#define SGR_NO_UNDERLINE CSI "24m" -#define SGR_REVERSE CSI "7m" -#define SGR_NO_REVERSE CSI "27m" -// many terminals can't handle `CSI 39 m' and `CSI 49 m' to reset -// the foreground and bachground color, respectively; thus we use -// `CSI 0 m' exclusively -#define SGR_DEFAULT CSI "0m" - -#define TTY_MAX_COLORS 8 -#define DEFAULT_COLOR_IDX TTY_MAX_COLORS - -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 *num = f->get_internal_name(); - long n; - if (num != 0 && (n = strtol(num, 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 - -class glyph { - static glyph *free_list; -public: - glyph *next; - short hpos; - unsigned int code; - unsigned char mode; - unsigned char back_color_idx; - unsigned char fore_color_idx; - void *operator new(size_t); - void operator delete(void *); - inline int draw_mode() { return mode & (VDRAW_MODE|HDRAW_MODE); } - inline int order() { - return mode & (VDRAW_MODE|HDRAW_MODE|CU_MODE|COLOR_CHANGE); } -}; - -glyph *glyph::free_list = 0; - -void *glyph::operator new(size_t) -{ - if (!free_list) { - const int BLOCK = 1024; - free_list = (glyph *)new char[sizeof(glyph) * BLOCK]; - for (int i = 0; i < BLOCK - 1; i++) - free_list[i].next = free_list + i + 1; - free_list[BLOCK - 1].next = 0; - } - glyph *p = free_list; - free_list = free_list->next; - p->next = 0; - return p; -} - -void glyph::operator delete(void *p) -{ - if (p) { - ((glyph *)p)->next = free_list; - free_list = (glyph *)p; - } -} - -class tty_printer : public printer { - int is_utf8; - glyph **lines; - int nlines; - int cached_v; - int cached_vpos; - unsigned char curr_fore_idx; - unsigned char curr_back_idx; - int is_underline; - int is_bold; - int cu_flag; - color tty_colors[TTY_MAX_COLORS]; - void make_underline(); - void make_bold(unsigned int); - unsigned char color_to_idx(color *col); - void add_char(unsigned int, int, int, color *, color *, unsigned char); -public: - tty_printer(const char *device); - ~tty_printer(); - void set_char(int, font *, const environment *, int, const char *name); - void draw(int code, int *p, int np, const environment *env); - void special(char *arg, const environment *env, char type); - void change_color(const environment *env); - void change_fill_color(const environment *env); - void put_char(unsigned int); - void put_color(unsigned char, int); - void begin_page(int) { } - void end_page(int page_length); - font *make_font(const char *); -}; - -tty_printer::tty_printer(const char *device) : cached_v(0) -{ - is_utf8 = !strcmp(device, "utf8"); - tty_colors[0].set_rgb(0, // black - 0, - 0); - tty_colors[1].set_rgb(color::MAX_COLOR_VAL, // red - 0, - 0); - tty_colors[2].set_rgb(0, // green - color::MAX_COLOR_VAL, - 0); - tty_colors[3].set_rgb(color::MAX_COLOR_VAL, // yellow - color::MAX_COLOR_VAL, - 0); - tty_colors[4].set_rgb(0, // blue - 0, - color::MAX_COLOR_VAL); - tty_colors[5].set_rgb(color::MAX_COLOR_VAL, // magenta - 0, - color::MAX_COLOR_VAL); - tty_colors[6].set_rgb(0, // cyan - color::MAX_COLOR_VAL, - color::MAX_COLOR_VAL); - tty_colors[7].set_rgb(color::MAX_COLOR_VAL, // white - color::MAX_COLOR_VAL, - color::MAX_COLOR_VAL); - nlines = 66; - lines = new glyph *[nlines]; - for (int i = 0; i < nlines; i++) - lines[i] = 0; - cu_flag = 0; -} - -tty_printer::~tty_printer() -{ - a_delete lines; -} - -void tty_printer::make_underline() -{ - if (old_drawing_scheme) { - putchar('_'); - putchar('\b'); - } - else { - if (!is_underline) { - if (italic_flag) - putstring(SGR_ITALIC); - else if (reverse_flag) - putstring(SGR_REVERSE); - else - putstring(SGR_UNDERLINE); - } - is_underline = 1; - } -} - -void tty_printer::make_bold(unsigned int c) -{ - if (old_drawing_scheme) { - put_char(c); - putchar('\b'); - } - else { - if (!is_bold) - putstring(SGR_BOLD); - is_bold = 1; - } -} - -unsigned char tty_printer::color_to_idx(color *col) -{ - if (col->is_default()) - return DEFAULT_COLOR_IDX; - for (int i = 0; i < TTY_MAX_COLORS; i++) - if (*col == tty_colors[i]) - return (unsigned char)i; - unsigned r, g, b; - col->get_rgb(&r, &g, &b); - error("Unknown color (%1, %2, %3) mapped to default", r, g, b); - return DEFAULT_COLOR_IDX; -} - -void tty_printer::set_char(int i, font *f, const environment *env, - int w, const char *name) -{ - if (w != font::hor) - fatal("width of character not equal to horizontal resolution"); - add_char(f->get_code(i), - env->hpos, env->vpos, - env->col, env->fill, - ((tty_font *)f)->get_mode()); -} - -void tty_printer::add_char(unsigned int c, - int h, int v, - color *fore, color *back, - unsigned char mode) -{ -#if 0 - // This is too expensive. - if (h % font::hor != 0) - fatal("horizontal position not a multiple of horizontal resolution"); -#endif - int hpos = h / font::hor; - if (hpos < SHRT_MIN || hpos > SHRT_MAX) { - error("character with ridiculous horizontal position discarded"); - return; - } - int vpos; - if (v == cached_v && cached_v != 0) - vpos = cached_vpos; - else { - if (v % font::vert != 0) - fatal("vertical position not a multiple of vertical resolution"); - vpos = v / font::vert; - if (vpos > nlines) { - glyph **old_lines = lines; - lines = new glyph *[vpos + 1]; - memcpy(lines, old_lines, nlines * sizeof(glyph *)); - for (int i = nlines; i <= vpos; i++) - lines[i] = 0; - a_delete old_lines; - nlines = vpos + 1; - } - // Note that the first output line corresponds to groff - // position font::vert. - if (vpos <= 0) { - error("character above first line discarded"); - return; - } - cached_v = v; - cached_vpos = vpos; - } - glyph *g = new glyph; - g->hpos = hpos; - g->code = c; - g->fore_color_idx = color_to_idx(fore); - g->back_color_idx = color_to_idx(back); - g->mode = mode; - - // The list will be reversed later. After reversal, it must be in - // increasing order of hpos, with COLOR_CHANGE and CU specials before - // HDRAW characters before VDRAW characters before normal characters - // at each hpos, and otherwise in order of occurrence. - - glyph **pp; - for (pp = lines + (vpos - 1); *pp; pp = &(*pp)->next) - if ((*pp)->hpos < hpos - || ((*pp)->hpos == hpos && (*pp)->order() >= g->order())) - break; - g->next = *pp; - *pp = g; -} - -void tty_printer::special(char *arg, const environment *env, char type) -{ - if (type == 'u') { - add_char(*arg - '0', env->hpos, env->vpos, env->col, env->fill, CU_MODE); - return; - } - if (type != 'p') - return; - char *p; - for (p = arg; *p == ' ' || *p == '\n'; p++) - ; - char *tag = p; - for (; *p != '\0' && *p != ':' && *p != ' ' && *p != '\n'; p++) - ; - if (*p == '\0' || strncmp(tag, "tty", p - tag) != 0) { - error("X command without `tty:' tag ignored"); - return; - } - p++; - for (; *p == ' ' || *p == '\n'; p++) - ; - char *command = p; - for (; *p != '\0' && *p != ' ' && *p != '\n'; p++) - ; - if (*command == '\0') { - error("empty X command ignored"); - return; - } - if (strncmp(command, "sgr", p - command) == 0) { - for (; *p == ' ' || *p == '\n'; p++) - ; - int n; - if (*p != '\0' && sscanf(p, "%d", &n) == 1 && n == 0) - old_drawing_scheme = 1; - else - old_drawing_scheme = 0; - } -} - -void tty_printer::change_color(const environment *env) -{ - add_char(0, env->hpos, env->vpos, env->col, env->fill, COLOR_CHANGE); -} - -void tty_printer::change_fill_color(const environment *env) -{ - add_char(0, env->hpos, env->vpos, env->col, env->fill, COLOR_CHANGE); -} - -void tty_printer::draw(int code, int *p, int np, const environment *env) -{ - if (code != 'l' || !draw_flag) - return; - if (np != 2) { - error("2 arguments required for line"); - return; - } - if (p[0] == 0) { - // vertical line - int v = env->vpos; - int len = p[1]; - if (len < 0) { - v += len; - len = -len; - } - while (len >= 0) { - add_char('|', env->hpos, v, env->col, env->fill, VDRAW_MODE); - len -= font::vert; - v += font::vert; - } - } - if (p[1] == 0) { - // horizontal line - int h = env->hpos; - int len = p[0]; - if (len < 0) { - h += len; - len = -len; - } - while (len >= 0) { - add_char('-', h, env->vpos, env->col, env->fill, HDRAW_MODE); - len -= font::hor; - h += font::hor; - } - } -} - -void tty_printer::put_char(unsigned int wc) -{ - if (is_utf8 && wc >= 0x80) { - char buf[6 + 1]; - int count; - char *p = buf; - if (wc < 0x800) - count = 1, *p = (unsigned char)((wc >> 6) | 0xc0); - else if (wc < 0x10000) - count = 2, *p = (unsigned char)((wc >> 12) | 0xe0); - else if (wc < 0x200000) - count = 3, *p = (unsigned char)((wc >> 18) | 0xf0); - else if (wc < 0x4000000) - count = 4, *p = (unsigned char)((wc >> 24) | 0xf8); - else if (wc <= 0x7fffffff) - count = 5, *p = (unsigned char)((wc >> 30) | 0xfC); - else - return; - do *++p = (unsigned char)(((wc >> (6 * --count)) & 0x3f) | 0x80); - while (count > 0); - *++p = '\0'; - putstring(buf); - } - else - putchar(wc); -} - -void tty_printer::put_color(unsigned char color_index, int back) -{ - if (color_index == DEFAULT_COLOR_IDX) { - putstring(SGR_DEFAULT); - // set bold and underline again - if (is_bold) - putstring(SGR_BOLD); - if (is_underline) { - if (italic_flag) - putstring(SGR_ITALIC); - else if (reverse_flag) - putstring(SGR_REVERSE); - else - putstring(SGR_UNDERLINE); - } - // set other color again - back = !back; - color_index = back ? curr_back_idx : curr_fore_idx; - } - putstring(CSI); - if (back) - putchar('4'); - else - putchar('3'); - putchar(color_index + '0'); - putchar('m'); -} - -void tty_printer::end_page(int page_length) -{ - if (page_length % font::vert != 0) - error("vertical position at end of page not multiple of vertical resolution"); - int lines_per_page = page_length / font::vert; - int last_line; - for (last_line = nlines; last_line > 0; last_line--) - if (lines[last_line - 1]) - break; -#if 0 - if (last_line > lines_per_page) { - error("characters past last line discarded"); - do { - --last_line; - while (lines[last_line]) { - glyph *tem = lines[last_line]; - lines[last_line] = tem->next; - delete tem; - } - } while (last_line > lines_per_page); - } -#endif - for (int i = 0; i < last_line; i++) { - glyph *p = lines[i]; - lines[i] = 0; - glyph *g = 0; - while (p) { - glyph *tem = p->next; - p->next = g; - g = p; - p = tem; - } - int hpos = 0; - glyph *nextp; - curr_fore_idx = DEFAULT_COLOR_IDX; - curr_back_idx = DEFAULT_COLOR_IDX; - is_underline = 0; - is_bold = 0; - for (p = g; p; delete p, p = nextp) { - nextp = p->next; - if (p->mode & CU_MODE) { - cu_flag = p->code; - continue; - } - if (nextp && p->hpos == nextp->hpos) { - if (p->draw_mode() == HDRAW_MODE && - nextp->draw_mode() == VDRAW_MODE) { - nextp->code = '+'; - continue; - } - if (p->draw_mode() != 0 && p->draw_mode() == nextp->draw_mode()) { - nextp->code = p->code; - continue; - } - if (!overstrike_flag) - continue; - } - if (hpos > p->hpos) { - do { - putchar('\b'); - hpos--; - } while (hpos > p->hpos); - } - else { - if (horizontal_tab_flag) { - for (;;) { - int next_tab_pos = ((hpos + TAB_WIDTH) / TAB_WIDTH) * TAB_WIDTH; - if (next_tab_pos > p->hpos) - break; - if (cu_flag) - make_underline(); - else if (!old_drawing_scheme && is_underline) { - if (italic_flag) - putstring(SGR_NO_ITALIC); - else if (reverse_flag) - putstring(SGR_NO_REVERSE); - else - putstring(SGR_NO_UNDERLINE); - is_underline = 0; - } - putchar('\t'); - hpos = next_tab_pos; - } - } - for (; hpos < p->hpos; hpos++) { - if (cu_flag) - make_underline(); - else if (!old_drawing_scheme && is_underline) { - if (italic_flag) - putstring(SGR_NO_ITALIC); - else if (reverse_flag) - putstring(SGR_NO_REVERSE); - else - putstring(SGR_NO_UNDERLINE); - is_underline = 0; - } - putchar(' '); - } - } - assert(hpos == p->hpos); - if (p->mode & COLOR_CHANGE) { - if (!old_drawing_scheme) { - if (p->fore_color_idx != curr_fore_idx) { - put_color(p->fore_color_idx, 0); - curr_fore_idx = p->fore_color_idx; - } - if (p->back_color_idx != curr_back_idx) { - put_color(p->back_color_idx, 1); - curr_back_idx = p->back_color_idx; - } - } - continue; - } - if (p->mode & UNDERLINE_MODE) - make_underline(); - else if (!old_drawing_scheme && is_underline) { - if (italic_flag) - putstring(SGR_NO_ITALIC); - else if (reverse_flag) - putstring(SGR_NO_REVERSE); - else - putstring(SGR_NO_UNDERLINE); - is_underline = 0; - } - if (p->mode & BOLD_MODE) - make_bold(p->code); - else if (!old_drawing_scheme && is_bold) { - putstring(SGR_NO_BOLD); - is_bold = 0; - } - if (!old_drawing_scheme) { - if (p->fore_color_idx != curr_fore_idx) { - put_color(p->fore_color_idx, 0); - curr_fore_idx = p->fore_color_idx; - } - if (p->back_color_idx != curr_back_idx) { - put_color(p->back_color_idx, 1); - curr_back_idx = p->back_color_idx; - } - } - put_char(p->code); - hpos++; - } - if (!old_drawing_scheme - && (is_bold || is_underline - || curr_fore_idx != DEFAULT_COLOR_IDX - || curr_back_idx != DEFAULT_COLOR_IDX)) - putstring(SGR_DEFAULT); - putchar('\n'); - } - if (form_feed_flag) { - if (last_line < lines_per_page) - putchar('\f'); - } - else { - for (; last_line < lines_per_page; last_line++) - putchar('\n'); - } -} - -font *tty_printer::make_font(const char *nm) -{ - return tty_font::load_tty_font(nm); -} - -printer *make_printer() -{ - return new tty_printer(device); -} - -static void usage(FILE *stream); - -int main(int argc, char **argv) -{ - program_name = argv[0]; - static char stderr_buf[BUFSIZ]; - if (getenv("GROFF_NO_SGR")) - old_drawing_scheme = 1; - setbuf(stderr, stderr_buf); - int c; - static const struct option long_options[] = { - { "help", no_argument, 0, CHAR_MAX + 1 }, - { "version", no_argument, 0, 'v' }, - { NULL, 0, 0, 0 } - }; - while ((c = getopt_long(argc, argv, "bBcdfF:hioruUv", long_options, NULL)) - != EOF) - switch(c) { - case 'v': - printf("GNU grotty (groff) version %s\n", Version_string); - exit(0); - break; - case 'i': - // Use italic font instead of underlining. - italic_flag = 1; - break; - case 'b': - // Do not embolden by overstriking. - bold_flag = 0; - break; - case 'c': - // Use old scheme for emboldening and underline. - old_drawing_scheme = 1; - 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 'r': - // Use reverse mode instead of underlining. - reverse_flag = 1; - 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 'd': - // Ignore \D commands. - draw_flag = 0; - break; - case CHAR_MAX + 1: // --help - usage(stdout); - exit(0); - break; - case '?': - usage(stderr); - exit(1); - break; - default: - assert(0); - } - if (old_drawing_scheme) { - italic_flag = 0; - reverse_flag = 0; - } - else { - bold_underline_mode = BOLD_MODE|UNDERLINE_MODE; - bold_flag = 1; - underline_flag = 1; - } - if (optind >= argc) - do_file("-"); - else { - for (int i = optind; i < argc; i++) - do_file(argv[i]); - } - delete pr; - return 0; -} - -static void usage(FILE *stream) -{ - fprintf(stream, "usage: %s [-bBcdfhioruUv] [-F dir] [files ...]\n", - program_name); -} -- cgit v1.1