rtoss

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/ @ 319  →  / @ 320
/bdf2ttf/src/bdf.c
@@ -44,16 +44,16 @@
 
typedef struct
{
char* name;
unsigned char width;
char* name;
unsigned char width;
} width_table_t;
 
static width_table_t cell_width_table[] = {
{ "JISX0208", 2 },
{ "JISX0212", 2 },
{ "JISX0213", 2 },
{ "KSX1001", 2 },
{ NULL, 0 },
{ "JISX0208", 2 },
{ "JISX0212", 2 },
{ "JISX0213", 2 },
{ "KSX1001", 2 },
{ NULL, 0 },
};
 
static int bdf_load_fh(bdf_t* font, FILE* fp);
@@ -67,791 +67,791 @@
static void chomp(char* str);
static int check_bdfsize(char* filename);
 
bdf_t*
bdf_t*
bdf_open()
{
bdf_t *font;
bdf_t *font;
 
font = (bdf_t*)calloc(1, sizeof(*font));
font->indexFirst = -1;
font->indexLast = -1;
memset(font->cell_width, 1, sizeof(font->cell_width));
return font;
font = (bdf_t*)calloc(1, sizeof(*font));
font->indexFirst = -1;
font->indexLast = -1;
memset(font->cell_width, 1, sizeof(font->cell_width));
return font;
}
 
void
void
bdf_close(bdf_t *font)
{
if (font)
{
int i;
if (font)
{
int i;
 
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
if (font->glyph[i])
glyph_close(font->glyph[i]);
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
if (font->glyph[i])
glyph_close(font->glyph[i]);
}
free(font);
}
free(font);
}
}
 
bdf_glyph_t*
bdf_glyph_t*
bdf_get_glyph(bdf_t* font, int id)
{
return font ? font->glyph[id] : NULL;
return font ? font->glyph[id] : NULL;
}
 
int
int
bdf_get_pixel_glyph(bdf_glyph_t* glyph, int x, int y)
{
if (glyph && x >= 0 && y >= 0
&& x < glyph->bbx.width
&& y < glyph->bbx.height
&& glyph->bitmap
)
{
int base = RAS_BYTE(glyph->bbx.width) * y;
return glyph->bitmap[base + (x / 8)] & (0x80 >> (x % 8))
? 1 : 0;
}
return -1;
if (glyph && x >= 0 && y >= 0
&& x < glyph->bbx.width
&& y < glyph->bbx.height
&& glyph->bitmap
)
{
int base = RAS_BYTE(glyph->bbx.width) * y;
return glyph->bitmap[base + (x / 8)] & (0x80 >> (x % 8))
? 1 : 0;
}
return -1;
}
 
int
int
bdf_get_pixel(bdf_t * font, int id, int x, int y)
{
if (font)
{
bdf_glyph_t* glyph = bdf_get_glyph(font, id);
return bdf_get_pixel_glyph(glyph, x, y);
}
return -1;
if (font)
{
bdf_glyph_t* glyph = bdf_get_glyph(font, id);
return bdf_get_pixel_glyph(glyph, x, y);
}
return -1;
}
 
static bdf_glyph_t *
static bdf_glyph_t *
glyph_open(int width, int height)
{
bdf_glyph_t * glyph;
size_t size;
bdf_glyph_t * glyph;
size_t size;
 
glyph = (bdf_glyph_t*)calloc(1, sizeof(*glyph));
size = RAS_BYTE(width) * height;
glyph->bitmap = (bdf_byte_t*)calloc(size, sizeof(bdf_byte_t));
return glyph;
glyph = (bdf_glyph_t*)calloc(1, sizeof(*glyph));
size = RAS_BYTE(width) * height;
glyph->bitmap = (bdf_byte_t*)calloc(size, sizeof(bdf_byte_t));
return glyph;
}
 
static void
static void
glyph_close(bdf_glyph_t *glyph)
{
if (glyph)
{
if (glyph->bitmap)
free(glyph->bitmap);
free(glyph);
}
if (glyph)
{
if (glyph->bitmap)
free(glyph->bitmap);
free(glyph);
}
}
 
static char*
static char*
skipspace(char* str)
{
while (isspace(*str))
++str;
return str;
while (isspace(*str))
++str;
return str;
}
 
static char*
static char*
iscmd(char* target, char* keyword)
{
size_t len = strlen(keyword);
return strncmp(target, keyword, len) == 0 && !isgraph(target[len])
size_t len = strlen(keyword);
return strncmp(target, keyword, len) == 0 && !isgraph(target[len])
? skipspace(target + len) : NULL;
}
 
void
void
chomp(char* str)
{
int len = strlen(str) - 1;
for (; len >= 0 && isspace(str[len]); --len)
str[len] = '\0';
int len = strlen(str) - 1;
for (; len >= 0 && isspace(str[len]); --len)
str[len] = '\0';
}
 
int
int
atoi_next(char** str)
{
int retval = atoi(*str);
while (isdigit(**str))
++*str;
*str = skipspace(*str);
return retval;
int retval = atoi(*str);
while (isdigit(**str))
++*str;
*str = skipspace(*str);
return retval;
}
 
int
int
hex2n(char ch)
{
if (ch >= '0' && ch <= '9')
return (int)(ch - '0');
else if (ch >= 'a' && ch <= 'f')
return (int)(ch - 'a' + 10);
else if (ch >= 'A' && ch <= 'F')
return (int)(ch - 'A' + 10);
else
return 0;
if (ch >= '0' && ch <= '9')
return (int)(ch - '0');
else if (ch >= 'a' && ch <= 'f')
return (int)(ch - 'a' + 10);
else if (ch >= 'A' && ch <= 'F')
return (int)(ch - 'A' + 10);
else
return 0;
}
 
int
int
hex2byte(char *str)
{
return (hex2n(str[0]) << 4) + hex2n(str[1]);
return (hex2n(str[0]) << 4) + hex2n(str[1]);
}
 
void
void
count_validglyph(bdf_t* font)
{
int i;
int i;
 
font->numGlyph = 0;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
if (font->glyph[i])
{
font->glyph[i]->id = font->numGlyph;
++font->numGlyph;
font->numGlyph = 0;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
if (font->glyph[i])
{
font->glyph[i]->id = font->numGlyph;
++font->numGlyph;
 
if (font->indexFirst < 0)
font->indexFirst = i;
font->indexLast = i;
}
if (font->indexFirst < 0)
font->indexFirst = i;
font->indexLast = i;
}
}
 
static char*
static char*
parse_FONT_backend(char* cmd, int c)
{
/* int c = 13; */
int len;
/* int c = 13; */
int len;
 
while (c && *cmd)
while (c && *cmd)
if (*cmd++ == '-')
--c;
len = strlen(cmd);
if (len > 0)
{
int i;
 
for (i = 0; i < len; ++i)
--c;
len = strlen(cmd);
if (len > 0)
{
if (cmd[i] == '.')
{
/* Remove year notification, and plane 0 */
int j, n;
int i;
 
for (j = i + 1; cmd[j] != '\0' && cmd[j] != '-'; ++j)
;
if (cmd[j] == '-' && (n = atoi(&cmd[j + 1])) > 0)
for (i = 0; i < len; ++i)
{
while (cmd[j] != '\0')
cmd[i++] = cmd[j++];
if (cmd[i] == '.')
{
/* Remove year notification, and plane 0 */
int j, n;
 
for (j = i + 1; cmd[j] != '\0' && cmd[j] != '-'; ++j)
;
if (cmd[j] == '-' && (n = atoi(&cmd[j + 1])) > 0)
{
while (cmd[j] != '\0')
cmd[i++] = cmd[j++];
}
cmd[i] = '\0';
break;
}
cmd[i] = toupper(cmd[i]);
}
cmd[i] = '\0';
break;
}
cmd[i] = toupper(cmd[i]);
/* Remove prefix "ISO", if exists. */
if (strncmp(cmd, "ISO", 3) == 0)
cmd += 3;
}
/* Remove prefix "ISO", if exists. */
if (strncmp(cmd, "ISO", 3) == 0)
cmd += 3;
}
return cmd;
return cmd;
}
 
static char*
static char*
parse_FONT(char* cmd)
{
return parse_FONT_backend(cmd, 13);
return parse_FONT_backend(cmd, 13);
}
 
static char*
static char*
removeQuote(char* str)
{
size_t len;
char *noQuotes;
size_t i, j;
len = strlen(str);
j = 0;
noQuotes = (char*)malloc(str);
if(str[0] != '"') {
noQuotes[j++] = str[0];
}
for(i = 1; i < len; i++){
if(str[i] == '"' && str[i-1] != '\\')
continue;
noQuotes[j++] = str[i];
}
return noQuotes;
size_t len;
char *noQuotes;
size_t i, j;
len = strlen(str);
j = 0;
noQuotes = (char*)malloc(str);
if(str[0] != '"') {
noQuotes[j++] = str[0];
}
for(i = 1; i < len; i++){
if(str[i] == '"' && str[i-1] != '\\')
continue;
noQuotes[j++] = str[i];
}
return noQuotes;
}
 
static ucsconv_t*
static ucsconv_t*
init_conv(char* encname, ucsconv_t** pconv)
{
ucsconv_t *conv;
ucsconv_t *conv;
 
if (conv = ucsconv_open())
{
int i;
char *postfix[] = { ".TXT", ".WIN.TXT" };
int loaded = 0;
if (conv = ucsconv_open())
{
int i;
char *postfix[] = { ".TXT", ".WIN.TXT" };
int loaded = 0;
 
/* Generate encode table filename */
for (i = 0; i < elementof(postfix); ++i)
{
int n;
char encfile[_MAX_PATH];
char *env = getenv("UCSTABLEDIR");
sprintf(encfile, "%s/%s%s", env ? env : UCS_TABLEDIR,
encname, postfix[i]);
n = ucsconv_load(conv, encfile);
loaded += n;
/* Generate encode table filename */
for (i = 0; i < elementof(postfix); ++i)
{
int n;
char encfile[_MAX_PATH];
char *env = getenv("UCSTABLEDIR");
sprintf(encfile, "%s/%s%s", env ? env : UCS_TABLEDIR,
encname, postfix[i]);
n = ucsconv_load(conv, encfile);
loaded += n;
#if 0
printf (" [%d] %s (%d)\n", i, encfile, n);
printf (" [%d] %s (%d)\n", i, encfile, n);
#endif
}
if (loaded == 0)
{
ucsconv_close(conv);
conv = NULL;
}
}
if (loaded == 0)
 
if (pconv)
{
ucsconv_close(conv);
conv = NULL;
if (*pconv)
ucsconv_close(*pconv);
*pconv = conv;
}
}
 
if (pconv)
{
if (*pconv)
ucsconv_close(*pconv);
*pconv = conv;
}
return conv;
return conv;
}
 
/*
* Return 1 if succeeded.
* Return -SIZE if failed.
*/
int
int
bdf_load_fh(bdf_t * font, FILE* fp)
{
bdf_glyph_t tmp, *ptmp = NULL;
int predat = 1;
int encnum = 0;
int ras = 0, line = 0;
char buf[8192], *cmd;
ucsconv_t* conv = NULL;
unsigned char cell_width = 1;
bdf_glyph_t tmp, *ptmp = NULL;
int predat = 1;
int encnum = 0;
int ras = 0, line = 0;
char buf[8192], *cmd;
ucsconv_t* conv = NULL;
unsigned char cell_width = 1;
 
memset(&tmp, 0, sizeof(tmp));
while (fgets(buf, sizeof(buf), fp))
{
chomp(buf);
if (predat)
memset(&tmp, 0, sizeof(tmp));
while (fgets(buf, sizeof(buf), fp))
{
/* Pre data section parser */
if (cmd = iscmd(buf, "CHARS"))
predat = 0;
else if (cmd = iscmd(buf, "SIZE"))
{
int size = atoi_next(&cmd);
if (font->size != size)
chomp(buf);
if (predat)
{
if (font->verbose > 0)
fprintf(stderr,
"WARNING: SIZE was changed (%d -> %d)\n",
font->size, size);
if (font->size < size)
font->size = size;
}
}
else if (cmd = iscmd(buf, "PIXEL_SIZE"))
{
int pixel_size = atoi_next(&cmd);
font->pixel_size = pixel_size;
}
else if (cmd = iscmd(buf, "FONTBOUNDINGBOX"))
{
font->bbx.width = atoi_next(&cmd);
font->bbx.height = atoi_next(&cmd);
font->bbx.offset.x = atoi_next(&cmd);
font->bbx.offset.y = atoi_next(&cmd);
}
else if (cmd = iscmd(buf, "FONT"))
{
if (cmd = parse_FONT(cmd))
{
width_table_t *p;
/* Pre data section parser */
if (cmd = iscmd(buf, "CHARS"))
predat = 0;
else if (cmd = iscmd(buf, "SIZE"))
{
int size = atoi_next(&cmd);
if (font->size != size)
{
if (font->verbose > 0)
fprintf(stderr,
"WARNING: SIZE was changed (%d -> %d)\n",
font->size, size);
if (font->size < size)
font->size = size;
}
}
else if (cmd = iscmd(buf, "PIXEL_SIZE"))
{
int pixel_size = atoi_next(&cmd);
font->pixel_size = pixel_size;
}
else if (cmd = iscmd(buf, "FONTBOUNDINGBOX"))
{
font->bbx.width = atoi_next(&cmd);
font->bbx.height = atoi_next(&cmd);
font->bbx.offset.x = atoi_next(&cmd);
font->bbx.offset.y = atoi_next(&cmd);
}
else if (cmd = iscmd(buf, "FONT"))
{
if (cmd = parse_FONT(cmd))
{
width_table_t *p;
 
TRACE("bdf_load: [#F] encoding is %s\n", cmd);
init_conv(cmd, &conv);
for (p = cell_width_table; p->name != NULL; ++p)
if (strcmp(p->name, cmd) == 0)
break;
if (p->name != NULL)
cell_width = p->width;
TRACE("bdf_load: [#F] encoding is %s\n", cmd);
init_conv(cmd, &conv);
for (p = cell_width_table; p->name != NULL; ++p)
if (strcmp(p->name, cmd) == 0)
break;
if (p->name != NULL)
cell_width = p->width;
}
else if (conv)
{
TRACE("bdf_load: disable usc #F\n");
ucsconv_close(conv);
conv = NULL;
}
}
else if (cmd = iscmd(buf, "CHARSET_REGISTRY"))
{
char* charset_name = removeQuote(cmd);
TRACE("bdf_load: get CHARSET_REGISTRY = %s\n", charset_name);
if ((cmd = parse_FONT_backend(charset_name, 0)) && !conv)
{
width_table_t *p;
 
TRACE("bdf_load: [#CR] encoding is %s\n", cmd);
init_conv(cmd, &conv);
for (p = cell_width_table; p->name != NULL; ++p)
if (strcmp(p->name, cmd) == 0)
break;
if (p->name != NULL)
cell_width = p->width;
}
/*else if (conv)
{
TRACE("bdf_load: disable usc #CR\n");
ucsconv_close(conv);
conv = NULL;
}*/
free(charset_name);
}
else if (cmd = iscmd(buf, "FONT_ASCENT"))
font->ascent = atoi(cmd);
else if (cmd = iscmd(buf, "FONT_DESCENT"))
font->descent = atoi(cmd);
}
else if (conv)
else if (ptmp)
{
TRACE("bdf_load: disable usc #F\n");
ucsconv_close(conv);
conv = NULL;
/* Parse bitmap */
if (cmd = iscmd(buf, "ENDCHAR"))
{
if (encnum >= 0)
{
if (font->glyph[encnum])
glyph_close(font->glyph[encnum]);
font->glyph[encnum] = ptmp;
//font->cell_width[encnum] = cell_width;
font->glyph_dwidth[encnum] = ptmp->dwidth.x;
font->cell_width[encnum] = ptmp->dwidth.x > (font->size / 2)
? 2 : 1;
}
else
glyph_close(ptmp);
ptmp = NULL;
}
else
{
int i;
bdf_byte_t *p = ptmp->bitmap + ras * line;
#if 0
if (line == 5)
{
fprintf(stderr, "(%s)", buf);
for (i = 0; i < ras; ++i)
fprintf(stderr, " %02X", hex2byte(buf + i * 2));
fprintf(stderr, "\n");
}
#endif
for (i = 0; i < ras; ++i)
p[i] = hex2byte(buf + i * 2);
++line;
}
}
}
else if (cmd = iscmd(buf, "CHARSET_REGISTRY"))
{
char* charset_name = removeQuote(cmd);
TRACE("bdf_load: get CHARSET_REGISTRY = %s\n", charset_name);
if ((cmd = parse_FONT_backend(charset_name, 0)) && !conv)
/* Parse font glyph headers */
else if (cmd = iscmd(buf, "ENCODING"))
{
width_table_t *p;
/* Convert encondig in UCS. When encondig wasn't converted, use
* original value */
encnum = atoi(cmd);
if (conv)
{
int convnum = (int)ucsconv_toUCS(conv, (ucschar_t)encnum);
#if 0
TRACE("bdf_load: ucs %04x => %04x\n", encnum, convnum);
#endif
 
TRACE("bdf_load: [#CR] encoding is %s\n", cmd);
init_conv(cmd, &conv);
for (p = cell_width_table; p->name != NULL; ++p)
if (strcmp(p->name, cmd) == 0)
break;
if (p->name != NULL)
cell_width = p->width;
if (convnum)
encnum = convnum;
else
{
char *filename = "STREAM";
if (font->loadingFilename)
filename = font->loadingFilename;
if (font->verbose > 0)
{
fprintf(stderr, "%04x can't convert to UCS (%s)\n",
encnum, filename);
}
encnum = -1;
}
}
}
/*else if (conv)
else if (cmd = iscmd(buf, "SWIDTH"))
{
TRACE("bdf_load: disable usc #CR\n");
ucsconv_close(conv);
conv = NULL;
}*/
free(charset_name);
}
else if (cmd = iscmd(buf, "FONT_ASCENT"))
font->ascent = atoi(cmd);
else if (cmd = iscmd(buf, "FONT_DESCENT"))
font->descent = atoi(cmd);
}
else if (ptmp)
{
/* Parse bitmap */
if (cmd = iscmd(buf, "ENDCHAR"))
{
if (encnum >= 0)
tmp.swidth.x = atoi_next(&cmd);
tmp.swidth.y = atoi_next(&cmd);
}
else if (cmd = iscmd(buf, "DWIDTH"))
{
if (font->glyph[encnum])
glyph_close(font->glyph[encnum]);
font->glyph[encnum] = ptmp;
//font->cell_width[encnum] = cell_width;
font->glyph_dwidth[encnum] = ptmp->dwidth.x;
font->cell_width[encnum] = ptmp->dwidth.x > (font->size / 2)
? 2 : 1;
tmp.dwidth.x = atoi_next(&cmd);
tmp.dwidth.y = atoi_next(&cmd);
}
else
glyph_close(ptmp);
ptmp = NULL;
}
else
{
int i;
bdf_byte_t *p = ptmp->bitmap + ras * line;
#if 0
if (line == 5)
else if (cmd = iscmd(buf, "BBX"))
{
fprintf(stderr, "(%s)", buf);
for (i = 0; i < ras; ++i)
fprintf(stderr, " %02X", hex2byte(buf + i * 2));
fprintf(stderr, "\n");
tmp.bbx.width = atoi_next(&cmd);
tmp.bbx.height = atoi_next(&cmd);
tmp.bbx.offset.x = atoi_next(&cmd);
tmp.bbx.offset.y = atoi_next(&cmd);
}
#endif
for (i = 0; i < ras; ++i)
p[i] = hex2byte(buf + i * 2);
++line;
}
}
/* Parse font glyph headers */
else if (cmd = iscmd(buf, "ENCODING"))
{
/* Convert encondig in UCS. When encondig wasn't converted, use
* original value */
encnum = atoi(cmd);
if (conv)
{
int convnum = (int)ucsconv_toUCS(conv, (ucschar_t)encnum);
#if 0
TRACE("bdf_load: ucs %04x => %04x\n", encnum, convnum);
#endif
else if (cmd = iscmd(buf, "BITMAP"))
{
ptmp = glyph_open(tmp.bbx.width, tmp.bbx.height);
tmp.bitmap = ptmp->bitmap;
*ptmp = tmp;
 
if (convnum)
encnum = convnum;
else
{
char *filename = "STREAM";
if (font->loadingFilename)
filename = font->loadingFilename;
if (font->verbose > 0)
{
fprintf(stderr, "%04x can't convert to UCS (%s)\n",
encnum, filename);
}
encnum = -1;
ras = RAS_BYTE(ptmp->bbx.width);
line = 0;
}
}
}
else if (cmd = iscmd(buf, "SWIDTH"))
if (font->pixel_size == 0)
{
tmp.swidth.x = atoi_next(&cmd);
tmp.swidth.y = atoi_next(&cmd);
font->pixel_size = font->size;
fprintf(stderr, "bdf_load: PIXEL_SIZE was not found, use %d\n", font->size);
}
else if (cmd = iscmd(buf, "DWIDTH"))
/* Remove a glyph for charcode 0 */
if (font->glyph[0])
{
tmp.dwidth.x = atoi_next(&cmd);
tmp.dwidth.y = atoi_next(&cmd);
glyph_close(font->glyph[0]);
font->glyph[0] = NULL;
}
else if (cmd = iscmd(buf, "BBX"))
{
tmp.bbx.width = atoi_next(&cmd);
tmp.bbx.height = atoi_next(&cmd);
tmp.bbx.offset.x = atoi_next(&cmd);
tmp.bbx.offset.y = atoi_next(&cmd);
}
else if (cmd = iscmd(buf, "BITMAP"))
{
ptmp = glyph_open(tmp.bbx.width, tmp.bbx.height);
tmp.bitmap = ptmp->bitmap;
*ptmp = tmp;
 
ras = RAS_BYTE(ptmp->bbx.width);
line = 0;
}
}
if (font->pixel_size == 0)
{
font->pixel_size = font->size;
fprintf(stderr, "bdf_load: PIXEL_SIZE was not found, use %d\n", font->size);
}
/* Remove a glyph for charcode 0 */
if (font->glyph[0])
{
glyph_close(font->glyph[0]);
font->glyph[0] = NULL;
}
/* Caliculate glyph statistics information */
count_validglyph(font);
return 1;
/* Caliculate glyph statistics information */
count_validglyph(font);
return 1;
}
 
int
int
bdf_load(bdf_t* font, char* filename)
{
FILE *fp;
int retval = 0;
FILE *fp;
int retval = 0;
 
if (!font)
if (!font)
return retval;
fp = fopen(filename, "rb");
if (fp)
{
font->loadingFilename = filename;
retval = bdf_load_fh(font, fp);
font->loadingFilename = NULL;
fclose(fp);
}
return retval;
fp = fopen(filename, "rb");
if (fp)
{
font->loadingFilename = filename;
retval = bdf_load_fh(font, fp);
font->loadingFilename = NULL;
fclose(fp);
}
return retval;
}
 
/*****************************************************************************
* BDF2
*****************************************************************************/
 
bdf2_t*
bdf2_t*
bdf2_open()
{
bdf2_t *font;
int i;
bdf2_t *font;
int i;
 
font = (bdf2_t*)calloc(1, sizeof(*font));
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
font->glyph_id[i] = -1;
font->glyph_width[i] = 1;
}
font = (bdf2_t*)calloc(1, sizeof(*font));
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
font->glyph_id[i] = -1;
font->glyph_width[i] = 1;
}
 
return font;
return font;
}
 
void
void
bdf2_close(bdf2_t* font)
{
if (!font)
if (!font)
return;
while (font->list)
{
bdf_list_t *next = font->list->next;
 
bdf_close(font->list->bdf);
free(font->list);
font->list = next;
}
if (font->sizelist)
{
free(font->sizelist);
font->sizelist = NULL;
}
free(font);
return;
while (font->list)
{
bdf_list_t *next = font->list->next;
 
bdf_close(font->list->bdf);
free(font->list);
font->list = next;
}
if (font->sizelist)
{
free(font->sizelist);
font->sizelist = NULL;
}
free(font);
return;
}
 
int
int
check_bdfsize(char* filename)
{
FILE *fp;
FILE *fp;
 
fp = fopen(filename, "rb");
if (!fp)
return 0;
else
{
int pixel_size = 0;
int size = 0;
char buf[8192], *cmd;
fp = fopen(filename, "rb");
if (!fp)
return 0;
else
{
int pixel_size = 0;
int size = 0;
char buf[8192], *cmd;
 
while (fgets(buf, sizeof(buf), fp))
{
chomp(buf);
if (cmd = iscmd(buf, "SIZE"))
size = atoi_next(&cmd);
while (fgets(buf, sizeof(buf), fp))
{
chomp(buf);
if (cmd = iscmd(buf, "SIZE"))
size = atoi_next(&cmd);
#ifdef USE_PIXELSIZE
else if (cmd = iscmd(buf, "PIXEL_SIZE"))
{
pixel_size = atoi_next(&cmd);
break;
}
else if (cmd = iscmd(buf, "PIXEL_SIZE"))
{
pixel_size = atoi_next(&cmd);
break;
}
#endif
}
fclose(fp);
}
fclose(fp);
#ifdef USE_PIXELSIZE
return pixel_size > 0 ? pixel_size : size;
return pixel_size > 0 ? pixel_size : size;
#else
return size;
return size;
#endif
}
}
}
 
int QSORT_CALLBACK
int QSORT_CALLBACK
numsort(const void* a, const void* b)
{
int *pa = (int*)a;
int *pb = (int*)b;
int *pa = (int*)a;
int *pb = (int*)b;
 
return *pa - *pb;
return *pa - *pb;
}
 
int
int
bdf2_load(bdf2_t* font, char* filename)
{
int size;
bdf_t *bdf;
int newsize = 0;
int retval;
int i;
int size;
bdf_t *bdf;
int newsize = 0;
int retval;
int i;
 
size = check_bdfsize(filename);
TRACE("bdf2_load: size=%d\n", size);
if (size <= 0)
{
fprintf(stderr, "check_bdfsize(%s) returns %d\n", filename, size);
return 0;
}
bdf = bdf2_get_bdf1(font, size);
/*
* If not exists BDF in that size, create new and set no zero value for
* newsize
*/
if (!bdf)
{
bdf_list_t *list;
size = check_bdfsize(filename);
TRACE("bdf2_load: size=%d\n", size);
if (size <= 0)
{
fprintf(stderr, "check_bdfsize(%s) returns %d\n", filename, size);
return 0;
}
bdf = bdf2_get_bdf1(font, size);
/*
* If not exists BDF in that size, create new and set no zero value for
* newsize
*/
if (!bdf)
{
bdf_list_t *list;
 
list = (bdf_list_t*)malloc(sizeof(*list));
list->bdf = bdf = bdf_open();
bdf->verbose = font->verbose;
list->next = font->list;
font->list = list;
++font->count;
newsize = size;
TRACE("bdf2_load: create a font size %d\n", newsize);
}
retval = bdf_load(bdf, filename);
if (retval != 1)
{
/* Unexpected error! This'll not be caused */
fprintf(stderr, "bdf2_load: bdf_load(%p, %s) return %d\n",
bdf, filename, retval);
return retval;
}
list = (bdf_list_t*)malloc(sizeof(*list));
list->bdf = bdf = bdf_open();
bdf->verbose = font->verbose;
list->next = font->list;
font->list = list;
++font->count;
newsize = size;
TRACE("bdf2_load: create a font size %d\n", newsize);
}
retval = bdf_load(bdf, filename);
if (retval != 1)
{
/* Unexpected error! This'll not be caused */
fprintf(stderr, "bdf2_load: bdf_load(%p, %s) return %d\n",
bdf, filename, retval);
return retval;
}
 
/* Check glyph existance */
font->numGlyph = 0;
font->indexFirst = -1;
font->indexLast = -1;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
bdf_glyph_t *g = bdf_get_glyph(bdf, i);
if (g)
/* Check glyph existance */
font->numGlyph = 0;
font->indexFirst = -1;
font->indexLast = -1;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
font->glyph_flag[i] |= BDF2GF_AVAILABLE;
bdf_glyph_t *g = bdf_get_glyph(bdf, i);
if (g)
{
font->glyph_flag[i] |= BDF2GF_AVAILABLE;
#ifdef USE_FLEXIBLE_GLYPHWIDTH
if (font->glyph_width[i] != 2 && g->bbx.width > (size / 2))
{
/* Multi cell glyph has always 2 cell */
font->glyph_width[i] = 2;
font->has_multicell = 1;
//TRACE("i=%d s=%d w=%d\n", i, size, g->bbx.width);
}
if (font->glyph_width[i] != 2 && g->bbx.width > (size / 2))
{
/* Multi cell glyph has always 2 cell */
font->glyph_width[i] = 2;
font->has_multicell = 1;
//TRACE("i=%d s=%d w=%d\n", i, size, g->bbx.width);
}
#else
font->glyph_width[i] = 1;
font->glyph_width[i] = 1;
#endif
}
if (font->glyph_flag[i] & BDF2GF_AVAILABLE)
{
font->glyph_id[i] = font->numGlyph;
++font->numGlyph;
if (font->indexFirst < 0)
font->indexFirst = i;
font->indexLast = i;
}
else
font->glyph_id[i] = -1;
}
if (font->glyph_flag[i] & BDF2GF_AVAILABLE)
TRACE("bdf2_load: numGlyph=%d\n", font->numGlyph);
/* Add size in the sizelist */
if (newsize > 0)
{
font->glyph_id[i] = font->numGlyph;
++font->numGlyph;
if (font->indexFirst < 0)
font->indexFirst = i;
font->indexLast = i;
font->sizelist = (int*)realloc(font->sizelist,
sizeof(int) * font->count);
font->sizelist[font->count - 1] = newsize;
qsort((void*)font->sizelist, font->count, sizeof(int), numsort);
}
else
font->glyph_id[i] = -1;
}
TRACE("bdf2_load: numGlyph=%d\n", font->numGlyph);
/* Add size in the sizelist */
if (newsize > 0)
{
font->sizelist = (int*)realloc(font->sizelist,
sizeof(int) * font->count);
font->sizelist[font->count - 1] = newsize;
qsort((void*)font->sizelist, font->count, sizeof(int), numsort);
}
 
bdf = bdf2_get_bdf1(font, font->sizelist[0]);
font->bboxX = bdf->bbx.width;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
font->glyph_dwidth[i] = bdf->glyph_dwidth[i];
bdf = bdf2_get_bdf1(font, font->sizelist[0]);
font->bboxX = bdf->bbx.width;
for (i = 0; i < BDF_MAX_GLYPH; ++i)
font->glyph_dwidth[i] = bdf->glyph_dwidth[i];
 
#ifndef USE_FLEXIBLE_GLYPHWIDTH
/* Chech cell width */
for (i = 0; i < font->count; ++i)
{
int j;
/* Chech cell width */
for (i = 0; i < font->count; ++i)
{
int j;
 
bdf = bdf2_get_bdf1(font, font->sizelist[i]);
for (j = 0; j < BDF_MAX_GLYPH; ++j)
if (font->glyph_width[j] < bdf->cell_width[j])
font->glyph_width[j] = bdf->cell_width[j];
}
bdf = bdf2_get_bdf1(font, font->sizelist[i]);
for (j = 0; j < BDF_MAX_GLYPH; ++j)
if (font->glyph_width[j] < bdf->cell_width[j])
font->glyph_width[j] = bdf->cell_width[j];
}
#endif
 
return 1;
return 1;
}
 
bdf_glyph_t*
bdf_glyph_t*
bdf2_get_glyph(bdf2_t* font, int size, int id)
{
bdf_t *bdf;
bdf_t *bdf;
 
bdf = bdf2_get_bdf1(font, size);
return bdf ? bdf_get_glyph(bdf, id) : NULL;
bdf = bdf2_get_bdf1(font, size);
return bdf ? bdf_get_glyph(bdf, id) : NULL;
}
 
int
int
bdf2_get_pixel(bdf2_t* font, int size, int id, int x, int y)
{
bdf_t *bdf;
bdf_t *bdf;
 
bdf = bdf2_get_bdf1(font, size);
return bdf ? bdf_get_pixel(bdf, id, x, y) : -1;
bdf = bdf2_get_bdf1(font, size);
return bdf ? bdf_get_pixel(bdf, id, x, y) : -1;
}
 
/*
* Search bdf_t by size.
*/
bdf_t*
bdf_t*
bdf2_get_bdf1(bdf2_t* font, int size)
{
bdf_list_t **list = &font->list;
bdf_list_t *tmp;
while (1)
{
tmp = *list;
if (!tmp)
return NULL; /* not found */
bdf_list_t **list = &font->list;
bdf_list_t *tmp;
while (1)
{
tmp = *list;
if (!tmp)
return NULL; /* not found */
#ifdef USE_PIXELSIZE
else if (tmp->bdf->pixel_size == size)
break; /* found */
else if (tmp->bdf->pixel_size == size)
break; /* found */
#else
else if (tmp->bdf->size == size)
break; /* found */
else if (tmp->bdf->size == size)
break; /* found */
#endif
list = &tmp->next;
}
/* Put found bdf_t top in the list */
if (tmp != font->list)
{
*list = tmp->next;
tmp->next = font->list;
font->list = tmp;
}
return font->list->bdf;
list = &tmp->next;
}
/* Put found bdf_t top in the list */
if (tmp != font->list)
{
*list = tmp->next;
tmp->next = font->list;
font->list = tmp;
}
return font->list->bdf;
}
 
int
int
bdf2_get_count(bdf2_t* font)
{
return font->count;
return font->count;
}
 
int*
int*
bdf2_get_sizelist(bdf2_t* font)
{
return font->sizelist;
return font->sizelist;
}
 
int
int
bdf2_get_glyph_id(bdf2_t* font, int id)
{
if (id < 0 || id >= BDF_MAX_GLYPH)
return -1;
else
return font->glyph_id[id];
if (id < 0 || id >= BDF_MAX_GLYPH)
return -1;
else
return font->glyph_id[id];
}
 
unsigned char
unsigned char
bdf2_get_glyph_flag(bdf2_t* font, int id)
{
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_flag[id];
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_flag[id];
}
 
unsigned char
unsigned char
bdf2_get_glyph_width(bdf2_t* font, int id)
{
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_width[id];
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_width[id];
}
 
unsigned char
unsigned char
bdf2_get_glyph_dwidth(bdf2_t* font, int id)
{
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_dwidth[id];
if (id < 0 || id >= BDF_MAX_GLYPH)
return 0;
else
return font->glyph_dwidth[id];
}
 
int
int
bdf2_is_glyph_available(bdf2_t* font, int id)
{
return bdf2_get_glyph_flag(font, id) & BDF2GF_AVAILABLE ? 1 : 0;
return bdf2_get_glyph_flag(font, id) & BDF2GF_AVAILABLE ? 1 : 0;
}
 
/*****************************************************************************
@@ -859,101 +859,101 @@
*****************************************************************************/
 
#ifdef BDF_TEST
void
void
out_bitmap(bdf_t* font)
{
int i;
int i;
 
printf("size=%d\n", font->size);
printf("bbx=%d %d %d %d\n", font->bbx.width, font->bbx.height,
font->bbx.offset.x, font->bbx.offset.y);
printf("numGlyph=%d\n", font->numGlyph);
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
int y;
bdf_glyph_t *glyph;
 
glyph = bdf_get_glyph(font, i);
if (!glyph)
continue;
printf("\n[%04x] %d %d %d %d\n", i,
glyph->bbx.width, glyph->bbx.height,
glyph->bbx.offset.x, glyph->bbx.offset.y);
for (y = 0; bdf_get_pixel(font, i, 0, y) >= 0; ++y)
printf("size=%d\n", font->size);
printf("bbx=%d %d %d %d\n", font->bbx.width, font->bbx.height,
font->bbx.offset.x, font->bbx.offset.y);
printf("numGlyph=%d\n", font->numGlyph);
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
int x;
int y;
bdf_glyph_t *glyph;
 
printf(" ");
for (x = 0; ; ++x)
{
int pixel = bdf_get_pixel(font, i, x, y);
if (pixel < 0)
break;
printf("%c", pixel ? '1' : '0');
}
printf("\n");
glyph = bdf_get_glyph(font, i);
if (!glyph)
continue;
printf("\n[%04x] %d %d %d %d\n", i,
glyph->bbx.width, glyph->bbx.height,
glyph->bbx.offset.x, glyph->bbx.offset.y);
for (y = 0; bdf_get_pixel(font, i, 0, y) >= 0; ++y)
{
int x;
 
printf(" ");
for (x = 0; ; ++x)
{
int pixel = bdf_get_pixel(font, i, x, y);
if (pixel < 0)
break;
printf("%c", pixel ? '1' : '0');
}
printf("\n");
}
}
}
}
 
void
void
out_bdf(bdf_t* font)
{
int i;
int i;
 
printf("SIZE %d %d %d\n", font->size, 72, 72);
printf("FONTBOUNDINGBOX %d %d %d %d\n",
font->bbx.width, font->bbx.height,
font->bbx.offset.x, font->bbx.offset.y);
printf("CHARS %d\n", font->numGlyph);
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
int x, y, X, Y;
bdf_glyph_t *glyph;
printf("SIZE %d %d %d\n", font->size, 72, 72);
printf("FONTBOUNDINGBOX %d %d %d %d\n",
font->bbx.width, font->bbx.height,
font->bbx.offset.x, font->bbx.offset.y);
printf("CHARS %d\n", font->numGlyph);
for (i = 0; i < BDF_MAX_GLYPH; ++i)
{
int x, y, X, Y;
bdf_glyph_t *glyph;
 
glyph = bdf_get_glyph(font, i);
if (!glyph)
continue;
printf("STARTCHAR .%04x.%04x\n", i, glyph->id);
printf("ENCODING %d\n", i);
printf("SWIDTH %d %d\n", glyph->swidth.x, glyph->swidth.y);
printf("DWIDTH %d %d\n", glyph->dwidth.x, glyph->dwidth.y);
printf("BBX %d %d %d %d\n",
glyph->bbx.width, glyph->bbx.height,
glyph->bbx.offset.x, glyph->bbx.offset.y);
printf("BITMAP\n");
X = RAS_BYTE(glyph->bbx.width);
Y = glyph->bbx.height;
for (y = 0; y < Y; ++y)
{
for (x = 0; x < X; ++x)
printf("%02x", glyph->bitmap[x + y * X]);
printf("\n");
glyph = bdf_get_glyph(font, i);
if (!glyph)
continue;
printf("STARTCHAR .%04x.%04x\n", i, glyph->id);
printf("ENCODING %d\n", i);
printf("SWIDTH %d %d\n", glyph->swidth.x, glyph->swidth.y);
printf("DWIDTH %d %d\n", glyph->dwidth.x, glyph->dwidth.y);
printf("BBX %d %d %d %d\n",
glyph->bbx.width, glyph->bbx.height,
glyph->bbx.offset.x, glyph->bbx.offset.y);
printf("BITMAP\n");
X = RAS_BYTE(glyph->bbx.width);
Y = glyph->bbx.height;
for (y = 0; y < Y; ++y)
{
for (x = 0; x < X; ++x)
printf("%02x", glyph->bitmap[x + y * X]);
printf("\n");
}
printf("ENDCHAR\n");
}
printf("ENDCHAR\n");
}
}
 
int
int
main(int argc, char** argv)
{
int i;
bdf_t* font;
int i;
bdf_t* font;
 
if (argc < 2)
{
printf("Usage: %s {bdffile} [{bdffile} ...]\n", argv[0]);
return -1;
}
if (argc < 2)
{
printf("Usage: %s {bdffile} [{bdffile} ...]\n", argv[0]);
return -1;
}
 
font = bdf_open();
for (i = 1; argv[i]; ++i)
font = bdf_open();
for (i = 1; argv[i]; ++i)
bdf_load(font, argv[i]);
 
//out_bitmap(font);
out_bdf(font);
//out_bitmap(font);
out_bdf(font);
 
bdf_close(font);
return 0;
bdf_close(font);
return 0;
}
#endif