rewrite mkfont_bdf

This commit is contained in:
uobikiemukot 2014-10-06 14:22:18 +09:00
parent 46847f4cc8
commit 4489a65a3e
5 changed files with 360 additions and 284 deletions

View file

@ -2,52 +2,37 @@ int pre_match(const char *buf, const char *str) {
return !strncmp(buf, str, strlen(str));
}
void print_bitmap(uint32_t *bitmap)
{
unsigned int i, j;
for (i = 0; i < MAX_HEIGHT; i++) {
for (j = 1; j <= sizeof(uint32_t) * BITS_PER_BYTE; j++) {
if (bitmap[i] & (1 << (sizeof(uint32_t) * BITS_PER_BYTE - j)))
fprintf(stderr, "@");
else
fprintf(stderr, ".");
}
fprintf(stderr, "\n");
}
}
int bit2byte(int bits)
{
return (bits + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
}
void shift_glyph(struct bdf_t *bdf, struct bdf_glyph_t *glyph)
void shift_glyph(struct bdf_header_t *bdf_header, struct bdf_char_t *bdf_char)
{
int i, byte, shift;
uint32_t tmp;
bitmap_width_t bitmap;
for (i = 0; i < glyph->bbh; i++) {
tmp = glyph->bitmap[i];
byte = bit2byte(glyph->bbw);
tmp <<= (bit2byte(glyph->dwidth) - byte) * BITS_PER_BYTE;
if (glyph->bbx >= 0)
tmp >>= glyph->bbx;
for (i = 0; i < bdf_char->bbh; i++) {
bitmap = bdf_char->bitmap[i];
byte = bit2byte(bdf_char->bbw);
bitmap <<= (bit2byte(bdf_char->dwidth) - byte) * BITS_PER_BYTE;
if (bdf_char->bbx >= 0)
bitmap >>= bdf_char->bbx;
else {
fprintf(stderr, "maybe overlapping (glpyh:%X bbx:%d)\n", glyph->encoding, glyph->bbx);
tmp <<= abs(glyph->bbx);
logging(ERROR, "maybe overlapping (glpyh:%X bbx:%d)\n", bdf_char->encoding, bdf_char->bbx);
bitmap <<= abs(bdf_char->bbx);
}
glyph->bitmap[i] = tmp;
bdf_char->bitmap[i] = bitmap;
}
shift = bdf->ascent - (glyph->bbh + glyph->bby);
shift = bdf_header->ascent - (bdf_char->bbh + bdf_char->bby);
if (shift >= 0) {
memmove(glyph->bitmap + shift, glyph->bitmap, sizeof(uint32_t) * glyph->bbh);
memset(glyph->bitmap, 0, sizeof(uint32_t) * shift);
memmove(bdf_char->bitmap + shift, bdf_char->bitmap, sizeof(bitmap_width_t) * bdf_char->bbh);
memset(bdf_char->bitmap, 0, sizeof(bitmap_width_t) * shift);
}
else {
fprintf(stderr, "maybe overlapping (glpyh:%X vertical shift:%d)\n", glyph->encoding, shift);
memmove(glyph->bitmap, glyph->bitmap + abs(shift), sizeof(uint32_t) * glyph->bbh);
logging(ERROR, "maybe overlapping (glpyh:%X vertical shift:%d)\n", bdf_char->encoding, shift);
memmove(bdf_char->bitmap, bdf_char->bitmap + abs(shift), sizeof(bitmap_width_t) * bdf_char->bbh);
}
}
@ -74,60 +59,66 @@ void load_table(char *path, enum encode_t encode)
if ((cp = strchr(buf, '\n')) != NULL)
*cp = '\0';
sscanf(buf, "%X %X", &from, &to);
sscanf(buf, "%X %X", (unsigned int *) &from, (unsigned int *) &to);
convert_table[from] = to;
}
}
int read_header(char *buf, struct bdf_t *bdf)
int read_header(char *buf, struct bdf_header_t *bdf_header)
{
char *cp;
if (pre_match(buf, "FONTBOUNDINGBOX "))
sscanf(buf + strlen("FONTBOUNDINGBOX "), "%d %d %d %d",
&bdf->bbw, &bdf->bbh, &bdf->bbx, &bdf->bby);
&bdf_header->bbw, &bdf_header->bbh, &bdf_header->bbx, &bdf_header->bby);
else if (pre_match(buf, "FONT_ASCENT "))
bdf->ascent = atoi(buf + strlen("FONT_ASCENT "));
bdf_header->ascent = atoi(buf + strlen("FONT_ASCENT "));
else if (pre_match(buf, "FONT_DESCENT "))
bdf->descent = atoi(buf + strlen("FONT_DESCENT "));
bdf_header->descent = atoi(buf + strlen("FONT_DESCENT "));
else if (pre_match(buf, "DEFAULT_CHAR "))
bdf->default_char = atoi(buf + strlen("DEFAULT_CHAR "));
bdf_header->default_char = atoi(buf + strlen("DEFAULT_CHAR "));
else if (pre_match(buf, "PIXEL_SIZE "))
bdf->pixel_size = atoi(buf + strlen("PIXEL_SIZE "));
bdf_header->pixel_size = atoi(buf + strlen("PIXEL_SIZE "));
else if (pre_match(buf, "CHARSET_REGISTRY ")) {
strncpy(bdf->charset, buf + strlen("CHARSET_REGISTRY "), BUFSIZE - 1);
fprintf(stderr, "%s\n", bdf->charset);
for (cp = bdf->charset; *cp != '\0'; cp++)
*cp = toupper(*cp);
strncpy(bdf_header->charset, buf + strlen("CHARSET_REGISTRY "), BUFSIZE - 1);
logging(DEBUG, "%s\n", bdf_header->charset);
if (strstr(bdf->charset, "X68000") != NULL || strstr(bdf->charset, "x68000") != NULL)
for (cp = bdf_header->charset; *cp != '\0'; cp++)
*cp = (char) toupper((int) *cp);
if (strstr(bdf_header->charset, "X68000") != NULL
|| strstr(bdf_header->charset, "x68000") != NULL)
load_table("./table/X68000", X68000);
else if (strstr(bdf->charset, "JISX0201") != NULL || strstr(bdf->charset, "jisx0201") != NULL)
else if (strstr(bdf_header->charset, "JISX0201") != NULL
|| strstr(bdf_header->charset, "jisx0201") != NULL)
load_table("./table/JISX0201", JISX0201);
else if (strstr(bdf->charset, "JISX0208") != NULL || strstr(bdf->charset, "jisx0208") != NULL)
else if (strstr(bdf_header->charset, "JISX0208") != NULL
|| strstr(bdf_header->charset, "jisx0208") != NULL)
load_table("./table/JISX0208", JISX0208);
else if (strstr(bdf->charset, "ISO8859") != NULL || strstr(bdf->charset, "iso8859") != NULL)
else if (strstr(bdf_header->charset, "ISO8859") != NULL
|| strstr(bdf_header->charset, "iso8859") != NULL)
load_table("./table/ISO8859", ISO8859);
else /* assume "ISO10646" */
load_table("./table/ISO10646", ISO10646);
}
else if (pre_match(buf, "CHARS ")) {
bdf->chars = atoi(buf + strlen("CHARS "));
bdf_header->chars = atoi(buf + strlen("CHARS "));
return BDF_CHAR;
}
return BDF_HEADER;
}
int read_char(char *buf, struct bdf_glyph_t *glyph)
int read_char(char *buf, struct bdf_char_t *bdf_char)
{
if (pre_match(buf, "BBX "))
sscanf(buf + strlen("BBX "), "%d %d %d %d", &glyph->bbw, &glyph->bbh, &glyph->bbx, &glyph->bby);
sscanf(buf + strlen("BBX "), "%d %d %d %d",
&bdf_char->bbw, &bdf_char->bbh, &bdf_char->bbx, &bdf_char->bby);
else if (pre_match(buf, "DWIDTH "))
glyph->dwidth = atoi(buf + strlen("DWIDTH "));
bdf_char->dwidth = atoi(buf + strlen("DWIDTH "));
else if (pre_match(buf, "ENCODING ")) {
glyph->encoding = atoi(buf + strlen("ENCODING "));
//fprintf(stderr, "reading char:%d\n", glyph->encoding);
bdf_char->encoding = atoi(buf + strlen("ENCODING "));
//logging(DEBUG, "reading char:%d\n", bdf_char->encoding);
}
else if (pre_match(buf, "BITMAP")) {
return BDF_BITMAP;
@ -136,67 +127,85 @@ int read_char(char *buf, struct bdf_glyph_t *glyph)
return BDF_CHAR;
}
int read_bitmap(struct glyph_t *fonts, char *buf, struct bdf_t *bdf, struct bdf_glyph_t *glyph)
int read_bitmap(struct glyph_list_t **glist_head, struct glyph_t *default_glyph,
char *buf, struct bdf_header_t *bdf_header, struct bdf_char_t *bdf_char)
{
int i;
static int count = 0;
uint32_t code;
uint8_t width, height;
static int count = 0;
struct glyph_list_t *listp;
struct glyph_t *glyph;
if (pre_match(buf, "ENDCHAR")) {
shift_glyph(bdf, glyph);
count = 0;
code = convert_table[glyph->encoding];
width = glyph->dwidth;
height = bdf->ascent + bdf->descent;
shift_glyph(bdf_header, bdf_char);
//fprintf(stderr, "code:%d width:%d height:%d\n", code, width, height);
code = convert_table[bdf_char->encoding];
width = bdf_char->dwidth;
height = bdf_header->ascent + bdf_header->descent;
if (code < UCS2_CHARS) {
fonts[code].width = width;
fonts[code].height = height;
fonts[code].bitmap = (uint32_t *) ecalloc(fonts[code].height, sizeof(uint32_t));
//logging(DEBUG, "code:%d width:%d height:%d\n", code, width, height);
for (i = 0; i < fonts[code].height; i++)
fonts[code].bitmap[i] = glyph->bitmap[i];
if (code < UCS2_CHARS && width <= 64) {
listp = ecalloc(1, sizeof(struct glyph_list_t));
glyph = ecalloc(1, sizeof(struct glyph_t));
glyph->width = width;
glyph->height = height;
/* XXX: max width 64 pixels (wide char) */
glyph->bitmap = (bitmap_width_t *) ecalloc(glyph->height, sizeof(bitmap_width_t));
for (int i = 0; i < glyph->height; i++)
glyph->bitmap[i] = bdf_char->bitmap[i];
/* add new element to glyph list */
listp->code = code;
listp->glyph = glyph;
listp->next = *glist_head;
*glist_head = listp;
if (code == DEFAULT_CHAR)
*default_glyph = *glyph;
}
memset(glyph, 0, sizeof(struct bdf_glyph_t));
memset(bdf_char, 0, sizeof(struct bdf_char_t));
return BDF_CHAR;
}
else
sscanf(buf, "%X", &glyph->bitmap[count++]);
sscanf(buf, "%X", (unsigned int *) &bdf_char->bitmap[count++]);
return BDF_BITMAP;
}
void load_bdf_glyph(struct glyph_t *fonts, char *path)
bool load_bdf_glyph(struct glyph_list_t **glist_head, struct glyph_t *default_glyph, char *path)
{
int mode = BDF_HEADER;
char buf[BUFSIZE], *cp;
char lbuf[BUFSIZE], *cp;
FILE *fp;
struct bdf_t bdf;
struct bdf_glyph_t glyph;
struct bdf_header_t bdf_header;
struct bdf_char_t bdf_char;
fp = efopen(path, "r");
if ((fp = efopen(path, "r")) == NULL)
return false;
memset(&bdf, 0, sizeof(struct bdf_t));
memset(&glyph, 0, sizeof(struct bdf_glyph_t));
memset(&bdf_header, 0, sizeof(struct bdf_header_t));
memset(&bdf_char, 0, sizeof(struct bdf_char_t));
fprintf(stderr, "read bdf: %s\n", path);
logging(DEBUG, "read bdf: %s\n", path);
while (fgets(buf, BUFSIZE, fp) != NULL) {
if ((cp = strchr(buf, '\n')) != NULL)
while (fgets(lbuf, BUFSIZE, fp) != NULL) {
if ((cp = strchr(lbuf, '\n')) != NULL)
*cp = '\0';
//fprintf(stderr, "%s\n", buf);
//fprintf(stderr, "%s\n", lbuf);
if (mode == BDF_HEADER)
mode = read_header(buf, &bdf);
mode = read_header(lbuf, &bdf_header);
else if (mode == BDF_CHAR)
mode = read_char(buf, &glyph);
mode = read_char(lbuf, &bdf_char);
else if (mode == BDF_BITMAP)
mode = read_bitmap(fonts, buf, &bdf, &glyph);
mode = read_bitmap(glist_head, default_glyph, lbuf, &bdf_header, &bdf_char);
}
efclose(fp);
return true;
}

View file

@ -1,183 +0,0 @@
void fatal(char *str)
{
perror(str);
exit(EXIT_FAILURE);
}
FILE *efopen(char *path, char *mode)
{
FILE *fp;
errno = 0;
if ((fp = fopen(path, mode)) == NULL) {
fprintf(stderr, "cannot open \"%s\"\n", path);
fatal("fopen");
}
return fp;
}
void efclose(FILE *fp)
{
errno = 0;
if (fclose(fp) < 0)
fatal("fclose");
}
void *ecalloc(size_t nmemb, size_t size)
{
void *ptr;
errno = 0;
if ((ptr = calloc(nmemb, size)) == NULL)
fatal("calloc");
return ptr;
}
/* for yaft original font format: not used
CODE
WIDTH HEIGHT
BITMAP
BITMAP
BITMAP
CODE
WIDTH HEIGHT
....
void load_glyph(struct glyph_t *fonts, char *path)
{
int count = 0, state = 0;
char buf[BUFSIZE], *endp;
FILE *fp;
uint16_t code = DEFAULT_CHAR;
fp = efopen(path, "r");
while (fgets(buf, BUFSIZE, fp) != NULL) {
if (strlen(buf) == 0 || buf[0] == '#')
continue;
switch (state) {
case 0:
code = atoi(buf);
if (fonts[code].bitmap != NULL) {
free(fonts[code].bitmap);
fonts[code].bitmap = NULL;
}
state = 1;
break;
case 1:
sscanf(buf, "%hhu %hhu", &fonts[code].width, &fonts[code].height);
fonts[code].bitmap = (uint32_t *) emalloc(fonts[code].height * sizeof(uint32_t));
state = 2;
break;
case 2:
fonts[code].bitmap[count++] = strtol(buf, &endp, 16);
if (count >= fonts[code].height)
state = count = 0;
break;
default:
break;
}
}
efclose(fp);
}
*/
void load_alias(struct glyph_t *fonts, char *alias)
{
unsigned int dst, src;
char buf[BUFSIZE];
FILE *fp;
fp = efopen(alias, "r");
while (fgets(buf, BUFSIZE, fp) != NULL) {
if (strlen(buf) == 0 || buf[0] == '#')
continue;
sscanf(buf, "%X %X", &dst, &src);
if ((dst >= UCS2_CHARS) || (src >= UCS2_CHARS))
continue;
if (fonts[src].bitmap != NULL) {
fprintf(stderr, "swapped: use U+%.4X for U+%.4X\n", src, dst);
free(fonts[dst].bitmap);
fonts[dst].width = fonts[src].width;
fonts[dst].height = fonts[src].height;
fonts[dst].bitmap = fonts[src].bitmap;
}
}
efclose(fp);
}
void set_empty_glyph(struct glyph_t *fonts, uint32_t code, enum glyph_width_t wide)
{
fonts[code].width = fonts[DEFAULT_CHAR].width * wide;
fonts[code].height = fonts[DEFAULT_CHAR].height;
fonts[code].bitmap = (uint32_t *) ecalloc(fonts[DEFAULT_CHAR].height, sizeof(uint32_t));
}
void check_fonts(struct glyph_t *fonts)
{
if (fonts[DEFAULT_CHAR].bitmap == NULL) {
fprintf(stderr, "default glyph(U+%.4X) not found\n", DEFAULT_CHAR);
exit(EXIT_FAILURE);
}
if (fonts[SUBSTITUTE_HALF].bitmap == NULL) {
fprintf(stderr, "half substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_HALF);
set_empty_glyph(fonts, SUBSTITUTE_HALF, HALF);
}
if (fonts[SUBSTITUTE_WIDE].bitmap == NULL) {
fprintf(stderr, "wide substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_WIDE);
set_empty_glyph(fonts, SUBSTITUTE_WIDE, WIDE);
}
if (fonts[REPLACEMENT_CHAR].bitmap == NULL) {
fprintf(stderr, "replacement glyph(U+%.4X) not found, use empty glyph\n", REPLACEMENT_CHAR);
set_empty_glyph(fonts, REPLACEMENT_CHAR, HALF);
}
}
void dump_fonts(struct glyph_t *fonts)
{
int i, j, width;
uint8_t cell_width, cell_height;
cell_width = fonts[DEFAULT_CHAR].width;
cell_height = fonts[DEFAULT_CHAR].height;
fprintf(stdout,
"struct glyph_t {\n"
"\tuint32_t code;\n"
"\tuint8_t width;\n"
"\tuint%d_t bitmap[%d];\n"
"};\n\n", ((cell_width + BITS_PER_BYTE - 1) / BITS_PER_BYTE) * BITS_PER_BYTE * 2, cell_height);
fprintf(stdout, "enum {\n\tCELL_WIDTH = %d,\n\tCELL_HEIGHT = %d\n};\n\n",
cell_width, cell_height);
fprintf(stdout, "static const struct glyph_t glyphs[] = {\n");
for (i = 0; i < UCS2_CHARS; i++) {
width = wcwidth(i);
if ((width <= 0) /* not printable */
|| (fonts[i].bitmap == NULL) /* glyph not found */
|| (fonts[i].height != cell_height) /* invalid font height */
|| (fonts[i].width != (cell_width * width))) /* invalid font width */
continue;
fprintf(stdout, "\t{%d, %d, {", i, width);
for (j = 0; j < cell_height; j++)
fprintf(stdout, "0x%X%s", fonts[i].bitmap[j], (j == (cell_height - 1)) ? "": ", ");
fprintf(stdout, "}},\n");
}
fprintf(stdout, "};\n");
}

View file

@ -1,31 +1,201 @@
#include "mkfont_bdf.h"
#include "../conf.h"
#include "font.h"
#include "util.h"
#include "bdf.h"
/* mkfont_bdf functions */
bool map_glyph(struct glyph_t *font[],
struct glyph_list_t *glist_head, struct glyph_t *default_glyph)
{
int width, cell_width = 0, cell_height = 0;
struct glyph_t *glyph;
struct glyph_list_t *listp;
if (default_glyph == NULL) {
logging(ERROR, "default glyph(U+%.4X) not found\n", DEFAULT_CHAR);
return false;
}
cell_width = default_glyph->width;
cell_height = default_glyph->height;
for (listp = glist_head; listp != NULL; listp = listp->next) {
if (listp->code >= UCS2_CHARS)
continue;
width = wcwidth(listp->code);
glyph = listp->glyph;
if ((width <= 0) /* not printable */
|| (glyph->height != cell_height) /* invalid font height */
|| (glyph->width != (cell_width * width))) /* invalid font width */
continue;
font[listp->code] = glyph;
}
return true;
}
bool load_alias(struct glyph_t *font[], char *alias)
{
unsigned int dst, src;
char buf[BUFSIZE];
FILE *fp;
if ((fp = efopen(alias, "r")) == NULL)
return false;
while (fgets(buf, BUFSIZE, fp) != NULL) {
if (strlen(buf) == 0 || buf[0] == '#')
continue;
sscanf(buf, "%X %X", &dst, &src);
if ((dst >= UCS2_CHARS) || (src >= UCS2_CHARS))
continue;
if (font[src] != NULL && font[dst] != NULL) {
logging(DEBUG, "swapped: use U+%.4X for U+%.4X\n", src, dst);
//free(font[dst]->bitmap);
font[dst]->width = font[src]->width;
font[dst]->height = font[src]->height;
//font[dst]->bitmap = font[src]->bitmap;
memcpy(font[dst]->bitmap, font[src]->bitmap, sizeof(bitmap_width_t) * font[src]->height);
}
}
efclose(fp);
return true;
}
bool check_font(struct glyph_t **font, struct glyph_t *empty_half, struct glyph_t *empty_wide)
{
empty_half->bitmap = (bitmap_width_t *) ecalloc(font[DEFAULT_CHAR]->height, sizeof(bitmap_width_t));
empty_wide->bitmap = (bitmap_width_t *) ecalloc(font[DEFAULT_CHAR]->height, sizeof(bitmap_width_t));
if (!empty_half->bitmap || !empty_wide->bitmap)
return false;
empty_half->width = font[DEFAULT_CHAR]->width;
empty_wide->width = font[DEFAULT_CHAR]->width * WIDE;
empty_half->height = font[DEFAULT_CHAR]->height;
empty_wide->height = font[DEFAULT_CHAR]->height;
if (font[SUBSTITUTE_HALF] == NULL) {
logging(WARN, "half substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_HALF);
font[SUBSTITUTE_HALF] = empty_half;
}
if (font[SUBSTITUTE_WIDE] == NULL) {
logging(WARN, "wide substitute glyph(U+%.4X) not found, use empty glyph\n", SUBSTITUTE_WIDE);
font[SUBSTITUTE_HALF] = empty_wide;
}
if (font[REPLACEMENT_CHAR] == NULL) {
logging(WARN, "replacement glyph(U+%.4X) not found, use empty glyph\n", REPLACEMENT_CHAR);
font[SUBSTITUTE_HALF] = empty_half;
}
return true;
}
bool dump_font(struct glyph_t *font[])
{
int i, j, width, int_type;
uint8_t cell_width, cell_height;
cell_width = font[DEFAULT_CHAR]->width;
cell_height = font[DEFAULT_CHAR]->height;
int_type = my_ceil(cell_width, BITS_PER_BYTE) /* minimum byte for containing half glyph */
* 2 /* minimum byte for containing wide glyph */
* BITS_PER_BYTE; /* minimum bits for containing wide glyph */
/* int_type: 16, 32, 48, 64, 80... */
if (int_type == 48) { /* uint48_t does not exist */
int_type = 64;
} else if (int_type >= 80) {
logging(ERROR, "BDF width too large (uint%d_t does not exist)\n", int_type);
return false;
}
fprintf(stdout,
"struct glyph_t {\n"
"\tuint32_t code;\n"
"\tuint8_t width;\n"
"\tuint%d_t bitmap[%d];\n"
"};\n\n", int_type, cell_height);
fprintf(stdout, "enum {\n\tCELL_WIDTH = %d,\n\tCELL_HEIGHT = %d\n};\n\n",
cell_width, cell_height);
fprintf(stdout, "static const struct glyph_t glyphs[] = {\n");
for (i = 0; i < UCS2_CHARS; i++) {
width = wcwidth(i);
if (font[i] == NULL) /* glyph not found */
continue;
fprintf(stdout, "\t{%d, %d, {", i, width);
for (j = 0; j < cell_height; j++)
fprintf(stdout, "0x%X%s", (unsigned int) font[i]->bitmap[j], (j == (cell_height - 1)) ? "": ", ");
fprintf(stdout, "}},\n");
}
fprintf(stdout, "};\n");
return true;
}
void cleanup(struct glyph_list_t *glist_head, struct glyph_t *empty_half, struct glyph_t *empty_wide)
{
struct glyph_list_t *listp, *next;
for (listp = glist_head; listp != NULL; listp = next) {
next = listp->next;
free(listp->glyph->bitmap);
free(listp->glyph);
free(listp);
}
free(empty_half->bitmap);
free(empty_wide->bitmap);
}
int main(int argc, char *argv[])
{
int i;
struct glyph_t fonts[UCS2_CHARS];
struct glyph_list_t *glist_head = NULL;
struct glyph_t *font[UCS2_CHARS], default_glyph, empty_wide, empty_half;
setlocale(LC_ALL, ""); /* set current locale for wcwidth() */
if (!setlocale(LC_ALL, "")) /* set current locale for wcwidth() */
logging(WARN, "setlocale() failed\n");
if (argc < 3) {
fprintf(stderr, "usage: ./mkfont ALIAS BDF1 [BDF2] [BDF3] ...\n");
exit(EXIT_FAILURE);
logging(FATAL, "usage: ./mkfont ALIAS BDF1 [BDF2] [BDF3] ...\n");
return EXIT_FAILURE;
}
for (i = 0; i < UCS2_CHARS; i++)
fonts[i].bitmap = NULL;
for (int i = 0; i < UCS2_CHARS; i++)
font[i] = NULL;
for (i = 2; i < argc; i++)
load_bdf_glyph(fonts, argv[i]);
for (int i = 2; i < argc; i++)
load_bdf_glyph(&glist_head, &default_glyph, argv[i]);
load_alias(fonts, argv[1]);
if (!map_glyph(font, glist_head, &default_glyph)) {
logging(FATAL, "map_glyph() failed\n");
goto err_occured;
}
check_fonts(fonts);
if (!load_alias(font, argv[1]))
logging(WARN, "font alias does not work\n");
dump_fonts(fonts);
if (!check_font(font, &empty_half, &empty_wide)) {
logging(FATAL, "map_glyph() failed\n");
goto err_occured;
}
if (!dump_font(font)) {
logging(FATAL, "map_glyph() failed\n");
goto err_occured;
}
cleanup(glist_head, &empty_half, &empty_wide);
return EXIT_SUCCESS;
err_occured:
cleanup(glist_head, &empty_half, &empty_wide);
return EXIT_FAILURE;
}

View file

@ -3,6 +3,7 @@
#include <ctype.h>
#include <errno.h>
#include <locale.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
@ -10,6 +11,8 @@
#include <string.h>
#include <wchar.h>
typedef uint64_t bitmap_width_t;
enum char_code {
/* 7 bit control char */
BEL = 0x07, BS = 0x08, HT = 0x09,
@ -25,7 +28,7 @@ enum misc {
BUFSIZE = 1024, /* read, esc, various buffer size */
UCS2_CHARS = 0x10000, /* number of UCS2 glyph */
DEFAULT_CHAR = SPACE, /* used for erase char, cell_size */
MAX_HEIGHT = 32,
MAX_HEIGHT = 64,
BDF_HEADER = 0,
BDF_CHAR = 1,
BDF_BITMAP = 2,
@ -51,10 +54,16 @@ enum glyph_width_t {
struct glyph_t {
uint8_t width, height;
uint32_t *bitmap;
bitmap_width_t *bitmap;
};
struct bdf_t {
struct glyph_list_t {
uint32_t code;
struct glyph_t *glyph;
struct glyph_list_t *next;
};
struct bdf_header_t {
int bbw, bbh, bbx, bby;
int ascent, descent;
int default_char;
@ -63,11 +72,11 @@ struct bdf_t {
char charset[BUFSIZE];
};
struct bdf_glyph_t {
struct bdf_char_t {
int bbw, bbh, bbx, bby;
int dwidth;
int encoding;
uint32_t bitmap[MAX_HEIGHT];
bitmap_width_t bitmap[MAX_HEIGHT];
};
int convert_table[UCS2_CHARS];

71
tools/util.h Normal file
View file

@ -0,0 +1,71 @@
/* wrapper of C functions */
enum loglevel_t {
DEBUG = 0,
WARN,
ERROR,
FATAL,
};
void logging(enum loglevel_t loglevel, char *format, ...)
{
va_list arg;
static const char *loglevel2str[] = {
[DEBUG] = "DEBUG",
[WARN] = "WARN",
[ERROR] = "ERROR",
[FATAL] = "FATAL",
};
/* debug message is available on verbose mode */
if ((loglevel == DEBUG) && (VERBOSE == false))
return;
fprintf(stderr, ">>%s<<\t", loglevel2str[loglevel]);
va_start(arg, format);
vfprintf(stderr, format, arg);
va_end(arg);
}
FILE *efopen(const char *path, char *mode)
{
FILE *fp;
errno = 0;
if ((fp = fopen(path, mode)) == NULL) {
logging(ERROR, "couldn't open \"%s\"\n", path);
logging(ERROR, "fopen: %s\n", strerror(errno));
}
return fp;
}
int efclose(FILE *fp)
{
int ret;
errno = 0;
if ((ret = fclose(fp)) < 0)
logging(ERROR, "fclose: %s\n", strerror(errno));
return ret;
}
void *ecalloc(size_t nmemb, size_t size)
{
void *ptr;
errno = 0;
if ((ptr = calloc(nmemb, size)) == NULL)
logging(ERROR, "calloc: %s\n", strerror(errno));
return ptr;
}
int my_ceil(int val, int div)
{
if (div == 0)
//return 0;
return -1;
else
return (val + div - 1) / div;
}