home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / gnu / groff-1.09-src.lha / src / amiga / groff-1.09 / addftinfo / addftinfo.cc next >
C/C++ Source or Header  |  1994-02-21  |  5KB  |  195 lines

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