/[groff]/groff/src/utils/xtotroff/xtotroff.c
ViewVC logotype

Diff of /groff/src/utils/xtotroff/xtotroff.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by wlemb, Tue Jun 1 10:42:02 2004 UTC revision 1.2 by wl, Thu Nov 25 08:08:33 2004 UTC
# Line 4  Line 4 
4   * convert X font metrics into troff font metrics   * convert X font metrics into troff font metrics
5   */   */
6    
7  #include        <X11/Xlib.h>  #ifdef HAVE_CONFIG_H
8  #include        <stdio.h>  #include <config.h>
 #include        <ctype.h>  
 #include        <unistd.h>  
 #include        <stdlib.h>  
 #include        <getopt.h>  
 #include        <string.h>  
 #include        <fcntl.h>  
 #include        "XFontName.h"  
 #include        "DviChar.h"  
   
 #ifdef X_NOT_STDC_ENV  
 char *malloc();  
 #else  
 #include <stdlib.h>  
9  #endif  #endif
10    
11  #define charWidth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width)  #include <X11/Xlib.h>
12  #define charHeight(fi,c)        ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent)  #include <stdio.h>
13  #define charDepth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent)  #include <ctype.h>
14  #define charLBearing(fi,c)      ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing)  #include <unistd.h>
15  #define charRBearing(fi,c)      ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing)  #include <stdlib.h>
16    #include <getopt.h>
17  Display         *dpy;  #include <string.h>
18  int             groff_flag = 0;  #include <fcntl.h>
19  unsigned        resolution = 75;  #include <limits.h>
20  unsigned        point_size = 10;  #include "XFontName.h"
21    #include "DviChar.h"
22    
23    #define charWidth(fi,c) \
24              ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width)
25    #define charHeight(fi,c) \
26              ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent)
27    #define charDepth(fi,c) \
28              ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent)
29    #define charLBearing(fi,c) \
30              ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing)
31    #define charRBearing(fi,c) \
32              ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing)
33    
34    extern const char *Version_string;
35    static char *program_name;
36    
37    Display *dpy;
38    unsigned resolution = 75;
39    unsigned point_size = 10;
40    
41  int charExists (XFontStruct *fi, int c)  int charExists(XFontStruct * fi, int c)
42  {  {
43          XCharStruct *p;    XCharStruct *p;
44    
45          /* `c' is always >= 0 */    /* `c' is always >= 0 */
46          if ((unsigned int)c < fi->min_char_or_byte2    if ((unsigned int) c < fi->min_char_or_byte2
47              || (unsigned int)c > fi->max_char_or_byte2)        || (unsigned int) c > fi->max_char_or_byte2)
48                  return 0;      return 0;
49          p = fi->per_char + (c - fi->min_char_or_byte2);    p = fi->per_char + (c - fi->min_char_or_byte2);
50          return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0    return p->lbearing != 0 || p->rbearing != 0 || p->width != 0
51                  || p->ascent != 0 || p->descent != 0 || p->attributes != 0);           || p->ascent != 0 || p->descent != 0 || p->attributes != 0;
52  }  }
53    
54  /* Canonicalize the font name by replacing scalable parts by *s. */  /* Canonicalize the font name by replacing scalable parts by *s. */
55    
56  static int  static int CanonicalizeFontName(char *font_name, char *canon_font_name)
 CanonicalizeFontName (char *font_name, char *canon_font_name)  
57  {  {
58          unsigned int    attributes;    unsigned int attributes;
59          XFontName       parsed;    XFontName parsed;
   
         if (!XParseFontName(font_name, &parsed, &attributes)) {  
                 fprintf (stderr, "not a standard name: %s\n", font_name);  
                 return 0;  
         }  
60    
61          attributes &= ~(FontNamePixelSize|FontNameAverageWidth    if (!XParseFontName(font_name, &parsed, &attributes)) {
62                          |FontNamePointSize      fprintf(stderr, "not a standard name: %s\n", font_name);
63                          |FontNameResolutionX|FontNameResolutionY);      return 0;
64          XFormatFontName(&parsed, attributes, canon_font_name);    }
65          return 1;  
66      attributes &= ~(FontNamePixelSize | FontNameAverageWidth
67                      | FontNamePointSize
68                      | FontNameResolutionX | FontNameResolutionY);
69      XFormatFontName(&parsed, attributes, canon_font_name);
70      return 1;
71  }  }
72    
73  static int  static int
74  FontNamesAmbiguous(const char *font_name, char **names, int count)  FontNamesAmbiguous(const char *font_name, char **names, int count)
75  {  {
76          char name1[2048], name2[2048];    char name1[2048], name2[2048];
77          int i;    int i;
   
         if (count == 1)  
                 return 0;  
78    
79          for (i = 0; i < count; i++) {    if (count == 1)
80                  if (!CanonicalizeFontName(names[i], i == 0 ? name1 : name2)) {      return 0;
                         fprintf(stderr, "bad font name: %s\n", names[i]);  
                         return 1;  
                 }  
                 if (i > 0 && strcmp(name1, name2) != 0) {  
                         fprintf(stderr, "ambiguous font name: %s\n", font_name);  
                         fprintf(stderr, "  matches %s\n", names[0]);  
                         fprintf(stderr, "  and %s\n", names[i]);  
                         return 1;  
                 }  
81    
82          }    for (i = 0; i < count; i++) {
83          return 0;      if (!CanonicalizeFontName(names[i], i == 0 ? name1 : name2)) {
84          fprintf(stderr, "bad font name: %s\n", names[i]);
85          return 1;
86        }
87        if (i > 0 && strcmp(name1, name2) != 0) {
88          fprintf(stderr, "ambiguous font name: %s\n", font_name);
89          fprintf(stderr, "  matches %s\n", names[0]);
90          fprintf(stderr, "  and %s\n", names[i]);
91          return 1;
92        }
93      }
94      return 0;
95  }  }
96    
97  static int  static int MapFont(char *font_name, const char *troff_name)
 MapFont (char *font_name, const char *troff_name)  
98  {  {
99          XFontStruct     *fi;    XFontStruct *fi;
100          int             count;    int count;
101          char            **names;    char **names;
102          FILE            *out;    FILE *out;
103          unsigned int    c;    unsigned int c;
104          unsigned int    attributes;    unsigned int attributes;
105          XFontName       parsed;    XFontName parsed;
106          int             j, k;    int j, k;
107          DviCharNameMap  *char_map;    DviCharNameMap *char_map;
108          char            encoding[256];    char encoding[256];
109          char            *s;    char *s;
110          int             wid;    int wid;
111          char            name_string[2048];    char name_string[2048];
112    
113          if (!XParseFontName(font_name, &parsed, &attributes)) {    if (!XParseFontName(font_name, &parsed, &attributes)) {
114                  fprintf (stderr, "not a standard name: %s\n", font_name);      fprintf(stderr, "not a standard name: %s\n", font_name);
115                  return 0;      return 0;
116          }    }
117    
118          attributes &= ~(FontNamePixelSize|FontNameAverageWidth);    attributes &= ~(FontNamePixelSize | FontNameAverageWidth);
119          attributes |= FontNameResolutionX;    attributes |= FontNameResolutionX;
120          attributes |= FontNameResolutionY;    attributes |= FontNameResolutionY;
121          attributes |= FontNamePointSize;    attributes |= FontNamePointSize;
122          parsed.ResolutionX = resolution;    parsed.ResolutionX = resolution;
123          parsed.ResolutionY = resolution;    parsed.ResolutionY = resolution;
124          parsed.PointSize = point_size*10;    parsed.PointSize = point_size * 10;
125          XFormatFontName(&parsed, attributes, name_string);    XFormatFontName(&parsed, attributes, name_string);
126    
127          names = XListFonts (dpy, name_string, 100000, &count);    names = XListFonts(dpy, name_string, 100000, &count);
128          if (count < 1) {    if (count < 1) {
129                  fprintf (stderr, "bad font name: %s\n", font_name);      fprintf(stderr, "bad font name: %s\n", font_name);
130                  return 0;      return 0;
131          }    }
132    
133          if (FontNamesAmbiguous(font_name, names, count))    if (FontNamesAmbiguous(font_name, names, count))
134                  return 0;      return 0;
135    
136          XParseFontName(names[0], &parsed, &attributes);    XParseFontName(names[0], &parsed, &attributes);
137          sprintf (encoding, "%s-%s", parsed.CharSetRegistry,    sprintf(encoding, "%s-%s", parsed.CharSetRegistry,
138                                      parsed.CharSetEncoding);            parsed.CharSetEncoding);
139          for (s = encoding; *s; s++)    for (s = encoding; *s; s++)
140                  if (isupper (*s))      if (isupper(*s))
141                          *s = tolower (*s);        *s = tolower(*s);
142          char_map = DviFindMap (encoding);    char_map = DviFindMap(encoding);
143          if (!char_map) {    if (!char_map) {
144                  fprintf (stderr, "not a standard encoding: %s\n", encoding);      fprintf(stderr, "not a standard encoding: %s\n", encoding);
145                  return 0;      return 0;
146          }    }
147    
148          fi = XLoadQueryFont (dpy, names[0]);    fi = XLoadQueryFont(dpy, names[0]);
149          if (!fi) {    if (!fi) {
150                  fprintf (stderr, "font does not exist: %s\n", names[0]);      fprintf(stderr, "font does not exist: %s\n", names[0]);
151                  return 0;      return 0;
152          }    }
153                    
154          printf ("%s -> %s\n", names[0], troff_name);    printf("%s -> %s\n", names[0], troff_name);
155    
156          { /* Avoid race while opening file */    {                             /* Avoid race while opening file */
157                  int fd;      int fd;
158                  (void) unlink (troff_name);      (void) unlink(troff_name);
159                  fd = open (troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);      fd = open(troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
160                  out = fdopen (fd, "w");      out = fdopen(fd, "w");
161          }    }
162    
163          if (!out) {    if (!out) {
164                  perror (troff_name);      perror(troff_name);
165                  return 0;      return 0;
166          }    }
167          fprintf (out, "name %s\n", troff_name);    fprintf(out, "name %s\n", troff_name);
168          if (!strcmp (char_map->encoding, "adobe-fontspecific"))    if (!strcmp(char_map->encoding, "adobe-fontspecific"))
169                  fprintf (out, "special\n");      fprintf(out, "special\n");
170          if (charExists (fi, ' ')) {    if (charExists(fi, ' ')) {
171                  int w = charWidth (fi, ' ');      int w = charWidth(fi, ' ');
172                  if (w > 0)      if (w > 0)
173                          fprintf (out, "spacewidth %d\n", w);        fprintf(out, "spacewidth %d\n", w);
174          }    }
175          fprintf (out, "charset\n");    fprintf(out, "charset\n");
176          for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) {    for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) {
177                  const char *name = DviCharName (char_map, c, 0);      const char *name = DviCharName(char_map, c, 0);
178                  if (charExists (fi, c) && (groff_flag || name)) {      if (charExists(fi, c)) {
179          wid = charWidth(fi, c);
180                          wid = charWidth (fi, c);  
181          fprintf(out, "%s\t%d", name ? name : "---", wid);
182                          fprintf (out, "%s\t%d",        int param[5];
183                                          name ? name : "---",        param[0] = charHeight(fi, c);
184                                          wid);        param[1] = charDepth(fi, c);
185                          if (groff_flag) {        param[2] = 0;             /* charRBearing (fi, c) - wid */
186                                  int     param[5];        param[3] = 0;             /* charLBearing (fi, c) */
187                                  param[0] = charHeight (fi, c);        param[4] = 0;             /* XXX */
188                                  param[1] = charDepth (fi, c);        for (j = 0; j < 5; j++)
189                                  param[2] = 0 /* charRBearing (fi, c) - wid */;          if (param[j] < 0)
190                                  param[3] = 0 /* charLBearing (fi, c) */;            param[j] = 0;
191                                  param[4] = 0; /* XXX */        for (j = 4; j >= 0; j--)
192                                  for (j = 0; j < 5; j++)          if (param[j] != 0)
193                                          if (param[j] < 0)            break;
194                                                  param[j] = 0;        for (k = 0; k <= j; k++)
195                                  for (j = 4; j >= 0; j--)          fprintf(out, ",%d", param[k]);
196                                          if (param[j] != 0)        fprintf(out, "\t0\t0%o\n", c);
197                                                  break;  
198                                  for (k = 0; k <= j; k++)        if (name) {
199                                          fprintf (out, ",%d", param[k]);          for (k = 1; DviCharName(char_map, c, k); k++) {
200                          }            fprintf(out, "%s\t\"\n", DviCharName(char_map, c, k));
201                          fprintf (out, "\t0\t0%o\n", c);          }
202                                  }
203                          if (name) {      }
204                                  for (k = 1; DviCharName(char_map,c,k); k++) {    }
205                                          fprintf (out, "%s\t\"\n",    XUnloadFont(dpy, fi->fid);
206                                                   DviCharName (char_map,c,k));    fclose(out);
207                                  }    return 1;
                         }  
                 }  
         }  
         XUnloadFont (dpy, fi->fid);  
         fclose (out);  
         return 1;  
208  }  }
209    
210  static void  static void usage(FILE *stream)
 usage(const char *prog)  
211  {  {
212          fprintf (stderr,    fprintf(stream,
213                   "usage: %s [-g] [-r resolution] [-s pointsize] FontMap\n",            "usage: %s [-r resolution] [-s pointsize] FontMap\n",
214                   prog);            program_name);
         exit (1);  
215  }  }
216    
217  int  int main(int argc, char **argv)
 main (int argc, char **argv)  
218  {  {
219          char    troff_name[1024];    char troff_name[1024];
220          char    font_name[1024];    char font_name[1024];
221          char    line[1024];    char line[1024];
222          char    *a, *b, c;    char *a, *b, c;
223          int     position;    FILE *map;
224          FILE    *map;    int opt;
225          int     opt;    static const struct option long_options[] = {
226        { "help", no_argument, 0, CHAR_MAX + 1 },
227          while ((opt = getopt(argc, argv, "gr:s:")) != EOF) {      { "version", no_argument, 0, 'v' },
228                  switch (opt) {      { NULL, 0, 0, 0 }
229                  case 'g':    };
230                          groff_flag = 1;  
231                          break;    program_name = argv[0];
232                  case 'r':  
233                          sscanf(optarg, "%u", &resolution);    while ((opt = getopt_long(argc, argv, "gr:s:v", long_options,
234                          break;                              NULL)) != EOF) {
235                  case 's':      switch (opt) {
236                          sscanf(optarg, "%u", &point_size);      case 'g':
237                          break;        /* unused; just for compatibility */
238                  default:        break;
239                          usage(argv[0]);      case 'r':
240                  }        sscanf(optarg, "%u", &resolution);
241          }        break;
242          if (argc - optind != 1)      case 's':
243                  usage(argv[0]);        sscanf(optarg, "%u", &point_size);
244          break;
245          dpy = XOpenDisplay (0);      case 'v':
246          if (!dpy) {        printf("xtotroff (groff) version %s\n", Version_string);
247                  fprintf (stderr, "Can't connect to the X server.\n");        exit(0);
248                  fprintf (stderr, "Make sure the DISPLAY environment variable is set correctly.\n");        break;
249                  exit (1);      case CHAR_MAX + 1: /* --help */
250          }        usage(stdout);
251          position = 1;        exit(0);
252          break;
253          map = fopen (argv[optind], "r");      case '?':
254          if (map == NULL) {        usage(stderr);
255                  perror (argv[optind]);        exit(1);
256                  exit (1);        break;
257          }      }
258      }
259          while (fgets (line, sizeof (line), map)) {    if (argc - optind != 1) {
260                  for (a=line,b=troff_name; *a; a++,b++) {      usage(stderr);
261                          c = (*b = *a);      exit(1);
262                          if (c == ' ' || c == '\t')    }
263                                  break;  
264                  }    dpy = XOpenDisplay(0);
265                  *b = '\0';    if (!dpy) {
266                  while (*a && (*a == ' ' || *a == '\t'))      fprintf(stderr, "Can't connect to the X server.\n");
267                          ++a;      fprintf(stderr,
268                  for (b=font_name; *a; a++,b++)              "Make sure the DISPLAY environment variable is set correctly.\n");
269                          if ((*b = *a) == '\n')      exit(1);
270                                  break;    }
271                  *b = '\0';  
272                  if (!MapFont (font_name, troff_name))    map = fopen(argv[optind], "r");
273                          exit (1);    if (map == NULL) {
274                  ++position;      perror(argv[optind]);
275          }      exit(1);
276          exit (0);    }
277    
278      while (fgets(line, sizeof(line), map)) {
279        for (a = line, b = troff_name; *a; a++, b++) {
280          c = (*b = *a);
281          if (c == ' ' || c == '\t')
282            break;
283        }
284        *b = '\0';
285        while (*a && (*a == ' ' || *a == '\t'))
286          ++a;
287        for (b = font_name; *a; a++, b++)
288          if ((*b = *a) == '\n')
289            break;
290        *b = '\0';
291        if (!MapFont(font_name, troff_name))
292          exit(1);
293      }
294      exit(0);
295  }  }
   
 /*  
 Local Variables:  
 c-indent-level: 8  
 c-continued-statement-offset: 8  
 c-brace-offset: -8  
 c-argdecl-indent: 8  
 c-label-offset: -8  
 c-tab-always-indent: nil  
 End:  
 */  

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26