printer.cpp revision 114402
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 31font_pointer_list::font_pointer_list(font *f, font_pointer_list *fp) 32: p(f), next(fp) 33{ 34} 35 36printer::printer() 37: font_list(0), font_table(0), nfonts(0) 38{ 39} 40 41printer::~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 54void 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 85font *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 97font *printer::make_font(const char *nm) 98{ 99 return font::load_font(nm); 100} 101 102void printer::end_of_line() 103{ 104} 105 106void printer::special(char *, const environment *, char) 107{ 108} 109 110void printer::draw(int, int *, int, const environment *) 111{ 112} 113 114void printer::change_color(const environment * const) 115{ 116} 117 118void printer::change_fill_color(const environment * const) 119{ 120} 121 122void 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 139void 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 152int 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 183void 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 208font *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} 215