diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/hershey/xhershey.c |
Initial commit
Diffstat (limited to 'fonts/hershey/xhershey.c')
-rw-r--r-- | fonts/hershey/xhershey.c | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/fonts/hershey/xhershey.c b/fonts/hershey/xhershey.c new file mode 100644 index 0000000000..9a5f655f81 --- /dev/null +++ b/fonts/hershey/xhershey.c @@ -0,0 +1,378 @@ +#include <stdio.h> + +#ifndef NO_X_WINDOW +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#endif NO_X_WINDOW + +#include "font.h" +#include "parse.h" + +#define MAXPIXEL 25 +#define NORMALVOFF 9 /* Normal baseline for Hershey fonts */ +#define CTOI(c) ((c)-'R') + +static char copyright[] = "Copyright (C) Ken Yap 1988"; + +static char *progname; +static char mfcode = 1; /* generate METAFONT code */ +static char xwin = 1; /* plot in X window */ +static char nums = 0; /* 0: none , 1: end points, 2: all */ +static char *fontlib = "occidental"; +static int mag = 2; +static int xorg, yorg; +#ifndef NO_X_WINDOW +Display *d; +Window w; +XSetWindowAttributes xswa; +Visual visual; +GC gc; +XGCValues xgcv; +#endif NO_X_WINDOW + +main(argc, argv) + int argc; + char *argv[]; +{ + register int i; + extern int optind; + extern char *optarg; + char *rindex(); + + if ((progname = rindex(argv[0], '/')) != NULL) + ++progname; + else + progname = argv[0]; + + while ((i = getopt(argc, argv, "f:m:n:MX")) != EOF) + switch (i) + { + case 'f': /* different Hershey database */ + fontlib = optarg; + break; + case 'm': /* magnification in window */ + mag = atoi(optarg); + if (mag <= 0 || mag > 10) + mag = 2; + break; + case 'n': /* put numbers on points */ + nums = atoi(optarg); + if (nums <= 0 || nums > 2) + nums = 0; + break; + case 'M': /* no METAFONT code */ + mfcode = 0; + break; + case 'X': /* no X window */ + xwin = 0; + break; + default: + usage(); + break; + } + + argc -= optind; + argv += optind; + if (argc > 0) + { + if (freopen(argv[0], "r", stdin) == NULL) + { + perror(argv[0]); + exit(1); + } + } + + xhershey(fontlib); + exit(0); +} + +static usage() +{ + (void)fprintf(stderr, "Usage: xhershey [-f fontlib] [-m mag] [-n annotelevel] [-M] [-X]\n"); + exit(1); +} + +static xhershey(fontfilename) + char *fontfilename; +/* +** Main loop, get user input, plot char, output code +*/ +{ + register FILE *fontfile; + char line[512]; + int parsespecs(); + Window makewindow(); + + if ((fontfile = fopen(fontfilename, "r")) == NULL) + { + perror(fontfilename); + return; + } +#ifndef NO_X_WINDOW + if (xwin) + { + if ((w = makewindow(progname)) == (Window)0) + { + fprintf(stderr, "Can't make X11 window\n"); + exit(1); + } + } +#endif + scanfont(fontfile); + (void)fprintf(stderr, "Font file ready...\n"); + while (fgets(line, sizeof(line), stdin) != NULL) + { + if (parsespecs(line)) + { + if (getline(fontfile, perchar.hersheyindex, line, sizeof(line))) + { +#ifdef PRINTDATA /* see raw data */ + fputs(line, stderr); +#endif PRINTDATA + if (mfcode) + genchar(line); +#ifndef NO_X_WINDOW + if (xwin) + displaychar(line); +#endif NO_X_WINDOW + } + else + (void)fprintf(stderr, "Char %d not in font\n", + perchar.hersheyindex); + } + } + (void)fclose(fontfile); +} + +#ifndef NO_X_WINDOW +Window makewindow(title) + char *title; +{ + Window w; + register int width, height; + XEvent event; + + xorg = MAXPIXEL * mag; + yorg = MAXPIXEL * mag; + width = xorg * 2; + height = yorg * 2; + + if (!(d = XOpenDisplay((char *)0))) + return ((Window)0); + + xswa.event_mask = ExposureMask | ButtonPressMask; + xswa.background_pixel = WhitePixel(d, DefaultScreen(d)); + xswa.border_pixel = BlackPixel(d, DefaultScreen(d)); + visual.visualid = CopyFromParent; + + if ((w = XCreateWindow(d, RootWindow(d, DefaultScreen(d)), + 0, 0, + width, height, + 1, 1, + InputOutput, &visual, + CWEventMask | CWBorderPixel | CWBackPixel, + &xswa)) == (Window)0) + return (0); + + XChangeProperty(d, w, XA_WM_NAME, XA_STRING, 8, + PropModeReplace, title, strlen(title)); + + XMapWindow(d, w); + + xgcv.foreground = BlackPixel(d, DefaultScreen(d)); + xgcv.background = WhitePixel(d, DefaultScreen(d)); + gc = XCreateGC(d, w, GCForeground | GCBackground, &xgcv); + + XNextEvent(d, &event); + switch (event.type) + { + case Expose: + while (XCheckTypedEvent(d, Expose, &event)) + ; + break; + default: + (void)fprintf(stderr, "Unknown event type %d\n", event.type); + break; + } + return (w); +} + +static displaychar(buf) + char *buf; +/* +** Plot char in window +*/ +{ + register int i, npoints, oxpos, oypos, xpos, ypos, xmin, xmax; + register char *p; + char spoints[4]; + XEvent event; + + XClearWindow(d, w); + spoints[3] = '\0'; + (void)strncpy(spoints, &buf[5], 3); + p = &buf[8]; + + /* first point fixes origin of char */ + xmin = CTOI(*p++) * mag + xorg; + xmax = CTOI(*p++) * mag + xorg; + ypos = NORMALVOFF * mag + yorg; + XDrawLine(d, w, gc, 0, ypos, xorg*2-1, ypos); + XDrawLine(d, w, gc, xmin, 0, xmin, yorg*2-1); + XDrawLine(d, w, gc, xmax, 0, xmax, yorg*2-1); + + npoints = atoi(spoints) - 1; + /* get first point */ + oxpos = CTOI(*p++) * mag + xorg; + oypos = CTOI(*p++) * mag + yorg; + if (nums > 0) + XDrawString(d, w, gc, oxpos + 2, oypos, "0", 1); + for (i = 1; i < npoints; ++i) + { + /* lift pen */ + if (*p == ' ') + { + p += 2; + ++i; + oxpos = CTOI(*p++) * mag + xorg; + oypos = CTOI(*p++) * mag + yorg; + if (nums > 0) + { + sprintf(spoints, "%d", i); + XDrawString(d, w, gc, oxpos + 2, oypos, + spoints, strlen(spoints)); + } + } + else + { + xpos = CTOI(*p++) * mag + xorg; + ypos = CTOI(*p++) * mag + yorg; + XDrawLine(d, w, gc, oxpos, oypos, xpos, ypos); + if (nums == 2 || nums == 1 + && (*p == ' ' || i == npoints - 1)) + { + sprintf(spoints, "%d", i); + XDrawString(d, w, gc, xpos + 2, ypos, + spoints, strlen(spoints)); + } + oxpos = xpos; + oypos = ypos; + } + } + for (;;) + { + XNextEvent(d, &event); + switch (event.type) + { + case Expose: + while (XCheckTypedEvent(d, Expose, &event)) + ; + break; + case ButtonPress: + return; + break; + default: + (void)fprintf(stderr, "Unknown event type %d\n", event.type); + break; + } + } +} +#endif NO_X_WINDOW + +static genchar(buf) + char *buf; +/* +** Generate METAFONT code for char +*/ +{ + register int i, npoints, oxpos, oypos, xpos, ypos; + register char *p; + int x0, y0, start, width, ymax = 0, ymin = 256; + char spoints[4]; + + spoints[3] = '\0'; + (void)strncpy(spoints, &buf[5], 3); + npoints = atoi(spoints) - 2; + p = &buf[8]; + + /* first two numbers are xmin and xmax */ + x0 = CTOI(*p++); + width = CTOI(*p++) - x0; + x0 += atoi(perchar.hoff); + y0 = NORMALVOFF + atoi(perchar.voff); + /* find height and depth */ + for (i = 0; i < npoints; ++i, p += 2) + { + if (*p != ' ') + { + ypos = y0 - CTOI(p[1]); + if (ypos > ymax) + ymax = ypos; + if (ypos < ymin) + ymin = ypos; + } + } + if (ymin > 0) + ymin = 0; + + /* output header */ + (void)printf("x#:=%su#; y#:=%su#;\n", perchar.hratio, perchar.vratio); + if ('!' <= perchar.asciiindex && perchar.asciiindex <= '~' && perchar.asciiindex != '"') + (void)printf("beginchar(\"%c\",%dx#,%dy#,%dy#); \"The letter %c\";\n", + perchar.asciiindex, width, ymax, -ymin, + perchar.asciiindex); + else + (void)printf("beginchar(char %d,%dx#,%dy#,%dy#); \"The letter '\\%03o'\";\n", + perchar.asciiindex, width, ymax, -ymin, + perchar.asciiindex); + (void)printf("adjust_fit(0,0); pickup plotter_pen;\n"); + (void)printf("x:=%su; y:=%su;\n", perchar.hratio, perchar.vratio); + + p = &buf[10]; + /* get first point */ + start = 0; + oxpos = CTOI(*p++) - x0; + oypos = y0 - CTOI(*p++); + (void)printf("z%d=(%dx,%dy);\n", start, oxpos, oypos); + for (i = 1; i <= npoints; ++i) + { + /* lift pen */ + if (*p == ' ') + { + outlist(start, i-1); + p += 2; + ++i; + oxpos = CTOI(*p++) - x0; + oypos = y0 - CTOI(*p++); + start = i; + (void)printf("z%d=(%dx,%dy);\n", i, oxpos, oypos); + } + else + { + xpos = CTOI(*p++) - x0; + ypos = y0 - CTOI(*p++); + (void)printf("z%d=(%dx,%dy);\n", i, xpos, ypos); + oxpos = xpos; + oypos = ypos; + } + } + outlist(start, i-1); + (void)printf("endchar;\n"); +} + +static outlist(start, end) + int start, end; +/* +** Output a list of points to join with curve +*/ +{ + register int i; + + /* null case? */ + if (start == end) + return; + (void)printf("draw "); + for (i = start; i < end; ++i) + (void)printf("z%d--", i); + (void)printf("z%d;\n", end); +} |