38 #define CHUNK_SIZE (64 * 1024) 39 #define HEADER_MAX 2000 41 #define SECTION_SIZE (sizeof(uint16_t) * 256) 96 #define LOG(lev, fmt, ...) \ 98 printf(fmt, ##__VA_ARGS__); 107 uint32_t hash = 0x811c9dc5;
215 for (i = 0; i <
BUCKETS; i++) {
266 uint8_t section_table[4][256];
267 uint8_t sec_count[4];
268 uint16_t *sections[4];
279 fp = fopen(path,
"wb");
281 LOG(
LOG_ERROR,
"Couldn't open header file \"%s\"\n", path);
287 fprintf(fp,
" */\n\n");
288 fprintf(fp,
"/* Don't edit this file, it was generated from the " 289 "plain text source data. */\n\n");
292 for (s = 0; s < 4; s++) {
293 fprintf(fp,
"const uint8_t *%s_section_table;\n",
295 fprintf(fp,
"const uint16_t *%s_sections;\n",
300 fprintf(fp,
"const uint8_t *font_glyph_data;\n");
316 fp = fopen(path,
"wb");
318 LOG(
LOG_ERROR,
"Couldn't open output file \"%s\"\n", path);
324 fprintf(fp,
" */\n\n");
325 fprintf(fp,
"/* Don't edit this file, it was generated from the " 326 "plain text source data. */\n\n");
328 fprintf(fp,
"#include <stdint.h>\n");
331 for (s = 0; s < 4; s++) {
333 fprintf(fp,
"static const uint8_t %s_section_table_c[256] = {\n",
336 for (i = 0; i < 256; i++) {
338 fprintf(fp,
"0x%.2X\n",
341 fprintf(fp,
"0x%.2X,\n",
344 fprintf(fp,
"\t0x%.2X, ",
347 fprintf(fp,
"0x%.2X, ",
351 fprintf(fp,
"};\nconst uint8_t *%s_section_table = &%s_section_table_c[0];\n\n",
353 fprintf(fp,
"static const uint16_t %s_sections_c[%i] = {\n",
357 for (i = 0; i < limit; i++) {
358 uint16_t offset = data->
sections[s][i];
360 fprintf(fp,
"0x%.4X\n", offset);
362 fprintf(fp,
"0x%.4X,\n", offset);
364 fprintf(fp,
"\t0x%.4X, ", offset);
366 fprintf(fp,
"0x%.4X, ", offset);
369 fprintf(fp,
"};\nconst uint16_t *%s_sections = &%s_sections_c[0];\n\n",
var_lables[s],
var_lables[s]);
372 fprintf(fp,
"static const uint8_t font_glyph_data_c[%i] = {\n",
375 fprintf(fp,
"\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n" 376 "\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n");
379 for (i = 0; i < limit; i++) {
382 for (y = 0; y < 16; y++) {
383 if (i == limit - 1 && y == 15)
384 fprintf(fp,
"0x%.2X\n", e->
data.
u8[y]);
386 fprintf(fp,
"0x%.2X,\n", e->
data.
u8[y]);
388 fprintf(fp,
"\t0x%.2X, ", e->
data.
u8[y]);
390 fprintf(fp,
"0x%.2X, ", e->
data.
u8[y]);
395 fprintf(fp,
"const uint8_t *font_glyph_data = &font_glyph_data_c[0];\n\n");
415 if (d->
glyphs >= 0xfffd) {
430 if ((s == 0 && d->
sections[style] == NULL) ||
433 uint16_t *temp = realloc(d->
sections[style], size);
439 memset(temp + d->
sec_count[style] * 256, 0,
455 int offset = pos % 11;
460 "expecting '\\n', got '%c' (%i)\n",
466 }
else if (pos < 3) {
469 "expecting ' ', got '%c' (%i)\n",
475 }
else if (offset == 0) {
476 if (c !=
'\n' && c !=
' ') {
478 "expecting '\\n' or ' ', " 485 }
else if (offset < 3) {
488 "expecting ' ', got '%c' (%i)\n",
494 }
else if (offset >= 3 && pos < 11) {
495 if (c !=
'.' && c !=
'#') {
497 "expecting '.' or '#', " 507 if (c !=
'.' && c !=
'#' && c !=
' ') {
509 "expecting '.', '#', or ' ', " 518 #define SEVEN_SET ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | \ 519 (1 << 4) | (1 << 5) | (1 << 6)) 521 #define THREE_SSS ((1 << 0) | (1 << 1) | (1 << 2)) 522 #define THREE_S_S ((1 << 0) | (1 << 2)) 523 #define THREE__SS ((1 << 0) | (1 << 1) ) 524 #define THREE_SS_ ( (1 << 1) | (1 << 2)) 525 #define THREE_S__ (1 << 2) 526 #define THREE__S_ (1 << 1) 527 #define THREE___S (1 << 0) 643 code_point[ 3] = (frag[l][0] << (4 + shift)) | (frag[r][0] << shift);
644 code_point[ 4] = (frag[l][1] << (4 + shift)) | (frag[r][1] << shift);
645 code_point[ 5] = (frag[l][2] << (4 + shift)) | (frag[r][2] << shift);
646 code_point[ 6] = (frag[l][3] << (4 + shift)) | (frag[r][3] << shift);
647 code_point[ 7] = (frag[l][4] << (4 + shift)) | (frag[r][4] << shift);
656 code_point[ 9] = (frag[l][0] << (4 + shift)) | (frag[r][0] << shift);
657 code_point[10] = (frag[l][1] << (4 + shift)) | (frag[r][1] << shift);
658 code_point[11] = (frag[l][2] << (4 + shift)) | (frag[r][2] << shift);
659 code_point[12] = (frag[l][3] << (4 + shift)) | (frag[r][3] << shift);
660 code_point[13] = (frag[l][4] << (4 + shift)) | (frag[r][4] << shift);
679 if (style == 1 || style == 3) {
693 int g_pos = ctx->
data.
in_gd.pos % 11 - 3;
701 "glyph line: %i, pos: %i\n",
710 (c ==
'.' || c ==
'#')) {
727 *row += 1 << (7 - g_pos);
729 ctx->
data.
in_gd.line_styles |= 1 << glyph;
730 }
else if (c ==
'.') {
731 ctx->
data.
in_gd.line_styles |= 1 << glyph;
739 "\"Regular\" glyph style must " 740 "be present\n", ctx->
id);
747 "styles don't match first line\n",
762 for (i = 0; i < 4; i++) {
787 ctx->
state = BEFORE_ID;
794 for (i = 0; i < 4; i++) {
808 if (c >=
'0' && c <=
'9')
810 else if (c >=
'A' && c <=
'F')
830 *
id += v << (4 * (3 - n));
841 const char *pos = buf;
842 const char *end = buf + len;
844 for (i = 0; i < 4; i++) {
845 count[i] = ctx->
count[i];
854 switch (ctx->
state) {
858 printf(
"Got: %c (%i)\n", *pos, *pos);
863 ctx->
state = IN_HEADER;
877 ctx->
state = BEFORE_ID;
879 }
else if (*pos ==
'*') {
884 }
else if (*pos ==
'\n') {
904 ctx->
state = GLYPH_ID;
907 }
else if (*pos ==
'U' &&
911 }
else if (*pos ==
'\n') {
934 ctx->
state = BEFORE_GLYPH_DATA;
939 case BEFORE_GLYPH_DATA:
942 ctx->
state = IN_GLYPH_DATA;
953 }
else if (*pos ==
'\n') {
958 }
else if (*pos ==
'-' &&
964 }
else if (*pos ==
' ' &&
970 }
else if (*pos ==
'-' &&
996 for (i = 0; i < 4; i++) {
998 ctx->
count[i] - count[i]);
1020 fp = fopen(path,
"rb");
1026 d = calloc(
sizeof(
struct font_data), 1);
1028 LOG(
LOG_ERROR,
"Couldn't allocate memory for font data\n");
1034 fseek(fp, 0L, SEEK_END);
1035 file_len = ftell(fp);
1036 if ((
long)file_len == -1) {
1042 fseek(fp, 0L, SEEK_SET);
1048 LOG(
LOG_ERROR,
"Couldn't allocate memory for input buffer\n");
1060 for (done = 0; done < file_len; done +=
CHUNK_SIZE) {
1066 len != file_len - done) {
1090 if (ctx.
state != BEFORE_ID) {
1099 for (i = 0; i < 4; i++) {
1101 count += ctx.
count[i];
1105 "(of which %i unique, %i codepoints, %i duplicates)\n",
1120 "\t%s [options] <in_file> <out_file>\n" 1123 "\t--help -h Display this text\n" 1124 "\t--quiet -q Don't show warnings\n" 1125 "\t--verbose -v Verbose output\n" 1126 "\t--debug -d Full debug output\n",
1132 const char *in_path = NULL;
1133 const char *out_path = NULL;
1134 char *header_path = NULL;
1143 struct option long_options[] = {
1144 {
"help", no_argument, NULL,
'h' },
1145 {
"quiet", no_argument, NULL,
'q' },
1146 {
"verbose", no_argument, NULL,
'v' },
1147 {
"debug", no_argument, NULL,
'd' },
1148 {
"header", required_argument, NULL,
'H' },
1151 while ((opt = getopt_long(argc, argv,
"hqvdH:", long_options, NULL)) != -1) {
1166 header_path = strdup(optarg);
1172 return EXIT_SUCCESS;
1177 return EXIT_FAILURE;
1181 if ((argc - optind) < 2) {
1184 return EXIT_FAILURE;
1187 in_path = argv[optind];
1188 out_path = argv[optind + 1];
1191 LOG(
LOG_DEBUG,
"Using output path: \"%s\"\n", out_path);
1197 return EXIT_FAILURE;
1201 if (ok && (header_path != NULL)) {
1206 for (i = 0; i < 4; i++) {
1211 return EXIT_FAILURE;
1214 return EXIT_SUCCESS;
struct glyph_entry glyph_entry
glyph_entry * ht[BUCKETS]
Hash table.
struct parse_context::@148::@152 before_gd
Interface to utility string handling.
static bool generate_font_header(const char *path, struct font_data *data)
static bool get_hex_digit_value(char c, int *v)
static glyph_entry * glyph_add_to_table(glyph_entry *new)
Add new glyph to hash table (or free, and return pointer to existing glyph)
uint8_t section_table[4][256]
int codepoints
Glyphs containing codepoints.
uint32_t u32[GLYPH_LEN/4]
static glyph_entry * glyph_add_to_chain(glyph_entry **head, glyph_entry *new)
Add a glyph to a hash chain (or free, and return pointer to existing glyph)
static bool add_glyph_to_data(glyph_entry *add, int id, int style, struct font_data *d)
static bool glyphs_match(const uint8_t *g1, const uint8_t *g2)
Check whether glyphs are identical (compares glyph data)
static void build_codepoint(int id, bool italic, uint8_t *code_point)
const char * short_labels[4]
union glyph_entry::@146 data
static void free_table(void)
Free glyph table.
static bool assemble_codepoint(const char *c, int n, int *id)
struct parse_context::@148::@150 before_id
static uint32_t glyph_hash(const uint8_t *g)
Get hash for glyph data.
static bool parse_chunk(struct parse_context *ctx, const char *buf, size_t len, struct font_data *d)
int count[4]
Count of glyphs in file.
struct parse_context::@148::@151 g_id
const char * var_lables[4]
static void free_chain(glyph_entry *head)
Free a glyph entry chain.
static bool parse_glyph_data(struct parse_context *ctx, char c, struct font_data *d)
static bool load_font(const char *path, struct font_data **data)
static bool generate_font_source(const char *path, struct font_data *data)
int main(int argc, char **argv)
Normal entry point from OS.
struct glyph_entry * next
static void parse_init(struct parse_context *ctx)
static bool glyph_is_codepoint(const glyph_entry *e, int id, int style)
union parse_context::@148 data
The state specific data.
static nserror path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, const float transform[6])
Plots a path.
uint8_t code_point[GLYPH_LEN]
Scratch glyph for generated code points.
enum parse_context::@147 state
Current parser state.
static uint32_t count(const http_directive *list, lwc_string *key)
struct parse_context::@148::@153 in_gd
static bool check_glyph_data_valid(int pos, char c)
#define LOG(lev, fmt,...)
struct parse_context::@148::@149 in_header
static void log_usage(const char *argv0)