From 822b3e760e4840dc688a840610379d977cec7b0c Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 2 Oct 2007 06:50:43 +0000 Subject: include the ucf font compiler and the ytty font in uuterm repository, incorporating a simple nonrecursive build system for the font. --- ucfcomp.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 ucfcomp.c (limited to 'ucfcomp.c') diff --git a/ucfcomp.c b/ucfcomp.c new file mode 100644 index 0000000..d607a43 --- /dev/null +++ b/ucfcomp.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include + +struct gmap +{ + struct gmap *next, *prev; + int glyph; + int width; + unsigned char rules[4*8]; + int len; + int offset; +}; + +static struct gmap *ctab[0x30000]; + +#define GMAP_WIDTH 1 + +#define GMAP_FINAL1 0 +#define GMAP_FINAL2 1 +#define GMAP_GLYPH1 2 +#define GMAP_GLYPH2 3 + +#define RULE_RANGE 4 +#define RULE_ATTACHED_TO 5 +#define RULE_WITH_ATTACHED 6 +#define RULE_FOLLOWS 7 +#define RULE_PRECEDES 8 + +#define CTAB_MASK 0x3fffffff +#define CTAB_INDIRECT 0x80000000 +#define CTAB_WIDTH 30 + +static void put_u32(int n) +{ + putchar(n>>24); + putchar(n>>16); + putchar(n>>8); + putchar(n); +} + +int main() +{ + char buf[256], *s; + int i; + int ch; + struct gmap *gm; + int type, begin, len; + int w=8, h=16; + unsigned char gbuf[32]; + char tmp[3]; + int width; + int nglyphs = 0; + unsigned char *glyphs = 0; + struct { unsigned begin, len, rel; } *ranges = 0; + int nranges = 0; + int ctab_len = 0; + int gmap_len = 0; + + while ((s=fgets(buf, sizeof buf, stdin))) { + if (*s++ != ':') continue; + for (tmp[2]=i=0; iglyph = nglyphs-width; + gm->width = width; + gm->next = 0; + gm->prev = ctab[ch]; + if (ctab[ch]) ctab[ch]->next = gm; + ctab[ch] = gm; + i=0; + while(irules)-12 && *s && !isspace(*s)) { + switch (*s++) { + case '+': type = RULE_WITH_ATTACHED; break; + case '-': type = RULE_ATTACHED_TO; break; + case '<': type = RULE_PRECEDES; break; + case '>': type = RULE_FOLLOWS; break; + default: exit(1); + } + if (*s == '[') { + begin = strtol(++s, &s, 16); + if (*s++ != '-') exit(1); + len = strtol(s, &s, 16) - begin + 1; + if (*s++ != ']') exit(1); + gm->rules[i++] = type; + gm->rules[i++] = begin>>16; + gm->rules[i++] = begin>>8; + gm->rules[i++] = begin; + gm->rules[i++] = RULE_RANGE; + gm->rules[i++] = len>>16; + gm->rules[i++] = len>>8; + gm->rules[i++] = len; + } else if (isxdigit(*s)) { + begin = strtol(s, &s, 16); + gm->rules[i++] = type; + gm->rules[i++] = begin>>16; + gm->rules[i++] = begin>>8; + gm->rules[i++] = begin; + } else exit(1); + } + gm->rules[i++] = GMAP_GLYPH1 | (gm->width-1); + gm->rules[i++] = (gm->glyph)>>16; + gm->rules[i++] = (gm->glyph)>>8; + gm->rules[i++] = (gm->glyph); + gm->len = i; + } + } + + /* Count total glyph mapping rules and figure the table offsets */ + for (ch=0; ch < sizeof(ctab)/sizeof(ctab[0]); ch++) { + for (gm = ctab[ch]; gm && gm->prev; gm = gm->prev); + /* Exclude rules that can be replaced by a trivial mapping */ + if (!gm || (!gm->next && gm->len == 4)) { + if (gm) gm->len = 0; + continue; + } + for (ctab[ch] = gm; gm; gm = gm->next) { + /* Terminate the rules list */ + if (!gm->next) gm->rules[gm->len-4] &= GMAP_WIDTH; + gm->offset = gmap_len; + gmap_len += gm->len; + } + } + + /* Compact empty intervals and intervals with trivial glyph mapping */ + begin = 1; + for (ch=1; ch <= sizeof(ctab)/sizeof(ctab[0]); ch++) { + if (ch == sizeof(ctab)/sizeof(ctab[0]) + || (ctab[ch-1] != ctab[ch] + &&(!ctab[ch-1] || !ctab[ch] + || ctab[ch-1]->prev || ctab[ch-1]->len > 4 + || ctab[ch]->prev || ctab[ch]->len > 4 + || ctab[ch]->glyph != ctab[ch-1]->glyph + ctab[ch-1]->width + || ctab[ch]->width != ctab[ch-1]->width))) { + if (ch - begin >= 1024) { + ranges = realloc(ranges, sizeof(ranges[0])*(nranges+1)); + ranges[nranges].begin = begin; + ranges[nranges++].len = ch-begin; + } + begin = ch+1; + } + } + ranges[nranges-1].len = 0x110000; + + /* Count total size of the character table */ + ranges[0].rel = ranges[0].begin; + ctab_len = 1 + nranges*2 + ranges[0].begin; + for (i=1; ilen == 0) + put_u32(ctab[ch]->glyph | ctab[ch]->width-1<<30); + else + put_u32(ctab[ch]->offset | 0x80000000); + } + // offset 32 + ctab_len + for (ch=0; ch < sizeof(ctab)/sizeof(ctab[0]); ch++) + for (gm = ctab[ch]; gm; gm = gm->next) + fwrite(gm->rules, 1, gm->len, stdout); + // offset 30 + ctab_len + gmap_len + fwrite(glyphs, 16, nglyphs, stdout); + + return 0; +} -- cgit v1.2.3