groff before CVS: release 1.05
[s-roff.git] / driver / printer.c
blobf498b8cb5fc8e3b317bb4ddbb15b1f640b0f80fb
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.uucp)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 1, or (at your option) any later
10 version.
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file LICENSE. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "driver.h"
23 printer *pr = 0;
25 font_pointer_list::font_pointer_list(font *f, font_pointer_list *fp)
26 : p(f), next(fp)
30 printer::printer()
31 : font_table(0), nfonts(0), font_list(0)
35 printer::~printer()
37 a_delete font_table;
38 while (font_list) {
39 font_pointer_list *tem = font_list;
40 font_list = font_list->next;
41 delete tem->p;
42 delete tem;
44 if (ferror(stdout) || fflush(stdout) < 0)
45 fatal("output error");
48 void printer::load_font(int n, const char *nm)
50 assert(n >= 0);
51 if (n >= nfonts) {
52 if (nfonts == 0) {
53 nfonts = 10;
54 if (nfonts <= n)
55 nfonts = n + 1;
56 font_table = new font *[nfonts];
57 for (int i = 0; i < nfonts; i++)
58 font_table[i] = 0;
60 else {
61 font **old_font_table = font_table;
62 int old_nfonts = nfonts;
63 nfonts *= 2;
64 if (n >= nfonts)
65 nfonts = n + 1;
66 font_table = new font *[nfonts];
67 for (int i = 0; i < old_nfonts; i++)
68 font_table[i] = old_font_table[i];
69 for (i = old_nfonts; i < nfonts; i++)
70 font_table[i] = 0;
73 font *f = find_font(nm);
74 font_table[n] = f;
77 font *printer::find_font(const char *nm)
79 for (font_pointer_list *p = font_list; p; p = p->next)
80 if (strcmp(p->p->get_name(), nm) == 0)
81 return p->p;
82 font *f = make_font(nm);
83 if (!f)
84 fatal("sorry, I can't continue");
85 font_list = new font_pointer_list(f, font_list);
86 return f;
89 font *printer::make_font(const char *nm)
91 return font::load_font(nm);
94 void printer::end_of_line()
98 void printer::special(char *, const environment *)
102 void printer::draw(int, int *, int, const environment *)
106 void printer::set_ascii_char(unsigned char c, const environment *env,
107 int *widthp)
109 char buf[2];
110 buf[0] = c;
111 buf[1] = '\0';
112 set_special_char(buf, env, widthp);
115 void printer::set_special_char(const char *nm, const environment *env,
116 int *widthp)
118 int i = font::name_to_index(nm);
119 int fn = env->fontno;
120 if (fn < 0 || fn >= nfonts) {
121 error("bad font position `%1'", fn);
122 return;
124 font *f = font_table[fn];
125 if (f == 0) {
126 error("no font mounted at `%1'", fn);
127 return;
129 if (!f->contains(i)) {
130 if (nm[0] != '\0' && nm[1] == '\0')
131 error("font `%1' does not contain ascii character `%2'",
132 f->get_name(),
133 nm[0]);
134 else
135 error("font `%1' does not contain special character `%2'",
136 f->get_name(),
137 nm);
138 return;
140 int w = f->get_width(i, env->size);
141 if (widthp)
142 *widthp = w;
143 set_char(i, f, env, w);
146 void printer::set_numbered_char(int num, const environment *env, int *widthp)
148 int i = font::number_to_index(num);
149 int fn = env->fontno;
150 if (fn < 0 || fn >= nfonts) {
151 error("bad font position `%1'", fn);
152 return;
154 font *f = font_table[fn];
155 if (f == 0) {
156 error("no font mounted at `%1'", fn);
157 return;
159 if (!f->contains(i)) {
160 error("font `%1' does not contain numbered character %2",
161 f->get_name(),
162 num);
163 return;
165 int w = f->get_width(i, env->size);
166 if (widthp)
167 *widthp = w;
168 set_char(i, f, env, w);