1114402Sru// -*- C++ -*- 2114402Sru/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc. 3114402Sru Written by James Clark (jjc@jclark.com) 4114402Sru 5114402SruThis file is part of groff. 6114402Sru 7114402Srugroff is free software; you can redistribute it and/or modify it under 8114402Sruthe terms of the GNU General Public License as published by the Free 9114402SruSoftware Foundation; either version 2, or (at your option) any later 10114402Sruversion. 11114402Sru 12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY 13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or 14114402SruFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15114402Srufor more details. 16114402Sru 17114402SruYou should have received a copy of the GNU General Public License along 18114402Sruwith groff; see the file COPYING. If not, write to the Free Software 19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */ 20114402Sru 21114402Sru#include "lib.h" 22114402Sru 23114402Sru#include <ctype.h> 24114402Sru#include <assert.h> 25114402Sru#include <stdlib.h> 26114402Sru#include <errno.h> 27114402Sru#include "errarg.h" 28114402Sru#include "error.h" 29114402Sru#include "stringclass.h" 30114402Sru#include "cset.h" 31114402Sru#include "guess.h" 32114402Sru 33114402Sruextern "C" const char *Version_string; 34114402Sru 35114402Srustatic void usage(FILE *stream); 36114402Srustatic void usage(); 37114402Srustatic void version(); 38114402Srustatic void convert_font(const font_params &, FILE *, FILE *); 39114402Sru 40114402Srutypedef int font_params::*param_t; 41114402Sru 42114402Srustatic struct { 43114402Sru const char *name; 44114402Sru param_t par; 45114402Sru} param_table[] = { 46114402Sru { "x-height", &font_params::x_height }, 47114402Sru { "fig-height", &font_params::fig_height }, 48114402Sru { "asc-height", &font_params::asc_height }, 49114402Sru { "body-height", &font_params::body_height }, 50114402Sru { "cap-height", &font_params::cap_height }, 51114402Sru { "comma-depth", &font_params::comma_depth }, 52114402Sru { "desc-depth", &font_params::desc_depth }, 53114402Sru { "body-depth", &font_params::body_depth }, 54114402Sru}; 55114402Sru 56114402Sru// These are all in thousandths of an em. 57114402Sru// These values are correct for PostScript Times Roman. 58114402Sru 59114402Sru#define DEFAULT_X_HEIGHT 448 60114402Sru#define DEFAULT_FIG_HEIGHT 676 61114402Sru#define DEFAULT_ASC_HEIGHT 682 62114402Sru#define DEFAULT_BODY_HEIGHT 676 63114402Sru#define DEFAULT_CAP_HEIGHT 662 64114402Sru#define DEFAULT_COMMA_DEPTH 143 65114402Sru#define DEFAULT_DESC_DEPTH 217 66114402Sru#define DEFAULT_BODY_DEPTH 177 67114402Sru 68114402Sruint main(int argc, char **argv) 69114402Sru{ 70114402Sru program_name = argv[0]; 71114402Sru int i; 72114402Sru for (i = 1; i < argc; i++) { 73114402Sru if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version")) 74114402Sru version(); 75114402Sru if (!strcmp(argv[i],"--help")) { 76114402Sru usage(stdout); 77114402Sru exit(0); 78114402Sru } 79114402Sru } 80114402Sru if (argc < 4) 81114402Sru usage(); 82114402Sru int resolution; 83114402Sru if (sscanf(argv[argc-3], "%d", &resolution) != 1) 84114402Sru usage(); 85114402Sru if (resolution <= 0) 86114402Sru fatal("resolution must be > 0"); 87114402Sru int unitwidth; 88114402Sru if (sscanf(argv[argc-2], "%d", &unitwidth) != 1) 89114402Sru usage(); 90114402Sru if (unitwidth <= 0) 91114402Sru fatal("unitwidth must be > 0"); 92114402Sru font_params param; 93114402Sru const char *font = argv[argc-1]; 94114402Sru param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I'); 95114402Sru param.em = (resolution*unitwidth)/72; 96114402Sru param.x_height = DEFAULT_X_HEIGHT; 97114402Sru param.fig_height = DEFAULT_FIG_HEIGHT; 98114402Sru param.asc_height = DEFAULT_ASC_HEIGHT; 99114402Sru param.body_height = DEFAULT_BODY_HEIGHT; 100114402Sru param.cap_height = DEFAULT_CAP_HEIGHT; 101114402Sru param.comma_depth = DEFAULT_COMMA_DEPTH; 102114402Sru param.desc_depth = DEFAULT_DESC_DEPTH; 103114402Sru param.body_depth = DEFAULT_BODY_DEPTH; 104114402Sru for (i = 1; i < argc && argv[i][0] == '-'; i++) { 105114402Sru if (argv[i][1] == '-' && argv[i][2] == '\0') { 106114402Sru i++; 107114402Sru break; 108114402Sru } 109114402Sru if (i + 1 >= argc) 110114402Sru usage(); 111114402Sru size_t j; 112114402Sru for (j = 0;; j++) { 113114402Sru if (j >= sizeof(param_table)/sizeof(param_table[0])) 114114402Sru fatal("parameter `%1' not recognized", argv[i] + 1); 115114402Sru if (strcmp(param_table[j].name, argv[i] + 1) == 0) 116114402Sru break; 117114402Sru } 118114402Sru if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1) 119114402Sru fatal("invalid argument `%1'", argv[i+1]); 120114402Sru i++; 121114402Sru } 122114402Sru if (argc - i != 3) 123114402Sru usage(); 124114402Sru errno = 0; 125114402Sru FILE *infp = fopen(font, "r"); 126114402Sru if (infp == 0) 127114402Sru fatal("can't open `%1': %2", font, strerror(errno)); 128114402Sru convert_font(param, infp, stdout); 129114402Sru return 0; 130114402Sru} 131114402Sru 132114402Srustatic void usage(FILE *stream) 133114402Sru{ 134114402Sru fprintf(stream, "usage: %s [-v] [-param value] ... " 135114402Sru "resolution unitwidth font\n", 136114402Sru program_name); 137114402Sru} 138114402Srustatic void usage() 139114402Sru{ 140114402Sru usage(stderr); 141114402Sru exit(1); 142114402Sru} 143114402Sru 144114402Srustatic void version() 145114402Sru{ 146114402Sru printf("GNU addftinfo (groff) version %s\n", Version_string); 147114402Sru exit(0); 148114402Sru} 149114402Sru 150114402Srustatic int get_line(FILE *fp, string *p) 151114402Sru{ 152114402Sru int c; 153114402Sru p->clear(); 154114402Sru while ((c = getc(fp)) != EOF) { 155114402Sru *p += char(c); 156114402Sru if (c == '\n') 157114402Sru break; 158114402Sru } 159114402Sru return p->length() > 0; 160114402Sru} 161114402Sru 162114402Srustatic void convert_font(const font_params ¶m, FILE *infp, FILE *outfp) 163114402Sru{ 164114402Sru string s; 165114402Sru while (get_line(infp, &s)) { 166114402Sru put_string(s, outfp); 167114402Sru if (s.length() >= 8 168114402Sru && strncmp(&s[0], "charset", 7)) 169114402Sru break; 170114402Sru } 171114402Sru while (get_line(infp, &s)) { 172114402Sru s += '\0'; 173114402Sru string name; 174114402Sru const char *p = s.contents(); 175114402Sru while (csspace(*p)) 176114402Sru p++; 177114402Sru while (*p != '\0' && !csspace(*p)) 178114402Sru name += *p++; 179114402Sru while (csspace(*p)) 180114402Sru p++; 181114402Sru for (const char *q = s.contents(); q < p; q++) 182114402Sru putc(*q, outfp); 183114402Sru char *next; 184114402Sru char_metric metric; 185114402Sru metric.width = (int)strtol(p, &next, 10); 186114402Sru if (next != p) { 187114402Sru printf("%d", metric.width); 188114402Sru p = next; 189114402Sru metric.type = (int)strtol(p, &next, 10); 190114402Sru if (next != p) { 191114402Sru name += '\0'; 192114402Sru guess(name.contents(), param, &metric); 193114402Sru if (metric.sk == 0) { 194114402Sru if (metric.left_ic == 0) { 195114402Sru if (metric.ic == 0) { 196114402Sru if (metric.depth == 0) { 197114402Sru if (metric.height != 0) 198114402Sru printf(",%d", metric.height); 199114402Sru } 200114402Sru else 201114402Sru printf(",%d,%d", metric.height, metric.depth); 202114402Sru } 203114402Sru else 204114402Sru printf(",%d,%d,%d", metric.height, metric.depth, metric.ic); 205114402Sru } 206114402Sru else 207114402Sru printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic, 208114402Sru metric.left_ic); 209114402Sru } 210114402Sru else 211114402Sru printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic, 212114402Sru metric.left_ic, metric.sk); 213114402Sru } 214114402Sru } 215114402Sru fputs(p, outfp); 216114402Sru } 217114402Sru} 218114402Sru 219