date and time created 87/02/05 15:19:05 by slatteng
authorDave Slattengren <slatteng@ucbvax.Berkeley.EDU>
Fri, 6 Feb 1987 07:19:05 +0000 (23:19 -0800)
committerDave Slattengren <slatteng@ucbvax.Berkeley.EDU>
Fri, 6 Feb 1987 07:19:05 +0000 (23:19 -0800)
SCCS-vsn: local/ditroff/ditroff.old.okeeffe/driver/x2ch.c 1.1

usr/src/local/ditroff/ditroff.old.okeeffe/driver/x2ch.c [new file with mode: 0644]

diff --git a/usr/src/local/ditroff/ditroff.old.okeeffe/driver/x2ch.c b/usr/src/local/ditroff/ditroff.old.okeeffe/driver/x2ch.c
new file mode 100644 (file)
index 0000000..a26fc52
--- /dev/null
@@ -0,0 +1,237 @@
+/*     x2ch.c  1.1     87/02/05
+ *
+ * Font translation for X font-style fonts to character format.
+ *
+ *     Use:  x2ch  [ -p# ] fontfile  [ character_list ]
+ *
+ *             Reads "fontfile" from current directory (or if not found,
+ *     from BITDIR defined below) and converts it to a character font format
+ *     editable by real people, and convertable BACK to X format by the
+ *     ch2x program.  The -p option specifies the "point size" of the font.
+ *     If no "-p#" is specified, the pointsize is 10.  Output goes to stdout.
+ */
+/* #define DEBUG       /* if defined, statistics are printed to stderr */
+
+#include <stdio.h>
+#include "xfont.h"
+
+
+#define        DIRSIZ  256
+#define BITDIR         "/usr/new/lib/X/font"
+
+
+struct FontData FH;
+#define        first   FH.firstChar
+#define        last    FH.lastChar
+short  bitmapindex[DIRSIZ + 1];/* bit offsets in bitmap */
+short  widths[DIRSIZ + 1];     /* widths calculated from but offsets */
+char   *charbits;              /* pointer to start of bitmap */
+char   **lineptr;              /* pointers to start of each line of bitmap */
+int    pointsize = 10;         /* can only be changed from command line */
+int    tmp;                    /* used for various short-lived things */
+int    *bitcount;              /* place to hold count of bits on a particular
+                                  line in bitmap - used to find the baseline */
+
+char   IName[100];                     /* input file name building place */
+unsigned char  defascii[DIRSIZ];       /* default characters to print */
+unsigned char  *charswanted = defascii;
+
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+       register int i;
+       register int j;
+       int FID;
+
+       if (argc < 2 || argc > 4) {
+    usage:
+               error("usage: %s [ -p# ] filename [ character-list ]", argv[0]);
+       }
+       if (argv[1][0] == '-') {
+               argv++;
+               if (argv[0][1] != 'p')
+                       goto usage;
+               pointsize = atoi(&(argv[0][2]));
+       }
+       for (i = 0; i < DIRSIZ; i++) {
+               bitmapindex[i] = 0;
+               widths[i] = 0;
+               defascii[i] = i;
+       }
+       if (argc == 3)
+               charswanted = (unsigned char *) argv[2];
+
+       /*
+        * find font in BITDIR or current directory, also trying to
+        * tack on the ".onx" extension onto the filename
+        */
+       ++argv;
+       sprintf(IName, "%s/%s.onx", BITDIR, *argv);
+       if ((FID = open(*argv, 0)) < 0) {
+               if ((FID = open(IName, 0)) < 0) {
+                       sprintf(IName, "%s.onx", *argv);
+                       if ((FID = open(IName, 0)) < 0) {
+                               sprintf(IName, "%s/%s", BITDIR, *argv);
+                               if ((FID = open(IName, 0)) < 0)
+                                       error("Can't find %s", *argv);
+                       }
+               }
+       }
+
+       if (read(FID, &FH, sizeof FH) != sizeof FH)
+               error("no header in Font file.");
+       if (first < 0 || last >= DIRSIZ || last <= first)
+               error("font boundaries (%d,%d) out of range", first, last);
+       if (FH.bmWidth <= 0 || FH.bmWidth >= 20000 ||
+                       FH.bmHeight <= 0 || FH.bmHeight >= 20000)
+               error("dimensions (%d,%d) out of range",FH.bmWidth,FH.bmHeight);
+       i = (((FH.bmWidth + 15) >> 3) &~ 1) * FH.bmHeight;
+       charbits = (char *) malloc(i);
+
+#ifdef DEBUG
+       fprintf(stderr,"Bit Map Ptr = %d\nBitMap Width = %d\nBit Map Height = %d\nBitsPerPixel = %d\nFirst Character = %d\nLast Character = %d\nLeft Array = %d\nBaseLine = %d\nSpace Index = %d\nFixed Width = %d\nbit map size = %d\n", FH.bitmapPtr, FH.bmWidth, FH.bmHeight, FH.bitsPerPixel, FH.firstChar, FH.lastChar, FH.leftArray, FH.baseline, FH.spaceIndex, FH.fixedWidth, i);
+#endif
+
+       lseek (FID, (long) FH.bitmapPtr, 0);
+       if (read(FID, charbits, i) != i)
+               error("bit map (%d chars) not in Font file", i);
+
+       if (FH.fixedWidth == 0) {
+               i = (last - first + 2) * sizeof (short);
+#ifdef DEBUG
+               fprintf(stderr, "width array size = %d\n", i);
+#endif
+               lseek (FID, (long) FH.leftArray, 0);
+               if (read(FID, &bitmapindex[first], i) != i)
+                       error("width map not in Font file");
+       } else {
+               for (i = first + 1; i <= last + 1; i++)
+                       bitmapindex[i] = bitmapindex[i - 1] + FH.fixedWidth;
+       }
+       /*
+        * figure out character widths from "leftarray"
+        */
+#ifdef DEBUG
+       fprintf(stderr,"left,widths:\n");
+#endif
+       for (i = first; i <= last; i++) {
+               if ((widths[i] = bitmapindex[i + 1] - bitmapindex[i]) < 0)
+                       error ("inconsistent width table");
+#ifdef DEBUG
+               fprintf(stderr,"%03d:%5d,%6d\n", i, bitmapindex[i], widths[i]);
+#endif
+       }
+       lineptr = (char **) malloc((FH.bmHeight + 2) * sizeof (char *));
+       j = ((FH.bmWidth + 15) >> 3) &~ 1;
+       lineptr[0] = charbits;
+       for (i = 1; i <= FH.bmHeight; i++) {
+               lineptr[i] = lineptr[i - 1] + j;
+       }
+
+       /*
+        * If not given a baseline, try to figure one out by counting the
+        * bits in a given row.  When the number falls suddenly, that's the
+        * baseline.  This is not guaranteed to work.
+        */
+       if (--FH.baseline < 0) {
+               tmp = 0;
+               bitcount = (int *) malloc((FH.bmHeight + 2) * sizeof (int));
+               for (i = 0; i < FH.bmHeight; i++) {
+                       bitcount[i] = 0;
+                       for (j = 0; j < FH.bmWidth; j++) {
+                               if (bitset(lineptr[i], j))
+                                       bitcount[i]++;
+                       }
+                       tmp += bitcount[i];
+#ifdef DEBUG
+                       fprintf(stderr, "bitcount[%d] == %d\n", i, bitcount[i]);
+#endif
+               }
+               tmp /= FH.bmHeight + 1;
+#ifdef DEBUG
+               fprintf(stderr, "average == %d\n", tmp);
+#endif
+               for (i = 1; i < FH.bmHeight; i++) {
+                       if (bitcount[i-1] > tmp && bitcount[i] < (tmp >> 1))
+                               FH.baseline = i - 1;
+               }
+               if (FH.baseline < 0)
+                       FH.baseline = 0;
+       }
+
+       printf("fontheader\ndesiz %d\nmag 1000\n", pointsize);
+       printf("rot 0\ncadv 0\nladv 1\nid 0\nres 75\n");
+
+       for (i = 0; i < DIRSIZ; i++) {
+               j = charswanted[i];
+               if (i > 0 && j == 0)
+                       break;
+               if (widths[j]) {
+                       register int k;
+                       register int l;
+
+                       printf(":%d, width = %d.00\n", j, widths[j]);
+
+                       for (k = 0; k < FH.bmHeight; k++) {
+                           for (l = 0; l < widths[j]; l++) {
+                               if (bitset(lineptr[k], bitmapindex[j]+l)) {
+                                       if (l == 0 && k == FH.baseline)
+                                               putchar('X');
+                                       else
+                                               putchar('@');
+                               } else {
+                                       if (l == 0 && k == FH.baseline)
+                                               putchar('x');
+                                       else
+                                               putchar('.');
+                               }
+                           }
+                           putchar('\n');
+                       }
+
+                       putchar('\n');
+               }
+       }
+       exit(0);
+}
+
+
+/*----------------------------------------------------------------------------*
+ | Routine:    error (format_string, argument1, argument2.... )
+ |
+ | Results:    fprints a message to standard error, then exits with error
+ |             code 1
+ |
+ | Side Efct:  This routine does NOT return
+ *----------------------------------------------------------------------------*/
+
+/*VARARGS1*/
+error(string, a1, a2, a3, a4)
+char *string;
+{ 
+       fprintf(stderr, "x2ch: ");
+       fprintf(stderr, string, a1, a2, a3, a4);
+       fprintf(stderr, "\n");
+       exit(1);
+}
+
+
+/*----------------------------------------------------------------------------*
+ | Routine:    bitset (bitstream pointer, bit number)
+ |
+ | Results:    returns nonzero if a bit is set in a supplied bit stream.
+ |             No range checking is done on anything.  Bit order is least
+ |             significant to most significant.
+ *----------------------------------------------------------------------------*/
+
+bitset(stream, bit)
+char *stream;
+register int bit;
+{
+       register char *p;
+
+       p = stream + (bit >> 3);
+       return ((*p) & (1 << (bit & 7)));
+}