/contrib/groff/src/utils/addftinfo/addftinfo.cpp

https://bitbucket.org/freebsd/freebsd-head/ · C++ · 218 lines · 183 code · 14 blank · 21 comment · 60 complexity · 9dae4401307d9cfcce6faaf7cde39057 MD5 · raw file

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