| @@ -46,52 +46,9 @@ static int const blocklist[] = | |||||
| 0, 0 | 0, 0 | ||||
| }; | }; | ||||
| static int printf_hex(char const *fmt, uint8_t *data, int bytes) | |||||
| { | |||||
| char buf[BUFSIZ]; | |||||
| char *parser = buf; | |||||
| int rewind = 0; /* we use this variable to rewind 2 bytes after \000 | |||||
| * was printed when the next char starts with "\", too. */ | |||||
| while(bytes--) | |||||
| { | |||||
| uint8_t c = *data++; | |||||
| if(c == '\\' || c == '"') | |||||
| { | |||||
| parser -= rewind; | |||||
| parser += sprintf(parser, "\\%c", c); | |||||
| rewind = 0; | |||||
| } | |||||
| else if(c >= 0x20 && c < 0x7f) | |||||
| { | |||||
| parser += sprintf(parser, "%c", c); | |||||
| rewind = 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| parser -= rewind; | |||||
| parser += sprintf(parser, "\\%.03o", c); | |||||
| rewind = c ? 0 : 2; | |||||
| } | |||||
| } | |||||
| parser -= rewind; | |||||
| parser[0] = '\0'; | |||||
| return printf(fmt, buf); | |||||
| } | |||||
| static int printf_u32(char const *fmt, uint32_t i) | |||||
| { | |||||
| uint32_t ni = htonl(i); | |||||
| return printf_hex(fmt, (uint8_t *)&ni, 4); | |||||
| } | |||||
| static int printf_u16(char const *fmt, uint16_t i) | |||||
| { | |||||
| uint16_t ni = htons(i); | |||||
| return printf_hex(fmt, (uint8_t *)&ni, 2); | |||||
| } | |||||
| static int printf_hex(char const *, uint8_t *, int); | |||||
| static int printf_u32(char const *, uint32_t); | |||||
| static int printf_u16(char const *, uint16_t); | |||||
| int main(void) | int main(void) | ||||
| { | { | ||||
| @@ -105,9 +62,15 @@ int main(void) | |||||
| int width, height, b, i, n, blocks, glyphs, data_bytes; | int width, height, b, i, n, blocks, glyphs, data_bytes; | ||||
| uint8_t *glyph_data; | uint8_t *glyph_data; | ||||
| int bpp = BPP; | |||||
| int dpi = DPI; | |||||
| char const *font = FONT; | |||||
| fprintf(stderr, "Font \"%s\", %i dpi, %i bpp\n", font, dpi, bpp); | |||||
| /* Initialise Pango */ | /* Initialise Pango */ | ||||
| fm = pango_ft2_font_map_new(); | fm = pango_ft2_font_map_new(); | ||||
| pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fm), DPI, DPI); | |||||
| pango_ft2_font_map_set_resolution(PANGO_FT2_FONT_MAP(fm), dpi, dpi); | |||||
| cx = pango_ft2_font_map_create_context(PANGO_FT2_FONT_MAP(fm)); | cx = pango_ft2_font_map_create_context(PANGO_FT2_FONT_MAP(fm)); | ||||
| l = pango_layout_new(cx); | l = pango_layout_new(cx); | ||||
| @@ -117,7 +80,7 @@ int main(void) | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| fd = pango_font_description_from_string(FONT); | |||||
| fd = pango_font_description_from_string(font); | |||||
| pango_layout_set_font_description(l, fd); | pango_layout_set_font_description(l, fd); | ||||
| pango_font_description_free(fd); | pango_font_description_free(fd); | ||||
| @@ -134,7 +97,7 @@ int main(void) | |||||
| pango_layout_get_extents(l, NULL, &r); | pango_layout_get_extents(l, NULL, &r); | ||||
| width = PANGO_PIXELS(r.width); | width = PANGO_PIXELS(r.width); | ||||
| height = PANGO_PIXELS(r.height); | height = PANGO_PIXELS(r.height); | ||||
| data_bytes = ((width * height) + (8 / BPP) - 1) / (8 / BPP); | |||||
| data_bytes = ((width * height) + (8 / bpp) - 1) / (8 / bpp); | |||||
| glyph_data = malloc(data_bytes); | glyph_data = malloc(data_bytes); | ||||
| /* Compute blocks and glyphs count */ | /* Compute blocks and glyphs count */ | ||||
| @@ -149,7 +112,7 @@ int main(void) | |||||
| /* Let's go! */ | /* Let's go! */ | ||||
| printf("/* libcucul font file\n"); | printf("/* libcucul font file\n"); | ||||
| printf(" * \"%s\": %i dpi, %i bpp, %ix%i glyphs\n", | printf(" * \"%s\": %i dpi, %i bpp, %ix%i glyphs\n", | ||||
| FONT, DPI, BPP, width, height); | |||||
| font, dpi, bpp, width, height); | |||||
| printf(" * Automatically generated by tools/makefont.c */\n"); | printf(" * Automatically generated by tools/makefont.c */\n"); | ||||
| printf("\n"); | printf("\n"); | ||||
| @@ -164,7 +127,7 @@ int main(void) | |||||
| printf_u16("\"%s\" /* version */\n", 1); | printf_u16("\"%s\" /* version */\n", 1); | ||||
| printf_u16("\"%s\" /* blocks */\n", blocks); | printf_u16("\"%s\" /* blocks */\n", blocks); | ||||
| printf_u32("\"%s\" /* glyphs */\n", glyphs); | printf_u32("\"%s\" /* glyphs */\n", glyphs); | ||||
| printf_u16("\"%s\" /* bpp */\n", BPP); | |||||
| printf_u16("\"%s\" /* bpp */\n", bpp); | |||||
| printf_u16("\"%s\" /* width */\n", width); | printf_u16("\"%s\" /* width */\n", width); | ||||
| printf_u16("\"%s\" /* height */\n", height); | printf_u16("\"%s\" /* height */\n", height); | ||||
| printf_u16("\"%s\" /* flags */\n", 1); | printf_u16("\"%s\" /* flags */\n", 1); | ||||
| @@ -235,14 +198,9 @@ int main(void) | |||||
| printf("/* U+%.04X: \"", i); | printf("/* U+%.04X: \"", i); | ||||
| if(i < 0x20 || (i >= 0x80 && i <= 0xa0)) | if(i < 0x20 || (i >= 0x80 && i <= 0xa0)) | ||||
| printf("\\x%.02x\" (", i); | |||||
| printf("\\x%.02x\" */", i); | |||||
| else | else | ||||
| printf("%s\" (", buf); | |||||
| for(x = 0; x < bytes; x++) | |||||
| printf("%s0x%.02X", x ? " " : "", (unsigned char)buf[x]); | |||||
| printf(") */\n"); | |||||
| printf("%s\" */ ", buf); | |||||
| /* Render glyph on a bitmap */ | /* Render glyph on a bitmap */ | ||||
| pango_layout_set_text(l, buf, -1); | pango_layout_set_text(l, buf, -1); | ||||
| @@ -258,9 +216,9 @@ int main(void) | |||||
| { | { | ||||
| uint8_t pixel = img.buffer[y * img.pitch + x]; | uint8_t pixel = img.buffer[y * img.pitch + x]; | ||||
| pixel >>= (8 - BPP); | |||||
| glyph_data[n / 8] |= pixel << (8 - BPP - (n % 8)); | |||||
| n += BPP; | |||||
| pixel >>= (8 - bpp); | |||||
| glyph_data[n / 8] |= pixel << (8 - bpp - (n % 8)); | |||||
| n += bpp; | |||||
| } | } | ||||
| } | } | ||||
| printf_hex("\"%s\"\n", glyph_data, data_bytes); | printf_hex("\"%s\"\n", glyph_data, data_bytes); | ||||
| @@ -274,3 +232,54 @@ int main(void) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* | |||||
| * XXX: the following functions are local | |||||
| */ | |||||
| static int printf_u32(char const *fmt, uint32_t i) | |||||
| { | |||||
| uint32_t ni = htonl(i); | |||||
| return printf_hex(fmt, (uint8_t *)&ni, 4); | |||||
| } | |||||
| static int printf_u16(char const *fmt, uint16_t i) | |||||
| { | |||||
| uint16_t ni = htons(i); | |||||
| return printf_hex(fmt, (uint8_t *)&ni, 2); | |||||
| } | |||||
| static int printf_hex(char const *fmt, uint8_t *data, int bytes) | |||||
| { | |||||
| char buf[BUFSIZ]; | |||||
| char *parser = buf; | |||||
| int rewind = 0; /* we use this variable to rewind 2 bytes after \000 | |||||
| * was printed when the next char starts with "\", too. */ | |||||
| while(bytes--) | |||||
| { | |||||
| uint8_t c = *data++; | |||||
| if(c == '\\' || c == '"') | |||||
| { | |||||
| parser -= rewind; | |||||
| parser += sprintf(parser, "\\%c", c); | |||||
| rewind = 0; | |||||
| } | |||||
| else if(c >= 0x20 && c < 0x7f) | |||||
| { | |||||
| parser += sprintf(parser, "%c", c); | |||||
| rewind = 0; | |||||
| } | |||||
| else | |||||
| { | |||||
| parser -= rewind; | |||||
| parser += sprintf(parser, "\\%.03o", c); | |||||
| rewind = c ? 0 : 2; | |||||
| } | |||||
| } | |||||
| parser -= rewind; | |||||
| parser[0] = '\0'; | |||||
| return printf(fmt, buf); | |||||
| } | |||||