summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwlemb <wlemb>2004-06-01 10:42:02 +0000
committerwlemb <wlemb>2004-06-01 10:42:02 +0000
commit60bdee578a108f5eb8dce087ae67dcfe6b6bebfb (patch)
treea36ebe89df1c73828e86410f93b9cf2e502db980
parent359b44826cf7a11f99f243e5f10cde9592627568 (diff)
downloadgroff-first.tar.gz
new xtotroff directoryimportfirst
-rw-r--r--src/utils/xtotroff/Makefile.sub8
-rw-r--r--src/utils/xtotroff/xtotroff.c294
2 files changed, 302 insertions, 0 deletions
diff --git a/src/utils/xtotroff/Makefile.sub b/src/utils/xtotroff/Makefile.sub
new file mode 100644
index 00000000..8a2fa5d1
--- /dev/null
+++ b/src/utils/xtotroff/Makefile.sub
@@ -0,0 +1,8 @@
+PROG=xtotroff$(EXEEXT)
+# MAN1=xtotroff.n
+MLIB=$(LIBM)
+XLIBS=$(LIBXUTIL)
+EXTRA_CFLAGS=$(X_CFLAGS)
+EXTRA_LDFLAGS=$(X_LIBS) $(X_PRE_LIBS) -lX11 $(X_EXTRA_LIBS) -lXaw
+OBJS=xtotroff.$(OBJEXT)
+CSRCS=$(srcdir)/xtotroff.c
diff --git a/src/utils/xtotroff/xtotroff.c b/src/utils/xtotroff/xtotroff.c
new file mode 100644
index 00000000..b3d5b02e
--- /dev/null
+++ b/src/utils/xtotroff/xtotroff.c
@@ -0,0 +1,294 @@
+/*
+ * xtotroff
+ *
+ * convert X font metrics into troff font metrics
+ */
+
+#include <X11/Xlib.h>
+#include <stdio.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>
+#endif
+
+#define charWidth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width)
+#define charHeight(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent)
+#define charDepth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent)
+#define charLBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing)
+#define charRBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing)
+
+Display *dpy;
+int groff_flag = 0;
+unsigned resolution = 75;
+unsigned point_size = 10;
+
+int charExists (XFontStruct *fi, int c)
+{
+ XCharStruct *p;
+
+ /* `c' is always >= 0 */
+ if ((unsigned int)c < fi->min_char_or_byte2
+ || (unsigned int)c > fi->max_char_or_byte2)
+ return 0;
+ p = fi->per_char + (c - fi->min_char_or_byte2);
+ return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0
+ || p->ascent != 0 || p->descent != 0 || p->attributes != 0);
+}
+
+/* Canonicalize the font name by replacing scalable parts by *s. */
+
+static int
+CanonicalizeFontName (char *font_name, char *canon_font_name)
+{
+ unsigned int attributes;
+ XFontName parsed;
+
+ if (!XParseFontName(font_name, &parsed, &attributes)) {
+ fprintf (stderr, "not a standard name: %s\n", font_name);
+ return 0;
+ }
+
+ attributes &= ~(FontNamePixelSize|FontNameAverageWidth
+ |FontNamePointSize
+ |FontNameResolutionX|FontNameResolutionY);
+ XFormatFontName(&parsed, attributes, canon_font_name);
+ return 1;
+}
+
+static int
+FontNamesAmbiguous(const char *font_name, char **names, int count)
+{
+ char name1[2048], name2[2048];
+ int i;
+
+ if (count == 1)
+ return 0;
+
+ for (i = 0; i < count; i++) {
+ if (!CanonicalizeFontName(names[i], i == 0 ? name1 : name2)) {
+ 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;
+ }
+
+ }
+ return 0;
+}
+
+static int
+MapFont (char *font_name, const char *troff_name)
+{
+ XFontStruct *fi;
+ int count;
+ char **names;
+ FILE *out;
+ unsigned int c;
+ unsigned int attributes;
+ XFontName parsed;
+ int j, k;
+ DviCharNameMap *char_map;
+ char encoding[256];
+ char *s;
+ int wid;
+ char name_string[2048];
+
+ if (!XParseFontName(font_name, &parsed, &attributes)) {
+ fprintf (stderr, "not a standard name: %s\n", font_name);
+ return 0;
+ }
+
+ attributes &= ~(FontNamePixelSize|FontNameAverageWidth);
+ attributes |= FontNameResolutionX;
+ attributes |= FontNameResolutionY;
+ attributes |= FontNamePointSize;
+ parsed.ResolutionX = resolution;
+ parsed.ResolutionY = resolution;
+ parsed.PointSize = point_size*10;
+ XFormatFontName(&parsed, attributes, name_string);
+
+ names = XListFonts (dpy, name_string, 100000, &count);
+ if (count < 1) {
+ fprintf (stderr, "bad font name: %s\n", font_name);
+ return 0;
+ }
+
+ if (FontNamesAmbiguous(font_name, names, count))
+ return 0;
+
+ XParseFontName(names[0], &parsed, &attributes);
+ sprintf (encoding, "%s-%s", parsed.CharSetRegistry,
+ parsed.CharSetEncoding);
+ for (s = encoding; *s; s++)
+ if (isupper (*s))
+ *s = tolower (*s);
+ char_map = DviFindMap (encoding);
+ if (!char_map) {
+ fprintf (stderr, "not a standard encoding: %s\n", encoding);
+ return 0;
+ }
+
+ fi = XLoadQueryFont (dpy, names[0]);
+ if (!fi) {
+ fprintf (stderr, "font does not exist: %s\n", names[0]);
+ return 0;
+ }
+
+ printf ("%s -> %s\n", names[0], troff_name);
+
+ { /* Avoid race while opening file */
+ int fd;
+ (void) unlink (troff_name);
+ fd = open (troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
+ out = fdopen (fd, "w");
+ }
+
+ if (!out) {
+ perror (troff_name);
+ return 0;
+ }
+ fprintf (out, "name %s\n", troff_name);
+ if (!strcmp (char_map->encoding, "adobe-fontspecific"))
+ fprintf (out, "special\n");
+ if (charExists (fi, ' ')) {
+ int w = charWidth (fi, ' ');
+ if (w > 0)
+ fprintf (out, "spacewidth %d\n", w);
+ }
+ fprintf (out, "charset\n");
+ for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) {
+ const char *name = DviCharName (char_map, c, 0);
+ if (charExists (fi, c) && (groff_flag || name)) {
+
+ wid = charWidth (fi, c);
+
+ fprintf (out, "%s\t%d",
+ name ? name : "---",
+ wid);
+ if (groff_flag) {
+ int param[5];
+ param[0] = charHeight (fi, c);
+ param[1] = charDepth (fi, c);
+ param[2] = 0 /* charRBearing (fi, c) - wid */;
+ param[3] = 0 /* charLBearing (fi, c) */;
+ param[4] = 0; /* XXX */
+ for (j = 0; j < 5; j++)
+ if (param[j] < 0)
+ param[j] = 0;
+ for (j = 4; j >= 0; j--)
+ if (param[j] != 0)
+ break;
+ for (k = 0; k <= j; k++)
+ fprintf (out, ",%d", param[k]);
+ }
+ fprintf (out, "\t0\t0%o\n", c);
+
+ if (name) {
+ for (k = 1; DviCharName(char_map,c,k); k++) {
+ fprintf (out, "%s\t\"\n",
+ DviCharName (char_map,c,k));
+ }
+ }
+ }
+ }
+ XUnloadFont (dpy, fi->fid);
+ fclose (out);
+ return 1;
+}
+
+static void
+usage(const char *prog)
+{
+ fprintf (stderr,
+ "usage: %s [-g] [-r resolution] [-s pointsize] FontMap\n",
+ prog);
+ exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+ char troff_name[1024];
+ char font_name[1024];
+ char line[1024];
+ char *a, *b, c;
+ int position;
+ FILE *map;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "gr:s:")) != EOF) {
+ switch (opt) {
+ case 'g':
+ groff_flag = 1;
+ break;
+ case 'r':
+ sscanf(optarg, "%u", &resolution);
+ break;
+ case 's':
+ sscanf(optarg, "%u", &point_size);
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+ if (argc - optind != 1)
+ usage(argv[0]);
+
+ dpy = XOpenDisplay (0);
+ if (!dpy) {
+ fprintf (stderr, "Can't connect to the X server.\n");
+ fprintf (stderr, "Make sure the DISPLAY environment variable is set correctly.\n");
+ exit (1);
+ }
+ position = 1;
+
+ map = fopen (argv[optind], "r");
+ if (map == NULL) {
+ perror (argv[optind]);
+ exit (1);
+ }
+
+ while (fgets (line, sizeof (line), map)) {
+ for (a=line,b=troff_name; *a; a++,b++) {
+ c = (*b = *a);
+ if (c == ' ' || c == '\t')
+ break;
+ }
+ *b = '\0';
+ while (*a && (*a == ' ' || *a == '\t'))
+ ++a;
+ for (b=font_name; *a; a++,b++)
+ if ((*b = *a) == '\n')
+ break;
+ *b = '\0';
+ if (!MapFont (font_name, troff_name))
+ exit (1);
+ ++position;
+ }
+ exit (0);
+}
+
+/*
+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:
+*/