#include #include #include #include #define WMAX 512 #define HMAX 256 #define CHARH 12 #define RL32(arr, ofs) (arr[ofs] + (arr[ofs+1] << 8) + (arr[ofs+2] << 16) + (arr[ofs+3] << 24)) #define LINEL 12 static int S(int x) { //this function computes the offset of the glyph for symbol x from //the start of the font, shifted right two bits (to fit in 8 bits) int hi = x / 21; int lo = (x % 21) * 12; return hi | lo; } int main(int argc, char **argv) { uint8_t header[54], image[HMAX][WMAX]; int x, y, w, h, bpp, c, x2, y2, nlines = 0, nglyphs = 0; FILE *f; char lines[256][LINEL+1] = {{0}}; int counts[256] = {0}; int symbols[256]; char font[256][CHARH][8]; unsigned char glyphdata[256]; //bytes to be stuffed into the font int i; /* read 8-bit images as they are, RGB images as grayscale */ if (!(f = fopen(argv[1], "rb"))) { fprintf(stderr, "failed to open %s\n" , argv[1]); return 1; } fread(header, 54, 1, f); w = RL32(header, 18); h = RL32(header, 22); bpp = header[28] + (header[29] << 8); fseek(f, RL32(header, 10), SEEK_SET); fprintf(stderr, "%ix%i %i bpp\n", w, h, bpp); if (w > WMAX || h > HMAX) { fprintf(stderr, "image too large\n"); return -1; } for (x = 0; x < 256; x++) strcpy(lines[x], " "); for (y = h-1; y >= 0; y--) { switch(bpp) { case 8: fread(image[y], w, 1, f); break; case 24: case 32: for (x = 0; x < w; x++) { int temp = getc(f) + getc(f) + getc(f); if (bpp == 32) getc(f); image[y][x] = temp / 3; } break; default: fprintf(stderr, "can't handle %i-bit BMPs\n", bpp); } /* align */ if (w*(bpp/8) & 3) fseek(f, 4 - (w*(bpp/8) & 3), SEEK_CUR); } fclose(f); for (i = 0; i < 66; i++) { c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!?.,abcdefghijklmnopqrstuvwxyz"[i]; for (y = 0; y < CHARH; y++) { font[c][y][7] = 0; for (x = 0; x < 7; x++) font[c][y][x] = image[y][i*7+x] > 128; } } for (x = 0;;) { if ((c = getc(stdin)) < 0) break; if (c == '\n') { x = 0; nlines++; continue; } lines[nlines][x++] = c; counts[c]++; } printf(" MAC FONT\n"); printf("Font"); i = 0; //offset for (x = 0; x < 256; x++) if (counts[x]) { symbols[x] = nglyphs++; printf("\n ;'%c'\n", x); for (y = CHARH-1; y >= 0; y--) { printf(" byte %%%i%i%i%i%i%i%i%i\n", font[x][y][0], font[x][y][1], font[x][y][2], font[x][y][3], font[x][y][4], font[x][y][5], font[x][y][6], font[x][y][7]); } if (i % 21 == 20) { printf("\n ;padding to next page\n"); printf(" word $FFFF,$FFFF\n"); } i++; } printf(" ENDM\n"); printf(" MAC TEXT_DATA\n"); printf("Lines\n"); for (x = 0; x < nlines; x++) { printf (" byte "); for (y = 0; y < 12; y += 4) { if (y > 0) printf(","); //lower six bits = glyph index //concat top two bits of all three bytes to form fourth glyph index //like so: //glyphs: Aaaaaa, Bbbbbb, Cccccc, Dddddd //byte 0: DdAaaaaa //byte 1: ddBbbbbb //byte 2: ddCccccc //TODO: pack the other way around? whichever is faster to decode /*printf("$%02X,$%02X,$%02X", symbols[lines[x][y+0]] | ((symbols[lines[x][y+3]] << 6) & 192), symbols[lines[x][y+1]] | ((symbols[lines[x][y+3]] << 4) & 192), symbols[lines[x][y+2]] | ((symbols[lines[x][y+3]] << 2) & 192));*/ printf("$%02X,$%02X,$%02X,$%02X", S(symbols[lines[x][y+0]]), S(symbols[lines[x][y+1]]), S(symbols[lines[x][y+2]]), S(symbols[lines[x][y+3]])); } printf(" ;%i: '%s'\n", x, lines[x]); } printf(" ENDM\n"); printf("CHARH equ %i\n", CHARH); printf("NSYM equ %i\n", nglyphs); printf("NLINES equ %i\n", nlines); x = nglyphs * CHARH; y = nlines * 9; printf(";font size: %i\n", CHARH*nglyphs); printf(";total size: %i + %i = %i B\n", x, y, x+y); return 0; }