/* Copyright 2006 DJ Delorie, distributed under the terms of the GPL v2 */ #include #include #include #include #define LINESIZE (int)(1000.0/72.0) #define LINESIZEPT 1 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ float fm_hlv[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0.277979 ,0.277979 ,0.35498 ,0.555981 ,0.555981 ,0.888989 ,0.666992 ,0.221997 ,0.332983 ,0.332983 ,0.388989 ,0.583984 ,0.277979 ,0.332983 ,0.277979 ,0.277979 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.277979 ,0.277979 ,0.583984 ,0.583984 ,0.583984 ,0.555981 ,1.01499 ,0.666992 ,0.666992 ,0.721997 ,0.721997 ,0.666992 ,0.610986 ,0.777979 ,0.721997 ,0.277979 ,0.5 ,0.666992 ,0.555981 ,0.832983 ,0.721997 ,0.777979 ,0.666992 ,0.777979 ,0.721997 ,0.666992 ,0.610986 ,0.721997 ,0.666992 ,0.943994 ,0.666992 ,0.666992 ,0.610986 ,0.277979 ,0.277979 ,0.277979 ,0.468994 ,0.555981 ,0.221997 ,0.555981 ,0.555981 ,0.5 ,0.555981 ,0.555981 ,0.277979 ,0.555981 ,0.555981 ,0.221997 ,0.221997 ,0.5 ,0.221997 ,0.832983 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.332983 ,0.5 ,0.277979 ,0.555981 ,0.5 ,0.721997 ,0.5 ,0.5 ,0.5 ,0.333984 ,0.259985 ,0.333984 ,0.583984 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.332983 ,0.555981 ,0.555981 ,0.166992 ,0.555981 ,0.555981 ,0.555981 ,0.555981 ,0.190991 ,0.332983 ,0.555981 ,0.332983 ,0.332983 ,0.5 ,0.5 ,0.0 ,0.555981 ,0.555981 ,0.555981 ,0.277979 ,0.0 ,0.536987 ,0.35 ,0.221997 ,0.332983 ,0.332983 ,0.555981 ,1.0 ,1.0 ,0.0 ,0.610986 ,0.0 ,0.332983 ,0.332983 ,0.332983 ,0.332983 ,0.332983 ,0.332983 ,0.332983 ,0.332983 ,0.0 ,0.332983 ,0.332983 ,0.0 ,0.332983 ,0.332983 ,0.332983 ,1.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,1.0 ,0.0 ,0.369995 ,0.0 ,0.0 ,0.0 ,0.0 ,0.555981 ,0.777979 ,1.0 ,0.36499 ,0.0 ,0.0 ,0.0 ,0.0 ,0.0 ,0.888989 ,0.0 ,0.0 ,0.0 ,0.277979 ,0.0 ,0.0 ,0.221997 ,0.610986 ,0.943994 ,0.610986 ,0.0 ,0.0 ,0.0 ,0.0 }; char **sym; int nsym; typedef struct { int type; int size; int color; int index; } Sortable; Sortable *sort; int nsort = 0; void save_sort (int type, int size, int color, int index) { sort[nsort].type = type; sort[nsort].color = color; sort[nsort].size = size; sort[nsort].index = index; nsort ++; } void * xrealloc (void *v, int n) { if (v) return realloc (v, n); return malloc (n); } char * safe_fgets (FILE *f) { static char *buffer = 0; static int bufsize = 0; int bufptr; int ch; bufptr = 0; while (1) { ch = fgetc(f); if (ch == EOF) { if (bufptr == 0) return 0; buffer[bufptr] = 0; return buffer; } if (ch == '\r') continue; if (bufsize <= bufptr) { bufsize += 10; buffer = (char *) xrealloc (buffer, bufsize+1); if (buffer == 0) { fprintf(stderr, "Out of memory! bufsize %d\n", bufsize); exit(1); } } buffer[bufptr++] = ch; if (ch == '\n') { buffer[bufptr-1] = 0; return buffer; } } } void read_symfile (FILE *f) { char *line; int msym = 0; while (line = safe_fgets(f)) { if (msym <= nsym) { msym += 10; sym = (char **) xrealloc (sym, msym*sizeof(char *)); } while (*line && isspace(*line)) line++; sym[nsym++] = strdup(line); } } int minx=1<<30, maxx=-(1<<30), miny=1<<30, maxy=-(1<<30); void coord(int x, int y, int w) { w /= 2; if (minx > x - w) minx = x - w; if (maxx < x + w) maxx = x + w; if (miny > y - w) miny = y - w; if (maxy < y + w) maxy = y + w; } int ps_length(char *t, int size) { float l = 0; while (*t) { l += fm_hlv[(*t) & 0xff] * size; t++; } return (int)l; } void scan_extents () { int i, j; int x, y, w, h, x1, y1, x2, y2, n, s, r, v, avc, a, align; int c; for (i=0; itype != b->type) return a->type - b->type; if (a->size != b->size) return a->size - b->size; if (a->color != b->color) return a->color - b->color; return a->index - b->index; } const char * colormap[] = { "1.0 1.0 1.0", /* background */ "0.0 0.0 0.0", /* white */ "0.8 0.0 0.0", /* red */ "0.0 0.5 0.0", /* green */ "0.0 0.0 1.0", /* blue */ "0.5 0.5 0.0", /* yellow */ "0.0 0.5 0.5", /* cyan */ "0.0 0.5 0.5", /* ? */ "0.8 0.0 0.0", /* red */ "0.0 0.5 0.0", /* green */ "0.0 0.5 0.0", /* green */ "0.9 0.4 0.0", /* orange */ "0.9 0.4 0.0", /* orange */ "0.0 0.5 0.5", /* cyan */ "0.6 0.6 0.6", /* grey90 */ "0.4 0.4 0.4", /* grey */ "0.6 0.0 0.6", /* "other" */ }; #define NUM_COLORS (sizeof(colormap)/sizeof(colormap[0])) void color_size (FILE *f, int c, int s) { static int oc = -1; static int os = -100; if (oc != c) { if (c < 0 || c >= NUM_COLORS) c = NUM_COLORS-1; fprintf(f, "%s setrgbcolor\n", colormap[c]); oc = c; } if (os != s) { if (s < LINESIZEPT) s = LINESIZEPT; fprintf(f, "%d setlinewidth\n", s); os = s; } } void write_eps (const char *filename, FILE *f) { int i, j, si; int x, y, w, h, x1, y1, x2, y2, n, s, r, v, avc, a, align; int c; double scale = 1.0; if (maxx - minx > 10000 || maxy - miny > 15000) scale = 0.5; minx -= MARGIN; miny -= MARGIN; maxx += MARGIN; maxy += MARGIN; fprintf(f, "%!PS-Adobe-3.0 EPSF-3.0\n"); fprintf(f, "%%%%BoundingBox: 0 0 %g %g\n", (maxx-minx)/1000.0 * 72 * scale, (maxy-miny)/1000.0 * 72 * scale); fprintf(f, "%%%%Pages: 1\n"); fprintf(f, "save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def\n"); fprintf(f, "%%%%EndProlog\n"); fprintf(f, "%%%%Page: 1 1\n"); fprintf(f, "%%%%BeginDocument: %s\n", filename); fprintf(f, "%g dup scale\n", 72.0/1000.0 * scale); fprintf(f, "%d %d translate\n", -minx, -miny); fprintf(f, "/t { gsave translate rotate moveto show grestore } bind def\n"); qsort (sort, nsort, sizeof(sort[0]), sort_func); for (si=0; si 1) { symfile = fopen (argv[1], "r"); if (!symfile) { fprintf(stderr, "Error: can't open %s for reading.\n", argv[1]); perror("The error was\n"); exit(1); } } else { symfile = stdin; } read_symfile(symfile); sort = (Sortable *) malloc (nsym * sizeof(Sortable)); if (symfile != stdin) fclose (symfile); scan_extents(); if (argc > 2) { epsfile = fopen (argv[2], "w"); if (!symfile) { fprintf(stderr, "Error: can't open %s for writing.\n", argv[2]); perror("The error was\n"); exit(1); } } else epsfile = stdout; write_eps(argc > 2 ? argv[2] : "stdout.eps", epsfile); if (epsfile != stdout) fclose(epsfile); exit(0); }