From a273b3d7ec4bc538a75ae33ec7b50c05a8247da0 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 13 Apr 2006 13:33:31 +0000 Subject: [PATCH] * Implemented cucul_get_font_width() and cucul_get_font_height(). * Documented most font functions. * Cleaned up cucul_render_canvas() and made it actually usable by external programs. Removed ugly printf() debug calls. --- cucul/cucul.h | 4 +++ cucul/font.c | 93 +++++++++++++++++++++++++++++++++++++++------------ test/font.c | 22 ++++++++++-- 3 files changed, 95 insertions(+), 24 deletions(-) diff --git a/cucul/cucul.h b/cucul/cucul.h index d1acf26..ca4b537 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -191,6 +191,10 @@ void cucul_free_dither(struct cucul_dither *); * @{ */ struct cucul_font; struct cucul_font *cucul_load_font(void *, unsigned int); +unsigned int cucul_get_font_width(struct cucul_font *); +unsigned int cucul_get_font_height(struct cucul_font *); +void cucul_render_canvas(cucul_t *, struct cucul_font *, unsigned char *, + unsigned int, unsigned int, unsigned int); void cucul_free_font(struct cucul_font *); /* @} */ diff --git a/cucul/font.c b/cucul/font.c index a1e9f7a..01529ed 100644 --- a/cucul/font.c +++ b/cucul/font.c @@ -135,6 +135,39 @@ struct cucul_font *cucul_load_font(void *data, unsigned int size) return f; } +/** \brief Get a font's maximum glyph width. + * + * This function returns the maximum value for the current font's glyphs + * + * \param f The font, as returned by \e cucul_load_font() + * \return The maximum glyph width. + */ +unsigned int cucul_get_font_width(struct cucul_font *f) +{ + return f->header.width; +} + +/** \brief Get a font's maximum glyph height. + * + * This function returns the maximum value for the current font's glyphs + * + * \param f The font, as returned by \e cucul_load_font() + * \return The maximum glyph height. + */ +unsigned int cucul_get_font_height(struct cucul_font *f) +{ + return f->header.height; +} + +/** \brief Free a font structure. + * + * This function frees all data allocated by \e cucul_load_font(). The + * font structure is no longer usable by other libcucul functions. Once + * this function has returned, the memory area that was given to + * \e cucul_load_font() can be freed. + * + * \param f The font, as returned by \e cucul_load_font() + */ void cucul_free_font(struct cucul_font *f) { free(f->glyph_list); @@ -142,20 +175,48 @@ void cucul_free_font(struct cucul_font *f) free(f); } -void cucul_render_canvas(cucul_t *qq, struct cucul_font *f) +/** \brief Render the canvas onto an image buffer. + * + * This function renders the given canvas on an image buffer using a specific + * font. The pixel format is fixed (32-bit ARGB, 8 bits for each component). + * + * The required image width can be computed using \e cucul_get_width(qq) and + * \e cucul_get_font_width(f). The required height can be computed using + * \e cucul_get_height(qq) and \e cucul_get_font_height(f). + * + * Glyphs that do not fit in the image buffer are currently not rendered at + * all. They may be cropped instead in future versions. + * + * \param qq The canvas to render + * \param f The font, as returned by \e cucul_load_font() + * \param buf The image buffer + * \param width The width (in pixels) of the image buffer + * \param height The height (in pixels) of the image buffer + * \param pitch The pitch (in bytes) of an image buffer line. + */ +void cucul_render_canvas(cucul_t *qq, struct cucul_font *f, + unsigned char *buf, unsigned int width, + unsigned int height, unsigned int pitch) { - uint8_t *buf, *glyph = NULL; - unsigned int x, y; - - buf = malloc(4 * qq->width * f->header.width - * qq->height * f->header.height); + uint8_t *glyph = NULL; + unsigned int x, y, xmax, ymax; if(f->header.bpp != 8) glyph = malloc(f->header.width * f->header.height); - for(y = 0; y < qq->height; y++) + if(width < qq->width * f->header.width) + xmax = width / f->header.width; + else + xmax = qq->width; + + if(height < qq->height * f->header.height) + ymax = height / f->header.height; + else + ymax = qq->height; + + for(y = 0; y < ymax; y++) { - for(x = 0; x < qq->width; x++) + for(x = 0; x < xmax; x++) { uint8_t argb[8]; unsigned int starty = y * f->header.height; @@ -207,11 +268,10 @@ void cucul_render_canvas(cucul_t *qq, struct cucul_font *f) break; } - /* Step 2: render glyph using true colours */ + /* Step 2: render glyph using colour attribute */ for(j = 0; j < g->height; j++) { - uint8_t *line = buf + 4 * ((starty + j) * qq->width - * f->header.width + startx); + uint8_t *line = buf + (starty + j) * pitch + 4 * startx; for(i = 0; i < g->width; i++) { @@ -228,19 +288,8 @@ void cucul_render_canvas(cucul_t *qq, struct cucul_font *f) } } - for(y = 0; y < qq->height * f->header.height; y++) - { - for(x = 0; x < qq->width * f->header.width; x++) - { - printf("%.02x", buf[4 * (y * qq->width * f->header.width + x) + 3]); - } - printf("\n"); - } - if(f->header.bpp != 8) free(glyph); - - free(buf); } /* diff --git a/test/font.c b/test/font.c index 38169b5..1f5f9d2 100644 --- a/test/font.c +++ b/test/font.c @@ -33,15 +33,33 @@ int main(int argc, char *argv[]) { cucul_t *qq; struct cucul_font *f; + unsigned char *buf; + unsigned int x, y, w, h; qq = cucul_create(5, 2); + cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLACK); cucul_putstr(qq, 0, 0, "ABcde"); cucul_putstr(qq, 0, 1, "&$âøÿ"); f = cucul_load_font(font_monospace9, 700000); - cucul_render_canvas(qq, f); - cucul_free_font(f); + w = cucul_get_width(qq) * cucul_get_font_width(f); + h = cucul_get_height(qq) * cucul_get_font_height(f); + buf = malloc(4 * w * h); + + cucul_render_canvas(qq, f, buf, w, h, 4 * w); + + for(y = 0; y < h; y++) + { + for(x = 0; x < w; x++) + { + printf("%.02x", buf[4 * (y * w + x) + 3]); + } + printf("\n"); + } + + free(buf); + cucul_free_font(f); cucul_free(qq); return 0;