@@ -41,7 +41,7 @@ struct font_header | |||
uint32_t control_size, data_size; | |||
uint16_t version, blocks; | |||
uint32_t glyphs; | |||
uint16_t bpp, width, height, flags; | |||
uint16_t bpp, width, height, maxwidth, maxheight, flags; | |||
}; | |||
struct block_info | |||
@@ -153,6 +153,8 @@ cucul_font_t *cucul_load_font(void const *data, unsigned int size) | |||
f->header.bpp = hton16(f->header.bpp); | |||
f->header.width = hton16(f->header.width); | |||
f->header.height = hton16(f->header.height); | |||
f->header.maxwidth = hton16(f->header.maxwidth); | |||
f->header.maxheight = hton16(f->header.maxheight); | |||
f->header.flags = hton16(f->header.flags); | |||
if(size != 4 + f->header.control_size + f->header.data_size | |||
@@ -254,7 +256,9 @@ cucul_font_t *cucul_load_font(void const *data, unsigned int size) | |||
if(f->glyph_list[i].data_offset >= f->header.data_size | |||
|| f->glyph_list[i].data_offset | |||
+ (f->glyph_list[i].width * f->glyph_list[i].height * | |||
f->header.bpp + 7) / 8 > f->header.data_size) | |||
f->header.bpp + 7) / 8 > f->header.data_size | |||
|| f->glyph_list[i].width > f->header.maxwidth | |||
|| f->glyph_list[i].height > f->header.maxheight) | |||
{ | |||
#if defined DEBUG | |||
if(f->glyph_list[i].data_offset >= f->header.data_size) | |||
@@ -268,6 +272,12 @@ cucul_font_t *cucul_load_font(void const *data, unsigned int size) | |||
"data end %i", f->glyph_list[i].data_offset | |||
+ (f->glyph_list[i].width * f->glyph_list[i].height * | |||
f->header.bpp + 7) / 8, f->header.data_size); | |||
else if(f->glyph_list[i].width > f->header.maxwidth) | |||
debug("font error: glyph %i has width %i > max width %i", | |||
f->glyph_list[i].width, f->header.maxwidth); | |||
else if(f->glyph_list[i].height > f->header.maxheight) | |||
debug("font error: glyph %i has height %i > max height %i", | |||
f->glyph_list[i].height, f->header.maxheight); | |||
#endif | |||
free(f->glyph_list); | |||
free(f->user_block_list); | |||
@@ -304,28 +314,30 @@ char const * const * cucul_get_font_list(void) | |||
return list; | |||
} | |||
/** \brief Get a font's maximum glyph width. | |||
/** \brief Get a font's standard glyph width. | |||
* | |||
* This function returns the maximum value for the current font's glyphs | |||
* Return the standard value for the current font's glyphs. Most glyphs in | |||
* the font will have this width, except fullwidth characters. | |||
* | |||
* This function never fails. | |||
* | |||
* \param f The font, as returned by cucul_load_font() | |||
* \return The maximum glyph width. | |||
* \return The standard glyph width. | |||
*/ | |||
unsigned int cucul_get_font_width(cucul_font_t *f) | |||
{ | |||
return f->header.width; | |||
} | |||
/** \brief Get a font's maximum glyph height. | |||
/** \brief Get a font's standard glyph height. | |||
* | |||
* This function returns the maximum value for the current font's glyphs | |||
* Returns the standard value for the current font's glyphs. Most glyphs in | |||
* the font will have this height. | |||
* | |||
* This function never fails. | |||
* | |||
* \param f The font, as returned by cucul_load_font() | |||
* \return The maximum glyph height. | |||
* \return The standard glyph height. | |||
*/ | |||
unsigned int cucul_get_font_height(cucul_font_t *f) | |||
{ | |||
@@ -340,10 +352,10 @@ unsigned int cucul_get_font_height(cucul_font_t *f) | |||
* | |||
* \code | |||
* { | |||
* 0x0, 0x80, // Basic latin: A, B, C, a, b, c | |||
* 0x80, 0x100, // Latin-1 supplement: "A, 'e, ^u | |||
* 0x530, 0x590, // Armenian | |||
* 0x0, 0x0, // END | |||
* 0x0000, 0x0080, // Basic latin: A, B, C, a, b, c | |||
* 0x0080, 0x0100, // Latin-1 supplement: "A, 'e, ^u | |||
* 0x0530, 0x0590, // Armenian | |||
* 0x0000, 0x0000, // END | |||
* }; | |||
* \endcode | |||
* | |||
@@ -25,8 +25,10 @@ font_header: | |||
uint16_t bpp; // Bits per pixel for glyph data (valid | |||
// Values are 1, 2, 4 and 8) | |||
uint16_t width; // Maximum glyph width | |||
uint16_t height; // Maximum glyph height | |||
uint16_t width; // Standard glyph width | |||
uint16_t height; // Standard glyph height | |||
uint16_t maxwidth; // Maximum glyph width | |||
uint16_t maxheight; // Maximum glyph height | |||
uint16_t flags; // Feature flags | |||
// bit 0: set to 1 if font is fixed width | |||
@@ -90,9 +90,9 @@ int main(int argc, char *argv[]) | |||
PangoRectangle r; | |||
FT_Bitmap img; | |||
int width, height, blocks, glyphs, fullwidth; | |||
int stdwidth, fullwidth, height, blocks, glyphs, fullglyphs; | |||
unsigned int n, b, i, index; | |||
unsigned int glyph_size, control_size, data_size, current_offset; | |||
unsigned int stdsize, fullsize, control_size, data_size, current_offset; | |||
uint8_t *glyph_data; | |||
struct glyph *gtab; | |||
@@ -148,33 +148,35 @@ int main(int argc, char *argv[]) | |||
/* Test rendering so that we know the glyph width */ | |||
pango_layout_set_markup(l, "@", -1); | |||
pango_layout_get_extents(l, NULL, &r); | |||
width = PANGO_PIXELS(r.width); | |||
stdwidth = PANGO_PIXELS(r.width); | |||
fullwidth = stdwidth * 2; | |||
height = PANGO_PIXELS(r.height); | |||
glyph_size = ((width * height) + (8 / bpp) - 1) / (8 / bpp); | |||
stdsize = ((stdwidth * height) + (8 / bpp) - 1) / (8 / bpp); | |||
fullsize = ((fullwidth * height) + (8 / bpp) - 1) / (8 / bpp); | |||
/* Compute blocks and glyphs count */ | |||
blocks = 0; | |||
glyphs = 0; | |||
fullwidth = 0; | |||
fullglyphs = 0; | |||
for(b = 0; blocklist[b + 1]; b += 2) | |||
{ | |||
blocks++; | |||
glyphs += blocklist[b + 1] - blocklist[b]; | |||
for(i = blocklist[b]; i < blocklist[b + 1]; i++) | |||
if(cucul_utf32_is_fullwidth(i)) | |||
fullwidth++; | |||
fullglyphs++; | |||
} | |||
control_size = 24 + 12 * blocks + 8 * glyphs; | |||
data_size = glyph_size * (glyphs + fullwidth); | |||
control_size = 28 + 12 * blocks + 8 * glyphs; | |||
data_size = stdsize * (glyphs - fullglyphs) + fullsize * fullglyphs; | |||
gtab = malloc(glyphs * sizeof(struct glyph)); | |||
glyph_data = malloc(data_size); | |||
/* Let's go! */ | |||
printf("/* libcucul font file\n"); | |||
printf(" * \"%s\": %i dpi, %i bpp, %ix%i glyphs\n", | |||
font, dpi, bpp, width, height); | |||
printf(" * \"%s\": %i dpi, %i bpp, %ix%i/%ix%i glyphs\n", | |||
font, dpi, bpp, stdwidth, height, fullwidth, height); | |||
printf(" * Automatically generated by tools/makefont.c:\n"); | |||
printf(" * tools/makefont %s \"%s\" %i %i\n", prefix, font, dpi, bpp); | |||
printf(" */\n"); | |||
@@ -204,8 +206,10 @@ int main(int argc, char *argv[]) | |||
printf_u16("\"%s\" /* blocks */\n", blocks); | |||
printf_u32("\"%s\" /* glyphs */\n", glyphs); | |||
printf_u16("\"%s\" /* bpp */\n", bpp); | |||
printf_u16("\"%s\" /* width */\n", width); | |||
printf_u16("\"%s\" /* height */\n", height); | |||
printf_u16("\"%s\" /* std width */\n", stdwidth); | |||
printf_u16("\"%s\" /* std height */\n", height); | |||
printf_u16("\"%s\" /* max width */\n", fullwidth); | |||
printf_u16("\"%s\" /* max height */\n", height); | |||
printf_u16("\"%s\" /* flags */\n", 1); | |||
printf("\n"); | |||
@@ -226,13 +230,13 @@ int main(int argc, char *argv[]) | |||
{ | |||
for(i = blocklist[b]; i < blocklist[b + 1]; i++) | |||
{ | |||
int x, y, bytes, current_width = width; | |||
unsigned int k, current_size = glyph_size; | |||
int x, y, bytes, current_width = stdwidth; | |||
unsigned int k, current_size = stdsize; | |||
if(cucul_utf32_is_fullwidth(i)) | |||
{ | |||
current_width *= 2; | |||
current_size *= 2; | |||
current_width = fullwidth; | |||
current_size = fullsize; | |||
} | |||
gtab[n].unicode = i; | |||
bytes = cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); | |||