# HG changeset patch # User David Demelier # Date 1602686434 -7200 # Node ID 28d9bb62fcb1c1f505009030934faf9e741ee5a6 # Parent 4f4795cba52f92c5e316d52c4f474c190aab7f90 core: add font_box function, closes #2495 While here, add an example of usage. diff -r 4f4795cba52f -r 28d9bb62fcb1 examples/CMakeLists.txt --- a/examples/CMakeLists.txt Wed Oct 14 14:52:26 2020 +0200 +++ b/examples/CMakeLists.txt Wed Oct 14 16:40:34 2020 +0200 @@ -29,6 +29,12 @@ ) molko_define_executable( + TARGET example-font + SOURCES example-font.c + LIBRARIES libcore +) + +molko_define_executable( TARGET example-inventory SOURCES example-inventory ASSETS diff -r 4f4795cba52f -r 28d9bb62fcb1 examples/example-font.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example-font.c Wed Oct 14 16:40:34 2020 +0200 @@ -0,0 +1,136 @@ +/* + * example-font.c -- show how to use fonts + * + * Copyright (c) 2020 David Demelier + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define W (1280) +#define H (720) + +/* Friendly taken from: https://lospec.com/palette-list/apollo */ +static const unsigned long colors[] = { + 0x3c5e8bff, /* Blue. */ + 0x468232ff, /* Green. */ + 0xad7757ff, /* Light brown. */ + 0x884b2bff, /* Brown. */ + 0x752438ff, /* Red. */ + 0x7a367bff, /* Magenta. */ + 0x151d28ff, /* Dark */ + 0xc7cfccff, /* Christian Grey. */ +}; + +static void +init(void) +{ + if (!sys_init() || + !window_init("Example - Font", W, H) || + !theme_init()) + panic(); +} + +static void +run(void) +{ + struct clock clock = {0}; + struct font *font = theme_default()->fonts[THEME_FONT_INTERFACE]; + int ci = 0; + enum font_style style = font->style; + + clock_start(&clock); + + for (;;) { + struct texture tex; + union event ev; + unsigned int elapsed = clock_elapsed(&clock); + + clock_start(&clock); + + while (event_poll(&ev)) { + switch (ev.type) { + case EVENT_KEYDOWN: + switch (ev.key.key) { + case KEY_LEFT: + if (ci > 0) + ci--; + break; + case KEY_RIGHT: + if ((size_t)ci < NELEM(colors)) + ci++; + break; + case KEY_SPACE: + if (style == FONT_STYLE_ANTIALIASED) + style = FONT_STYLE_NONE; + else + style = FONT_STYLE_ANTIALIASED; + default: + break; + } + break; + case EVENT_QUIT: + return; + default: + break; + } + } + + painter_set_color(0xffffffff); + painter_clear(); + + font->color = colors[ci]; + font->style = style; + + if (!font_render(font, &tex, "Example of text. Use / to change color and to toggle antialiasing.")) + panic(); + + texture_draw(&tex, 10, 10); + painter_present(); + texture_finish(&tex); + + if ((elapsed = clock_elapsed(&clock)) < 20) + delay(20 - elapsed); + } +} + +static void +quit(void) +{ + theme_finish(); + window_finish(); + sys_finish(); +} + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + init(); + run(); + quit(); + + return 0; +} diff -r 4f4795cba52f -r 28d9bb62fcb1 libcore/core/font.c --- a/libcore/core/font.c Wed Oct 14 14:52:26 2020 +0200 +++ b/libcore/core/font.c Wed Oct 14 16:40:34 2020 +0200 @@ -17,8 +17,6 @@ */ #include -#include -#include #include @@ -67,7 +65,7 @@ bool font_render(struct font *font, struct texture *tex, const char *text) { - assert(font); + assert(font_ok(font)); assert(text); SDL_Color fg = { @@ -97,11 +95,23 @@ unsigned int font_height(const struct font *font) { - assert(font); + assert(font_ok(font)); return TTF_FontHeight(font->handle); } +bool +font_box(const struct font *font, const char *text, unsigned int *w, unsigned int *h) +{ + assert(font_ok(font)); + assert(text); + + if (TTF_SizeUTF8(font->handle, text, (int *)w, (int *)h) != 0) + return error_sdl(); + + return true; +} + void font_finish(struct font *font) { @@ -109,4 +119,6 @@ if (font->handle) TTF_CloseFont(font->handle); + + memset(font, 0, sizeof (*font)); } diff -r 4f4795cba52f -r 28d9bb62fcb1 libcore/core/font.h --- a/libcore/core/font.h Wed Oct 14 14:52:26 2020 +0200 +++ b/libcore/core/font.h Wed Oct 14 16:40:34 2020 +0200 @@ -44,7 +44,7 @@ struct font { enum font_style style; /*!< (RW) Style for rendering. */ unsigned long color; /*!< (RW) Color for rendering. */ - void *handle; /*!< (RO) Native handle. */ + void *handle; /*!< (PV) Native handle. */ }; /** @@ -91,7 +91,7 @@ * This function use the current color/style and other properties in the font * to render the texture. * - * \pre font != NULL + * \pre font_ok(font) * \pre tex != NULL * \param font the font to use * \param tex the texture to generate @@ -104,7 +104,7 @@ /** * Get the maximum height for all glyphs. * - * \pre font != NULL + * \pre font_ok(font) * \param font the font handle * \return the height in pixels */ @@ -112,6 +112,20 @@ font_height(const struct font *font); /** + * Compute the text size required with this font. + * + * \pre font_ok(font) + * \pre text != NULL + * \param font the font object + * \param text the UTF-8 text + * \param w pointer to width (may be NULL) + * \param h pointer to height (may be NULL) + * \return false in case of error and pointers to w and h are left unmodified + */ +bool +font_box(const struct font *font, const char *text, unsigned int *w, unsigned int *h); + +/** * Close the font. * * \pre font != NULL