Add groff 1.19.1, stripped down appropriately.
[dragonfly.git] / contrib / groff-1.19 / src / libs / libdriver / printer.cpp
1 // -*- C++ -*-
2
3 // <groff_src_dir>/src/libs/libdriver/printer.cpp
4
5 /* Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002, 2003
6    Free Software Foundation, Inc.
7    Written by James Clark (jjc@jclark.com)
8
9    Last update: 04 Apr 2003
10
11    This file is part of groff.
12
13    groff is free software; you can redistribute it and/or modify it
14    under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2, or (at your option)
16    any later version.
17
18    groff is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with groff; see the file COPYING.  If not, write to the Free
25    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26    02111-1307, USA.
27 */
28
29 #include "driver.h"
30
31 font_pointer_list::font_pointer_list(font *f, font_pointer_list *fp)
32 : p(f), next(fp)
33 {
34 }
35
36 printer::printer()
37 : font_list(0), font_table(0), nfonts(0)
38 {
39 }
40
41 printer::~printer()
42 {
43   a_delete font_table;
44   while (font_list) {
45     font_pointer_list *tem = font_list;
46     font_list = font_list->next;
47     delete tem->p;
48     delete tem;
49   }
50   if (ferror(stdout) || fflush(stdout) < 0)
51     fatal("output error");
52 }
53
54 void printer::load_font(int n, const char *nm)
55 {
56   assert(n >= 0);
57   if (n >= nfonts) {
58     if (nfonts == 0) {
59       nfonts = 10;
60       if (nfonts <= n)
61         nfonts = n + 1;
62       font_table = new font *[nfonts];
63       for (int i = 0; i < nfonts; i++)
64         font_table[i] = 0;
65     }
66     else {
67       font **old_font_table = font_table;
68       int old_nfonts = nfonts;
69       nfonts *= 2;
70       if (n >= nfonts)
71         nfonts = n + 1;
72       font_table = new font *[nfonts];
73       int i;
74       for (i = 0; i < old_nfonts; i++)
75         font_table[i] = old_font_table[i];
76       for (i = old_nfonts; i < nfonts; i++)
77         font_table[i] = 0;
78       a_delete old_font_table;
79     }
80   }
81   font *f = find_font(nm);
82   font_table[n] = f;
83 }
84
85 font *printer::find_font(const char *nm)
86 {
87   for (font_pointer_list *p = font_list; p; p = p->next)
88     if (strcmp(p->p->get_name(), nm) == 0)
89       return p->p;
90   font *f = make_font(nm);
91   if (!f)
92     fatal("sorry, I can't continue");
93   font_list = new font_pointer_list(f, font_list);
94   return f;
95 }
96
97 font *printer::make_font(const char *nm)
98 {
99   return font::load_font(nm);
100 }
101
102 void printer::end_of_line()
103 {
104 }
105
106 void printer::special(char *, const environment *, char)
107 {
108 }
109
110 void printer::draw(int, int *, int, const environment *)
111 {
112 }
113
114 void printer::change_color(const environment * const)
115 {
116 }
117
118 void printer::change_fill_color(const environment * const)
119 {
120 }
121
122 void printer::set_ascii_char(unsigned char c, const environment *env, 
123                              int *widthp)
124 {
125   char  buf[2];
126   int   w;
127   font *f;
128
129   buf[0] = c;
130   buf[1] = '\0';
131
132   int i = set_char_and_width(buf, env, &w, &f);
133   set_char(i, f, env, w, 0);
134   if (widthp) {
135     *widthp = w;
136   }
137 }
138
139 void printer::set_special_char(const char *nm, const environment *env,
140                                int *widthp)
141 {
142   font *f;
143   int w;
144   int i = set_char_and_width(nm, env, &w, &f);
145   if (i != -1) {
146     set_char(i, f, env, w, nm);
147     if (widthp)
148       *widthp = w;
149   }
150 }
151
152 int printer::set_char_and_width(const char *nm, const environment *env,
153                                 int *widthp, font **f)
154 {
155   int i = font::name_to_index(nm);
156   int fn = env->fontno;
157   if (fn < 0 || fn >= nfonts) {
158     error("bad font position `%1'", fn);
159     return(-1);
160   }
161   *f = font_table[fn];
162   if (*f == 0) {
163     error("no font mounted at `%1'", fn);
164     return(-1);
165   }
166   if (!(*f)->contains(i)) {
167     if (nm[0] != '\0' && nm[1] == '\0')
168       error("font `%1' does not contain ascii character `%2'",
169             (*f)->get_name(),
170             nm[0]);
171     else
172       error("font `%1' does not contain special character `%2'",
173             (*f)->get_name(),
174             nm);
175     return(-1);
176   }
177   int w = (*f)->get_width(i, env->size);
178   if (widthp)
179     *widthp = w;
180   return( i );
181 }
182
183 void printer::set_numbered_char(int num, const environment *env, int *widthp)
184 {
185   int i = font::number_to_index(num);
186   int fn = env->fontno;
187   if (fn < 0 || fn >= nfonts) {
188     error("bad font position `%1'", fn);
189     return;
190   }
191   font *f = font_table[fn];
192   if (f == 0) {
193     error("no font mounted at `%1'", fn);
194     return;
195   }
196   if (!f->contains(i)) {
197     error("font `%1' does not contain numbered character %2",
198           f->get_name(),
199           num);
200     return;
201   }
202   int w = f->get_width(i, env->size);
203   if (widthp)
204     *widthp = w;
205   set_char(i, f, env, w, 0);
206 }
207
208 font *printer::get_font_from_index(int fontno)
209 {
210   if ((fontno >= 0) && (fontno < nfonts))
211     return(font_table[fontno]);
212   else
213     return(0);
214 }