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 / xditview / xtotroff.c < prev   
C/C++ Source or Header  |  1991-10-09  |  7KB  |  304 lines

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