@@ -41,7 +41,7 @@ struct font_header | |||||
uint32_t control_size, data_size; | uint32_t control_size, data_size; | ||||
uint16_t version, blocks; | uint16_t version, blocks; | ||||
uint32_t glyphs; | uint32_t glyphs; | ||||
uint16_t bpp, width, height, flags; | |||||
uint16_t bpp, width, height, maxwidth, maxheight, flags; | |||||
}; | }; | ||||
struct block_info | 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.bpp = hton16(f->header.bpp); | ||||
f->header.width = hton16(f->header.width); | f->header.width = hton16(f->header.width); | ||||
f->header.height = hton16(f->header.height); | 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); | f->header.flags = hton16(f->header.flags); | ||||
if(size != 4 + f->header.control_size + f->header.data_size | 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 | if(f->glyph_list[i].data_offset >= f->header.data_size | ||||
|| f->glyph_list[i].data_offset | || f->glyph_list[i].data_offset | ||||
+ (f->glyph_list[i].width * f->glyph_list[i].height * | + (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 defined DEBUG | ||||
if(f->glyph_list[i].data_offset >= f->header.data_size) | 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 | "data end %i", f->glyph_list[i].data_offset | ||||
+ (f->glyph_list[i].width * f->glyph_list[i].height * | + (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); | ||||
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 | #endif | ||||
free(f->glyph_list); | free(f->glyph_list); | ||||
free(f->user_block_list); | free(f->user_block_list); | ||||
@@ -304,28 +314,30 @@ char const * const * cucul_get_font_list(void) | |||||
return list; | 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. | * This function never fails. | ||||
* | * | ||||
* \param f The font, as returned by cucul_load_font() | * \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) | unsigned int cucul_get_font_width(cucul_font_t *f) | ||||
{ | { | ||||
return f->header.width; | 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. | * This function never fails. | ||||
* | * | ||||
* \param f The font, as returned by cucul_load_font() | * \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) | 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 | * \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 | * \endcode | ||||
* | * | ||||
@@ -25,8 +25,10 @@ font_header: | |||||
uint16_t bpp; // Bits per pixel for glyph data (valid | uint16_t bpp; // Bits per pixel for glyph data (valid | ||||
// Values are 1, 2, 4 and 8) | // 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 | uint16_t flags; // Feature flags | ||||
// bit 0: set to 1 if font is fixed width | // bit 0: set to 1 if font is fixed width | ||||
@@ -90,9 +90,9 @@ int main(int argc, char *argv[]) | |||||
PangoRectangle r; | PangoRectangle r; | ||||
FT_Bitmap img; | FT_Bitmap img; | ||||
int width, height, blocks, glyphs, fullwidth; | |||||
int stdwidth, fullwidth, height, blocks, glyphs, fullglyphs; | |||||
unsigned int n, b, i, index; | 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; | uint8_t *glyph_data; | ||||
struct glyph *gtab; | struct glyph *gtab; | ||||
@@ -148,33 +148,35 @@ int main(int argc, char *argv[]) | |||||
/* Test rendering so that we know the glyph width */ | /* Test rendering so that we know the glyph width */ | ||||
pango_layout_set_markup(l, "@", -1); | pango_layout_set_markup(l, "@", -1); | ||||
pango_layout_get_extents(l, NULL, &r); | 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); | 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 */ | /* Compute blocks and glyphs count */ | ||||
blocks = 0; | blocks = 0; | ||||
glyphs = 0; | glyphs = 0; | ||||
fullwidth = 0; | |||||
fullglyphs = 0; | |||||
for(b = 0; blocklist[b + 1]; b += 2) | for(b = 0; blocklist[b + 1]; b += 2) | ||||
{ | { | ||||
blocks++; | blocks++; | ||||
glyphs += blocklist[b + 1] - blocklist[b]; | glyphs += blocklist[b + 1] - blocklist[b]; | ||||
for(i = blocklist[b]; i < blocklist[b + 1]; i++) | for(i = blocklist[b]; i < blocklist[b + 1]; i++) | ||||
if(cucul_utf32_is_fullwidth(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)); | gtab = malloc(glyphs * sizeof(struct glyph)); | ||||
glyph_data = malloc(data_size); | glyph_data = malloc(data_size); | ||||
/* 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", | |||||
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(" * Automatically generated by tools/makefont.c:\n"); | ||||
printf(" * tools/makefont %s \"%s\" %i %i\n", prefix, font, dpi, bpp); | printf(" * tools/makefont %s \"%s\" %i %i\n", prefix, font, dpi, bpp); | ||||
printf(" */\n"); | printf(" */\n"); | ||||
@@ -204,8 +206,10 @@ int main(int argc, char *argv[]) | |||||
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\" /* 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_u16("\"%s\" /* flags */\n", 1); | ||||
printf("\n"); | printf("\n"); | ||||
@@ -226,13 +230,13 @@ int main(int argc, char *argv[]) | |||||
{ | { | ||||
for(i = blocklist[b]; i < blocklist[b + 1]; i++) | 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)) | if(cucul_utf32_is_fullwidth(i)) | ||||
{ | { | ||||
current_width *= 2; | |||||
current_size *= 2; | |||||
current_width = fullwidth; | |||||
current_size = fullsize; | |||||
} | } | ||||
gtab[n].unicode = i; | gtab[n].unicode = i; | ||||
bytes = cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); | bytes = cucul_utf32_to_utf8(gtab[n].buf, gtab[n].unicode); | ||||