#include #include #include #include #include FT_FREETYPE_H #include FT_GLYPH_H #include FT_TRUETYPE_DRIVER_H #include FT_MODULE_H #include #define OPCODE_REPEAT 253 #define OPCODE_EOL 254 #define OPCODE_EOC 255 #define MAX_RLE 80 /* Maximum number of repeats */ /**************************************************************************** * BYTEPOINTER FUNCTIONS ****************************************************************************/ struct histogram { int position; int count; }; struct bytepointer { unsigned char *p; unsigned char *start; unsigned char *end; struct histogram histogram[256]; }; struct bitoutput { FILE *fp; int col; int byte_count; uint8_t byte; uint8_t bit; }; void init_bytepointer (struct bytepointer *bp, unsigned char *buffer, int n) { int i; bp->p = buffer; bp->start = buffer; bp->end = buffer + n; for (i=0; i<256; i++) { bp->histogram[i].position = i; bp->histogram[i].count = 0; } } void save_byte (struct bytepointer *bp, unsigned char byte) { if (bp->p == bp->end) { printf ("OUT OF BITPOINTER MEMORY.\n"); exit (2); } // If byte is more than MAX_RLE, break into MAX_RLE, 0, remainder while (byte < OPCODE_REPEAT && byte > MAX_RLE) { * (bp->p++) = MAX_RLE; * (bp->p++) = 0; byte -= MAX_RLE; } * (bp->p++) = byte; bp->histogram[byte].count++; } int histcmp (const void *p, const void *q) { struct histogram *p0 = (struct histogram *) p; struct histogram *q0 = (struct histogram *) q; return q0->count - p0->count; } void save_bits (struct bitoutput *bits, int bit) { if (bit) bits->byte |= bits->bit; bits->bit >>= 1; if (!bits->bit) { if (bits->col == 12) { fprintf (bits->fp, ",\n\t"); bits->col = 0; } else if (bits->col != 0) fprintf (bits->fp, ", "); fprintf (bits->fp, "0x%02X", bits->byte); bits->col++; bits->byte_count++; bits->bit = 0x80; bits->byte = 0; } } void output_bitstream (struct bytepointer *bp, int max_width, int scaled) { unsigned char *p; struct bitoutput bits; int col, i, v, lookup[256], offset, offsets[96]; qsort (bp->histogram, 256, sizeof (struct histogram), histcmp); for (i=0; i<256; i++) { lookup[bp->histogram[i].position] = i; } bits.fp = fopen ("font.h", "w"); bits.byte = 0; bits.bit = 0x80; bits.col = 0; bits.byte_count = 0; offset = 0; offsets[0] = 0; fprintf (bits.fp, "/********************************************************************\n" "* Font File format:\n" "* 2 bits: =0, opcode lut index 0\n" "* =1, opcode lut index is in next 3 bits + 1\n" "* =2, opcode lut index is in next 4 bits + 9\n" "* =3, opcode lut index is in next 6 bits + 25\n" "********************************************************************/\n"); fprintf (bits.fp, "unsigned char mfont[] = {\n\t"); for (p = bp->start; p <= bp->p; p++) { v = lookup[*p]; if (v == 0) { save_bits (&bits, 0); save_bits (&bits, 0); } else if (v < 9) { v = v-1; save_bits (&bits, 0); save_bits (&bits, 1); save_bits (&bits, v & 4); save_bits (&bits, v & 2); save_bits (&bits, v & 1); } else if (v < 25) { v = v-9; save_bits (&bits, 1); save_bits (&bits, 0); save_bits (&bits, v & 8); save_bits (&bits, v & 4); save_bits (&bits, v & 2); save_bits (&bits, v & 1); } else { v = v-25; save_bits (&bits, 1); save_bits (&bits, 1); save_bits (&bits, v & 32); save_bits (&bits, v & 16); save_bits (&bits, v & 8); save_bits (&bits, v & 4); save_bits (&bits, v & 2); save_bits (&bits, v & 1); } if (*p == OPCODE_EOC) { while (bits.bit != 0x80) save_bits (&bits, 0); offsets[++offset] = bits.byte_count; } } fprintf (bits.fp, "};\n"); fprintf (bits.fp, "unsigned char flut[] = {\n\t"); for (i=0, col=0; bp->histogram[i].count; i++) { if (col == 14) { fprintf (bits.fp, ",\n\t"); col = 0; } else if (col != 0) fprintf (bits.fp, ", "); fprintf (bits.fp, "%3d", bp->histogram[i].position); col++; bits.byte_count++; } fprintf (bits.fp, "};\n"); fprintf (bits.fp, "unsigned int foffs[] = {\n\t"); for (i=0, col=0; iglyph; if ( (error = FT_Render_Glyph (slot, FT_RENDER_MODE_MONO))) { fprintf (stderr, "Error loading char"); exit (2); } if ( (error = FT_Get_Glyph (slot, &glyph))) { fprintf (stderr, "Error loading char"); exit (2); } bitmap = &slot->bitmap; if ( (int) (slot->bitmap_top - bitmap->rows) < max_decender) { max_decender = slot->bitmap_top - bitmap->rows; } if (bitmap->rows > max_width) max_width = bitmap->rows; } max_width++; /* Generate glyphs and encode */ for (c=32; c < 127; c++) { if ( (error = FT_Load_Char (face, c, FT_LOAD_TARGET_MONO))) { fprintf (stderr, "Error loading char"); exit (2); } slot = face->glyph; if ( (error = FT_Render_Glyph (slot, FT_RENDER_MODE_MONO))) { fprintf (stderr, "Error loading char"); exit (2); } if ( (error = FT_Get_Glyph (slot, &glyph))) { fprintf (stderr, "Error loading char"); exit (2); } bitmap = &slot->bitmap; advance = slot->bitmap_left; if (advance < 0) advance = 0; color = 0; for (; advance > 0; advance--) { save_byte (&bp, OPCODE_EOL); if (verbose) printf ("\n"); } for (x=0; x < bitmap->width; x++) { int repeat = 0; // Check for repeating line if (x > 0) { int v0; for (y = bitmap->rows-1; y >= 0; y--) { byte = (x-1) /8; bit = 0x80 >> ( (x-1) &7); v0 = (bitmap->buffer[y*bitmap->pitch + byte]&bit) ? 1: 0; byte = x/8; bit = 0x80 >> (x&7); v = (bitmap->buffer[y*bitmap->pitch + byte]&bit) ? 1: 0; if (v0 != v) break; } if (y < 0) repeat = 1; } // Find end of spaces for (y0=0; y0rows; y0++) { byte = x/8; bit = 0x80 >> (x&7); v = (bitmap->buffer[y0*bitmap->pitch + byte]&bit) ? 1: 0; if (v) break; } offset = -max_decender+ (slot->bitmap_top - bitmap->rows); if (y0 == bitmap->rows) offset = 0; if (verbose) { for (y=0; yrows-1; y>=y0; y--) { byte = x/8; bit = 0x80 >> (x&7); v = (bitmap->buffer[y*bitmap->pitch + byte]&bit) ? 1: 0; if (verbose) { if (v) printf (repeat ? "*" : "#"); else printf (" "); } if (v==color) offset++; else { if (!repeat) save_byte (&bp, offset); color ^= 1; offset = 1; } } if (repeat) { save_byte (&bp, OPCODE_REPEAT); } else { save_byte (&bp, offset); save_byte (&bp, OPCODE_EOL); } color = 0; if (verbose) printf ("\n"); } advance = (slot->advance.x >> 6) - bitmap->width - ( (slot->bitmap_left > 0) ? slot->bitmap_left : 0); if (advance < 0) advance = 0; for (; advance > 0; advance--) { save_byte (&bp, OPCODE_EOL); if (verbose) printf ("\n"); } save_byte (&bp, OPCODE_EOC); FT_Done_Glyph (glyph); } output_bitstream (&bp, max_width, scaled); }