1// -*- C++ -*- 2/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc. 3 Written by James Clark (jjc@jclark.com) 4 5This file is part of groff. 6 7groff is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 2, or (at your option) any later 10version. 11 12groff is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License along 18with groff; see the file COPYING. If not, write to the Free Software 19Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21#include "lib.h" 22 23#include <ctype.h> 24#include <assert.h> 25#include <stdlib.h> 26#include <errno.h> 27#include "errarg.h" 28#include "error.h" 29#include "stringclass.h" 30#include "cset.h" 31#include "guess.h" 32 33extern "C" const char *Version_string; 34 35static void usage(FILE *stream); 36static void usage(); 37static void version(); 38static void convert_font(const font_params &, FILE *, FILE *); 39 40typedef int font_params::*param_t; 41 42static struct { 43 const char *name; 44 param_t par; 45} param_table[] = { 46 { "x-height", &font_params::x_height }, 47 { "fig-height", &font_params::fig_height }, 48 { "asc-height", &font_params::asc_height }, 49 { "body-height", &font_params::body_height }, 50 { "cap-height", &font_params::cap_height }, 51 { "comma-depth", &font_params::comma_depth }, 52 { "desc-depth", &font_params::desc_depth }, 53 { "body-depth", &font_params::body_depth }, 54}; 55 56// These are all in thousandths of an em. 57// These values are correct for PostScript Times Roman. 58 59#define DEFAULT_X_HEIGHT 448 60#define DEFAULT_FIG_HEIGHT 676 61#define DEFAULT_ASC_HEIGHT 682 62#define DEFAULT_BODY_HEIGHT 676 63#define DEFAULT_CAP_HEIGHT 662 64#define DEFAULT_COMMA_DEPTH 143 65#define DEFAULT_DESC_DEPTH 217 66#define DEFAULT_BODY_DEPTH 177 67 68int main(int argc, char **argv) 69{ 70 program_name = argv[0]; 71 int i; 72 for (i = 1; i < argc; i++) { 73 if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version")) 74 version(); 75 if (!strcmp(argv[i],"--help")) { 76 usage(stdout); 77 exit(0); 78 } 79 } 80 if (argc < 4) 81 usage(); 82 int resolution; 83 if (sscanf(argv[argc-3], "%d", &resolution) != 1) 84 usage(); 85 if (resolution <= 0) 86 fatal("resolution must be > 0"); 87 int unitwidth; 88 if (sscanf(argv[argc-2], "%d", &unitwidth) != 1) 89 usage(); 90 if (unitwidth <= 0) 91 fatal("unitwidth must be > 0"); 92 font_params param; 93 const char *font = argv[argc-1]; 94 param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I'); 95 param.em = (resolution*unitwidth)/72; 96 param.x_height = DEFAULT_X_HEIGHT; 97 param.fig_height = DEFAULT_FIG_HEIGHT; 98 param.asc_height = DEFAULT_ASC_HEIGHT; 99 param.body_height = DEFAULT_BODY_HEIGHT; 100 param.cap_height = DEFAULT_CAP_HEIGHT; 101 param.comma_depth = DEFAULT_COMMA_DEPTH; 102 param.desc_depth = DEFAULT_DESC_DEPTH; 103 param.body_depth = DEFAULT_BODY_DEPTH; 104 for (i = 1; i < argc && argv[i][0] == '-'; i++) { 105 if (argv[i][1] == '-' && argv[i][2] == '\0') { 106 i++; 107 break; 108 } 109 if (i + 1 >= argc) 110 usage(); 111 size_t j; 112 for (j = 0;; j++) { 113 if (j >= sizeof(param_table)/sizeof(param_table[0])) 114 fatal("parameter `%1' not recognized", argv[i] + 1); 115 if (strcmp(param_table[j].name, argv[i] + 1) == 0) 116 break; 117 } 118 if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1) 119 fatal("invalid argument `%1'", argv[i+1]); 120 i++; 121 } 122 if (argc - i != 3) 123 usage(); 124 errno = 0; 125 FILE *infp = fopen(font, "r"); 126 if (infp == 0) 127 fatal("can't open `%1': %2", font, strerror(errno)); 128 convert_font(param, infp, stdout); 129 return 0; 130} 131 132static void usage(FILE *stream) 133{ 134 fprintf(stream, "usage: %s [-v] [-param value] ... " 135 "resolution unitwidth font\n", 136 program_name); 137} 138static void usage() 139{ 140 usage(stderr); 141 exit(1); 142} 143 144static void version() 145{ 146 printf("GNU addftinfo (groff) version %s\n", Version_string); 147 exit(0); 148} 149 150static int get_line(FILE *fp, string *p) 151{ 152 int c; 153 p->clear(); 154 while ((c = getc(fp)) != EOF) { 155 *p += char(c); 156 if (c == '\n') 157 break; 158 } 159 return p->length() > 0; 160} 161 162static void convert_font(const font_params ¶m, FILE *infp, FILE *outfp) 163{ 164 string s; 165 while (get_line(infp, &s)) { 166 put_string(s, outfp); 167 if (s.length() >= 8 168 && strncmp(&s[0], "charset", 7)) 169 break; 170 } 171 while (get_line(infp, &s)) { 172 s += '\0'; 173 string name; 174 const char *p = s.contents(); 175 while (csspace(*p)) 176 p++; 177 while (*p != '\0' && !csspace(*p)) 178 name += *p++; 179 while (csspace(*p)) 180 p++; 181 for (const char *q = s.contents(); q < p; q++) 182 putc(*q, outfp); 183 char *next; 184 char_metric metric; 185 metric.width = (int)strtol(p, &next, 10); 186 if (next != p) { 187 printf("%d", metric.width); 188 p = next; 189 metric.type = (int)strtol(p, &next, 10); 190 if (next != p) { 191 name += '\0'; 192 guess(name.contents(), param, &metric); 193 if (metric.sk == 0) { 194 if (metric.left_ic == 0) { 195 if (metric.ic == 0) { 196 if (metric.depth == 0) { 197 if (metric.height != 0) 198 printf(",%d", metric.height); 199 } 200 else 201 printf(",%d,%d", metric.height, metric.depth); 202 } 203 else 204 printf(",%d,%d,%d", metric.height, metric.depth, metric.ic); 205 } 206 else 207 printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic, 208 metric.left_ic); 209 } 210 else 211 printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic, 212 metric.left_ic, metric.sk); 213 } 214 } 215 fputs(p, outfp); 216 } 217} 218 219