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