| @@ -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); | ||||