# HG changeset patch # User David Demelier # Date 1634367680 -7200 # Node ID 979960e65f76ce9ac7b297d71ef0b5ff45b90448 # Parent 94828af916bbd05964597804dea3ca86c45c8612 js: add font bindings While here, correct int to long in font_render. diff -r 94828af916bb -r 979960e65f76 doc/docs/dev/api/core/font.md --- a/doc/docs/dev/api/core/font.md Thu Oct 14 21:21:28 2021 +0200 +++ b/doc/docs/dev/api/core/font.md Sat Oct 16 09:01:20 2021 +0200 @@ -80,7 +80,7 @@ ```c int -font_render(struct font *font, struct texture *tex, const char *text, unsigned int color) +font_render(struct font *font, struct texture *tex, const char *text, unsigned long color) ``` ### font\_height diff -r 94828af916bb -r 979960e65f76 extern/libduktape/CMakeLists.txt --- a/extern/libduktape/CMakeLists.txt Thu Oct 14 21:21:28 2021 +0200 +++ b/extern/libduktape/CMakeLists.txt Sat Oct 16 09:01:20 2021 +0200 @@ -22,7 +22,7 @@ target_include_directories( libmlk-duktape PUBLIC - $ + $ ) set_target_properties(libmlk-duktape PROPERTIES PREFIX "") diff -r 94828af916bb -r 979960e65f76 src/libmlk-core-js/CMakeLists.txt --- a/src/libmlk-core-js/CMakeLists.txt Thu Oct 14 21:21:28 2021 +0200 +++ b/src/libmlk-core-js/CMakeLists.txt Sat Oct 16 09:01:20 2021 +0200 @@ -22,8 +22,12 @@ SOURCES ${libmlk-core-js_SOURCE_DIR}/core/js-clock.c ${libmlk-core-js_SOURCE_DIR}/core/js-clock.h + ${libmlk-core-js_SOURCE_DIR}/core/js-core.c + ${libmlk-core-js_SOURCE_DIR}/core/js-core.h ${libmlk-core-js_SOURCE_DIR}/core/js-event.c ${libmlk-core-js_SOURCE_DIR}/core/js-event.h + ${libmlk-core-js_SOURCE_DIR}/core/js-font.c + ${libmlk-core-js_SOURCE_DIR}/core/js-font.h ${libmlk-core-js_SOURCE_DIR}/core/js-painter.c ${libmlk-core-js_SOURCE_DIR}/core/js-painter.h ${libmlk-core-js_SOURCE_DIR}/core/js-texture.c diff -r 94828af916bb -r 979960e65f76 src/libmlk-core-js/core/js-core.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-core.c Sat Oct 16 09:01:20 2021 +0200 @@ -0,0 +1,51 @@ +/* + * js-core.c -- core binding + * + * Copyright (c) 2020-2021 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 "js-core.h" + +#define VFS DUK_HIDDEN_SYMBOL("Mlk.Vfs") + +void +js_core_bind(duk_context *ctx, struct vfs *vfs) +{ + assert(ctx); + assert(vfs); + + /* We put the VFS object. */ + duk_push_global_stash(ctx); + duk_push_pointer(ctx, vfs); + duk_put_prop_string(ctx, -2, VFS); + duk_pop(ctx); +} + +struct vfs * +js_core_global_vfs(duk_context *ctx) +{ + assert(ctx); + + struct vfs *vfs; + + duk_push_global_stash(ctx); + duk_get_prop_string(ctx, -1, VFS); + vfs = duk_to_pointer(ctx, -1); + duk_pop(ctx); + + return vfs; +} diff -r 94828af916bb -r 979960e65f76 src/libmlk-core-js/core/js-core.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-core.h Sat Oct 16 09:01:20 2021 +0200 @@ -0,0 +1,32 @@ +/* + * js-core.h -- core binding + * + * Copyright (c) 2020-2021 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. + */ + +#ifndef MLK_CORE_JS_H +#define MLK_CORE_JS_H + +#include + +struct vfs; + +void +js_core_bind(duk_context *, struct vfs *); + +struct vfs * +js_core_global_vfs(duk_context *); + +#endif /* !MLK_CORE_JS_H */ diff -r 94828af916bb -r 979960e65f76 src/libmlk-core-js/core/js-font.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-font.c Sat Oct 16 09:01:20 2021 +0200 @@ -0,0 +1,176 @@ +/* + * js-font.c -- core texture binding + * + * Copyright (c) 2020-2021 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 "js-core.h" +#include "js-font.h" +#include "js-texture.h" + +#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Font") + +static inline struct font * +self(duk_context *ctx) +{ + struct font *font; + + duk_push_this(ctx); + duk_get_prop_string(ctx, -1, SIGNATURE); + font = duk_to_pointer(ctx, -1); + duk_pop_2(ctx); + + if (!font) + duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Font object"); + + return font; +} + +static duk_ret_t +Font_getStyle(duk_context *ctx) +{ + duk_push_int(ctx, self(ctx)->style); + + return 1; +} + +static duk_ret_t +Font_setStyle(duk_context *ctx) +{ + const int style = duk_require_int(ctx, 0); + + if (style < 0 || style >= FONT_STYLE_LAST) + duk_error(ctx, DUK_ERR_ERROR, "invalid style"); + + self(ctx)->style = style; + + return 0; +} + +static duk_ret_t +Font_getHeight(duk_context *ctx) +{ + duk_push_uint(ctx, font_height(self(ctx))); + + return 1; +} + +static duk_ret_t +Font_new(duk_context *ctx) +{ + const char *entry = duk_require_string(ctx, 0); + const unsigned int size = duk_require_uint(ctx, 1); + struct vfs_file file; + struct font *font; + + if (vfs_open(js_core_global_vfs(ctx), &file, entry, "r") < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + font = alloc_new0(sizeof (*font)); + + if (font_openvfs(font, &file, size) < 0) { + free(font); + vfs_file_finish(&file); + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + } + + vfs_file_finish(&file); + + duk_push_this(ctx); + duk_push_pointer(ctx, font); + duk_put_prop_string(ctx, -2, SIGNATURE); + duk_push_string(ctx, "style"); + duk_push_c_function(ctx, Font_getStyle, 0); + duk_push_c_function(ctx, Font_setStyle, 1); + duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); + duk_push_string(ctx, "height"); + duk_push_c_function(ctx, Font_getHeight, 0); + duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); + duk_pop(ctx); + + return 0; +} + +static duk_ret_t +Font_render(duk_context *ctx) +{ + const char *text = duk_require_string(ctx, 0); + unsigned long color = duk_require_uint(ctx, 1); + struct texture *tex; + + tex = alloc_new0(sizeof (*tex)); + + if (font_render(self(ctx), tex, text, color) < 0) { + free(tex); + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + } + + js_texture_push(ctx, tex); + + return 1; +} + +static duk_ret_t +Font_query(duk_context *ctx) +{ + const char *text = duk_require_string(ctx, 0); + unsigned int w, h; + + if (font_query(self(ctx), text, &w, &h) < 0) + duk_error(ctx, DUK_ERR_ERROR, "%s", error()); + + duk_push_object(ctx); + duk_push_uint(ctx, w); + duk_put_prop_string(ctx, -2, "w"); + duk_push_uint(ctx, h); + duk_put_prop_string(ctx, -2, "h"); + + return 1; +} + +static const struct duk_function_list_entry methods[] = { + { "render", Font_render, 2 }, + { "query", Font_query, 1 }, + { NULL, NULL, 0 } +}; + +static const struct duk_number_list_entry styles[] = { + { "ANTIALIASED", FONT_STYLE_ANTIALIASED, }, + { "NONE", FONT_STYLE_NONE }, + { NULL, 0 } +}; + +void +js_font_bind(duk_context *ctx) +{ + assert(ctx); + + duk_push_c_function(ctx, Font_new, 2); + duk_push_object(ctx); + duk_put_number_list(ctx, -1, styles); + duk_put_prop_string(ctx, -2, "Style"); + duk_push_object(ctx); + duk_put_function_list(ctx, -1, methods); + duk_put_prop_string(ctx, -2, "prototype"); + duk_put_global_string(ctx, "Font"); +} diff -r 94828af916bb -r 979960e65f76 src/libmlk-core-js/core/js-font.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core-js/core/js-font.h Sat Oct 16 09:01:20 2021 +0200 @@ -0,0 +1,27 @@ +/* + * js-font.h -- core texture binding + * + * Copyright (c) 2020-2021 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. + */ + +#ifndef MLK_CORE_JS_FONT_H +#define MLK_CORE_JS_FONT_H + +#include + +void +js_font_bind(duk_context *); + +#endif /* !MLK_CORE_JS_FONT_H */ diff -r 94828af916bb -r 979960e65f76 src/libmlk-core/core/font.c --- a/src/libmlk-core/core/font.c Thu Oct 14 21:21:28 2021 +0200 +++ b/src/libmlk-core/core/font.c Sat Oct 16 09:01:20 2021 +0200 @@ -26,6 +26,8 @@ #include "font.h" #include "texture_p.h" #include "util.h" +#include "vfs.h" +#include "vfs_p.h" int font_open(struct font *font, const char *path, unsigned int size) @@ -55,13 +57,29 @@ } int +font_openvfs(struct font *font, struct vfs_file *file, unsigned int size) +{ + assert(font); + assert(vfs_file_ok(file)); + + SDL_RWops *ops; + + if (!(ops = vfs_to_rw(file))) + return -1; + if (!(font->handle = TTF_OpenFontRW(ops, 1, size))) + return errorf("%s", SDL_GetError()); + + return 0; +} + +int font_ok(const struct font *font) { return font && font->handle; } int -font_render(struct font *font, struct texture *tex, const char *text, unsigned int color) +font_render(struct font *font, struct texture *tex, const char *text, unsigned long color) { assert(font_ok(font)); assert(text); diff -r 94828af916bb -r 979960e65f76 src/libmlk-core/core/font.h --- a/src/libmlk-core/core/font.h Thu Oct 14 21:21:28 2021 +0200 +++ b/src/libmlk-core/core/font.h Sat Oct 16 09:01:20 2021 +0200 @@ -24,10 +24,12 @@ #include "core.h" struct texture; +struct vfs_file; enum font_style { FONT_STYLE_ANTIALIASED, - FONT_STYLE_NONE + FONT_STYLE_NONE, + FONT_STYLE_LAST }; struct font { @@ -44,10 +46,13 @@ font_openmem(struct font *, const void *, size_t, unsigned int); int +font_openvfs(struct font *, struct vfs_file *, unsigned int); + +int font_ok(const struct font *); int -font_render(struct font *, struct texture *, const char *, unsigned int); +font_render(struct font *, struct texture *, const char *, unsigned long); unsigned int font_height(const struct font *); diff -r 94828af916bb -r 979960e65f76 src/libmlk-core/core/vfs.c --- a/src/libmlk-core/core/vfs.c Thu Oct 14 21:21:28 2021 +0200 +++ b/src/libmlk-core/core/vfs.c Sat Oct 16 09:01:20 2021 +0200 @@ -17,9 +17,14 @@ */ #include +#include +#include +#include #include +#include "error.h" #include "vfs.h" +#include "vfs_p.h" int vfs_open(struct vfs *vfs, struct vfs_file *file, const char *entry, const char *mode) @@ -32,6 +37,12 @@ return vfs->open(vfs, file, entry, mode); } +int +vfs_ok(struct vfs *vfs) +{ + return vfs && vfs->open && vfs->finish; +} + void vfs_finish(struct vfs *vfs) { @@ -41,6 +52,12 @@ memset(vfs, 0, sizeof (*vfs)); } +int +vfs_file_ok(struct vfs_file *file) +{ + return file && file->read && file->write && file->flush && file->finish; +} + size_t vfs_file_read(struct vfs_file *file, void *buf, size_t bufsz) { @@ -50,6 +67,33 @@ return file->read(file, buf, bufsz); } +char * +vfs_file_aread(struct vfs_file *file, size_t *outlen) +{ + FILE *fp; + char *out = NULL, buf[BUFSIZ]; + size_t len, nr; + + if (!(fp = open_memstream(&out, &len))) + return errorf("%s", strerror(errno)), NULL; + + while ((nr = vfs_file_read(file, buf, sizeof (buf))) > 0) { + if (fwrite(buf, 1, nr, fp) != nr) { + errorf("%s", strerror(errno)); + fclose(fp); + free(out); + return NULL; + } + } + + fclose(fp); + + if (outlen) + *outlen = len; + + return out; +} + size_t vfs_file_write(struct vfs_file *file, void *buf, size_t bufsz) { @@ -74,3 +118,33 @@ file->finish(file); } + +/* private */ + +static int +rw_vfs_file_close(SDL_RWops *context) +{ + free(context->hidden.mem.base); + free(context); + + return 0; +} + +SDL_RWops * +vfs_to_rw(struct vfs_file *file) +{ + SDL_RWops *ops; + char *data; + size_t datasz; + + if (!(data = vfs_file_aread(file, &datasz))) + return NULL; + if (!(ops = SDL_RWFromConstMem(data, datasz))) { + free(data); + return errorf("%s", SDL_GetError()), NULL; + } + + ops->close = rw_vfs_file_close; + + return ops; +} diff -r 94828af916bb -r 979960e65f76 src/libmlk-core/core/vfs.h --- a/src/libmlk-core/core/vfs.h Thu Oct 14 21:21:28 2021 +0200 +++ b/src/libmlk-core/core/vfs.h Sat Oct 16 09:01:20 2021 +0200 @@ -44,14 +44,23 @@ int vfs_open(struct vfs *, struct vfs_file *, const char *, const char *); +int +vfs_ok(struct vfs *); + void vfs_finish(struct vfs *); /* vfs_file */ +int +vfs_file_ok(struct vfs_file *); + size_t vfs_file_read(struct vfs_file *, void *, size_t); +char * +vfs_file_aread(struct vfs_file *, size_t *); + size_t vfs_file_write(struct vfs_file *, void *, size_t); diff -r 94828af916bb -r 979960e65f76 src/libmlk-core/core/vfs_p.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/libmlk-core/core/vfs_p.h Sat Oct 16 09:01:20 2021 +0200 @@ -0,0 +1,27 @@ +/* + * vfs.h -- (PRIVATE) virtual file system abstraction + * + * Copyright (c) 2020-2021 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. + */ + +#ifndef MOLKO_CORE_VFS_P_H +#define MOLKO_CORE_VFS_P_H + +#include + +SDL_RWops * +vfs_to_rw(struct vfs_file *); + +#endif /* !MOLKO_CORE_VFS_P_H */ diff -r 94828af916bb -r 979960e65f76 src/mlk-run/main.c --- a/src/mlk-run/main.c Thu Oct 14 21:21:28 2021 +0200 +++ b/src/mlk-run/main.c Sat Oct 16 09:01:20 2021 +0200 @@ -27,7 +27,9 @@ #include #include +#include #include +#include #include #include #include @@ -50,6 +52,8 @@ core_bind(duk_context *ctx) { js_clock_bind(ctx); + js_core_bind(ctx, &vfs); + js_font_bind(ctx); js_event_bind(ctx); js_painter_bind(ctx); js_texture_bind(ctx); @@ -74,25 +78,6 @@ duk_pop(ctx); } -static char * -extract(struct vfs_file *file) -{ - FILE *fp; - char *out, buf[BUFSIZ]; - size_t len, nr; - - if (!(fp = open_memstream(&out, &len))) - panic(); - - while ((nr = vfs_file_read(file, buf, sizeof (buf))) > 0) - if (fwrite(buf, 1, nr, fp) <= 0) - panic(); - - fclose(fp); - - return out; -} - static void startup(void) { @@ -101,8 +86,9 @@ if (vfs_open(&vfs, &main, "main.js", "r") < 0) panic(); + if (!(code = vfs_file_aread(&main, NULL))) + panic(); - code = extract(&main); vfs_file_finish(&main); if (duk_peval_string(ctx, code))