From 6e2c3832d850497fe715c813869a5e52a454bb1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 7 Feb 2018 12:53:11 +0100 Subject: Add most remaining sdl_ttf functions The only functions left are glyphs and functions I'm not sure should be implemented. --- README.asciidoc | 38 +--- c_src/esdl2.h | 27 +++ c_src/sdl_ttf.c | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/esdl2.erl | 84 ++++++++ src/sdl_ttf.erl | 141 +++++++++++++- 5 files changed, 832 insertions(+), 43 deletions(-) diff --git a/README.asciidoc b/README.asciidoc index cbf5fca..70975ec 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -92,46 +92,13 @@ to the public headers. * 'SDL_ttf.h': ** A function to obtain the SDL_ttf version could be useful ** `TTF_Linked_Version` (if it makes sense, depends on how the library is loaded) -** `TTF_ByteSwappedUNICODE` -** `TTF_OpenFontIndex` -** `TTF_OpenFontRW` -** `TTF_OpenFontIndexRW` -** `TTF_GetFontStyle` -** `TTF_SetFontStyle` -** `TTF_GetFontOutline` -** `TTF_SetFontOutline` -** `TTF_GetFontHinting` -** `TTF_SetFontHinting` -** `TTF_FontHeight` -** `TTF_FontAscent` -** `TTF_FontDescent` -** `TTF_FontLineSkip` -** `TTF_GetFontKerning` -** `TTF_SetFontKerning` -** `TTF_FontFaces` -** `TTF_FontFaceIsFixedWidth` -** `TTF_FontFaceFamilyName` -** `TTF_FontFaceStyleName` +** `TTF_OpenFontRW` (unclear if we need it) +** `TTF_OpenFontIndexRW` (unclear if we need it) ** `TTF_GlyphIsProvided` ** `TTF_GlyphMetrics` -** `TTF_SizeText` -** `TTF_SizeUTF8` -** `TTF_SizeUNICODE` -** `TTF_RenderText_Solid` -** `TTF_RenderUNICODE_Solid` ** `TTF_RenderGlyph_Solid` -** `TTF_RenderText_Shaded` -** `TTF_RenderUTF8_Shaded` -** `TTF_RenderUNICODE_Shaded` ** `TTF_RenderGlyph_Shaded` -** `TTF_RenderText_Blended` -** `TTF_RenderUTF8_Blended` -** `TTF_RenderUNICODE_Blended` -** `TTF_RenderText_Blended_Wrapped` -** `TTF_RenderUTF8_Blended_Wrapped` -** `TTF_RenderUNICODE_Blended_Wrapped` ** `TTF_RenderGlyph_Blended` -** `TTF_CloseFont` ** `TTF_GetFontKerningSizeGlyphs` * 'SDL_version.h': `SDL_GetRevisionNumber` must be implemented. The macros may also be useful. * 'SDL_video.h': The following elements are missing: @@ -208,6 +175,7 @@ These don't make a lot of sense for Erlang. * 'SDL_quit.h' (only necessary when using `SDL_Main`?) * 'SDL_stdinc.h': only a few functions are implemented, others are not interesting. * 'SDL_thread.h' +* 'SDL_ttf.h': the rendering functions for `Text` and `UNICODE` are not interesting because they internally call the `UTF8` functions so we may as well provide utf8-encoded binaries directly. The `TTF_ByteSwappedUNICODE` also falls in this category and is not provided. * 'SDL_video.h': the functions `SDL_CreateWindowFrom`, `SDL_SetWindowData` and `SDL_GetWindowData` take external data as argument. == Nothing to implement diff --git a/c_src/esdl2.h b/c_src/esdl2.h index cad60a7..e82278a 100644 --- a/c_src/esdl2.h +++ b/c_src/esdl2.h @@ -56,6 +56,7 @@ A(bgra8888) \ A(bgrx8888) \ A(blend) \ + A(bold) \ A(borderless) \ A(bottom) \ A(bottom_left) \ @@ -126,6 +127,7 @@ A(input_focus) \ A(input_grabbed) \ A(invalid) \ + A(italic) \ A(iyuv) \ A(joy_axis_motion) \ A(joy_ball_motion) \ @@ -145,6 +147,7 @@ A(left_ctrl) \ A(left_gui) \ A(left_shift) \ + A(light) \ A(max_texture_height) \ A(max_texture_width) \ A(maximized) \ @@ -154,6 +157,7 @@ A(minimum) \ A(mod) \ A(mode) \ + A(mono) \ A(mouse_capture) \ A(mouse_down) \ A(mouse_focus) \ @@ -223,6 +227,7 @@ A(src_alpha) \ A(src_color) \ A(state) \ + A(strikethrough) \ A(substract) \ A(sym) \ A(syswm) \ @@ -241,6 +246,7 @@ A(true) \ A(type) \ A(undefined) \ + A(underline) \ A(unknown) \ A(utility) \ A(uyvy) \ @@ -424,10 +430,31 @@ F(set_texture_blend_mode, 2) \ F(set_texture_color_mod, 4) \ /* sdl_ttf */ \ + F(ttf_font_ascent, 1) \ + F(ttf_font_descent, 1) \ + F(ttf_font_face_family_name, 1) \ + F(ttf_font_face_is_fixed_width, 1) \ + F(ttf_font_face_style_name, 1) \ + F(ttf_font_faces, 1) \ + F(ttf_font_height, 1) \ + F(ttf_font_line_skip, 1) \ + F(ttf_get_font_hinting, 1) \ + F(ttf_get_font_kerning, 1) \ + F(ttf_get_font_outline, 1) \ + F(ttf_get_font_style, 1) \ F(ttf_init, 0) \ F(ttf_open_font, 2) \ + F(ttf_open_font_index, 3) \ F(ttf_quit, 0) \ + F(ttf_render_utf8_blended, 3) \ + F(ttf_render_utf8_blended_wrapped, 4) \ + F(ttf_render_utf8_shaded, 4) \ F(ttf_render_utf8_solid, 3) \ + F(ttf_set_font_hinting, 2) \ + F(ttf_set_font_kerning, 2) \ + F(ttf_set_font_outline, 2) \ + F(ttf_set_font_style, 2) \ + F(ttf_size_utf8, 2) \ F(ttf_was_init, 0) \ /* sdl_version */ \ F(get_version, 0) \ diff --git a/c_src/sdl_ttf.c b/c_src/sdl_ttf.c index 7deb729..917c9d9 100644 --- a/c_src/sdl_ttf.c +++ b/c_src/sdl_ttf.c @@ -22,6 +22,257 @@ void dtor_Font(ErlNifEnv* env, void* obj) TTF_CloseFont(font); } +#define TTF_STYLE_FLAGS(F) \ + F(normal, TTF_STYLE_NORMAL) \ + F(bold, TTF_STYLE_BOLD) \ + F(italic, TTF_STYLE_ITALIC) \ + F(underline, TTF_STYLE_UNDERLINE) \ + F(strikethrough, TTF_STYLE_STRIKETHROUGH) + +static NIF_LIST_TO_FLAGS_FUNCTION(list_to_ttf_style_flags, int, TTF_STYLE_FLAGS) +static NIF_FLAGS_TO_LIST_FUNCTION(ttf_style_flags_to_list, int, TTF_STYLE_FLAGS) + +#define TTF_HINTING_ENUM(E) \ + E(normal, TTF_HINTING_NORMAL) \ + E(light, TTF_HINTING_LIGHT) \ + E(mono, TTF_HINTING_MONO) \ + E(none, TTF_HINTING_NONE) + +static NIF_ATOM_TO_ENUM_FUNCTION(atom_to_ttf_hinting, int, TTF_HINTING_ENUM) +static NIF_ENUM_TO_ATOM_FUNCTION(ttf_hinting_to_atom, int, TTF_HINTING_ENUM) + +// ttf_font_ascent + +NIF_CALL_HANDLER(thread_ttf_font_ascent) +{ + return enif_make_int(env, TTF_FontAscent(args[0])); +} + +NIF_FUNCTION(ttf_font_ascent) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_ascent, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_descent + +NIF_CALL_HANDLER(thread_ttf_font_descent) +{ + return enif_make_int(env, TTF_FontDescent(args[0])); +} + +NIF_FUNCTION(ttf_font_descent) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_descent, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_face_family_name + +NIF_CALL_HANDLER(thread_ttf_font_face_family_name) +{ + const char* name; + ErlNifBinary bin; + + name = TTF_FontFaceFamilyName(args[0]); + + if (!name) + return atom_undefined; + + enif_alloc_binary(strlen(name), &bin); + memcpy(bin.data, name, bin.size); + + return enif_make_binary(env, &bin); +} + +NIF_FUNCTION(ttf_font_face_family_name) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_face_family_name, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_face_is_fixed_width + +NIF_CALL_HANDLER(thread_ttf_font_face_is_fixed_width) +{ + if (TTF_FontFaceIsFixedWidth(args[0])) + return atom_true; + + return atom_false; +} + +NIF_FUNCTION(ttf_font_face_is_fixed_width) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_face_is_fixed_width, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_face_style_name + +NIF_CALL_HANDLER(thread_ttf_font_face_style_name) +{ + const char* name; + ErlNifBinary bin; + + name = TTF_FontFaceStyleName(args[0]); + + if (!name) + return atom_undefined; + + enif_alloc_binary(strlen(name), &bin); + memcpy(bin.data, name, bin.size); + + return enif_make_binary(env, &bin); +} + +NIF_FUNCTION(ttf_font_face_style_name) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_face_style_name, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_faces + +NIF_CALL_HANDLER(thread_ttf_font_faces) +{ + return enif_make_int64(env, TTF_FontFaces(args[0])); +} + +NIF_FUNCTION(ttf_font_faces) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_faces, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_height + +NIF_CALL_HANDLER(thread_ttf_font_height) +{ + return enif_make_int(env, TTF_FontHeight(args[0])); +} + +NIF_FUNCTION(ttf_font_height) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_height, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_font_line_skip + +NIF_CALL_HANDLER(thread_ttf_font_line_skip) +{ + return enif_make_int(env, TTF_FontLineSkip(args[0])); +} + +NIF_FUNCTION(ttf_font_line_skip) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_font_line_skip, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_get_font_hinting + +NIF_CALL_HANDLER(thread_ttf_get_font_hinting) +{ + return ttf_hinting_to_atom(TTF_GetFontHinting(args[0])); +} + +NIF_FUNCTION(ttf_get_font_hinting) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_get_font_hinting, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_get_font_kerning + +NIF_CALL_HANDLER(thread_ttf_get_font_kerning) +{ + if (TTF_GetFontKerning(args[0])) + return atom_true; + + return atom_false; +} + +NIF_FUNCTION(ttf_get_font_kerning) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_get_font_kerning, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_get_font_outline + +NIF_CALL_HANDLER(thread_ttf_get_font_outline) +{ + return enif_make_int(env, TTF_GetFontOutline(args[0])); +} + +NIF_FUNCTION(ttf_get_font_outline) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_get_font_outline, 1, + NIF_RES_GET(Font, font_res)); +} + +// ttf_get_font_style + +NIF_CALL_HANDLER(thread_ttf_get_font_style) +{ + return ttf_style_flags_to_list(env, TTF_GetFontStyle(args[0])); +} + +NIF_FUNCTION(ttf_get_font_style) +{ + void* font_res; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + + return nif_thread_call(env, thread_ttf_get_font_style, 1, + NIF_RES_GET(Font, font_res)); +} + // ttf_init NIF_CALL_HANDLER(thread_ttf_init) @@ -37,7 +288,7 @@ NIF_FUNCTION(ttf_init) return nif_thread_call(env, thread_ttf_init, 0); } -// ttf_openfont +// ttf_open_font NIF_CALL_HANDLER(thread_ttf_open_font) { @@ -80,6 +331,51 @@ NIF_FUNCTION(ttf_open_font) filename, ptsize); } +// ttf_open_font_index + +NIF_CALL_HANDLER(thread_ttf_open_font_index) +{ + TTF_Font* font; + obj_Font* res; + ERL_NIF_TERM term; + + font = TTF_OpenFontIndex(args[0], (long)args[1], (long)args[2]); + + enif_free(args[0]); + + if (!font) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Font, font, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_open_font_index) +{ + ErlNifBinary bin; + char* filename; + int ptsize; + long index; + + BADARG_IF(!enif_get_int(env, argv[1], &ptsize)); + BADARG_IF(!enif_get_int64(env, argv[2], &index)); + + // Getting the filename last to simplify the code due to memory allocation. + + BADARG_IF(!enif_inspect_binary(env, argv[0], &bin)); + + filename = enif_alloc(bin.size + 1); + memcpy(filename, bin.data, bin.size); + filename[bin.size] = '\0'; + + return nif_thread_call(env, thread_ttf_open_font_index, 3, + filename, ptsize, index); +} + // ttf_quit NIF_CAST_HANDLER(thread_ttf_quit) @@ -92,6 +388,170 @@ NIF_FUNCTION(ttf_quit) return nif_thread_cast(env, thread_ttf_quit, 0); } +// ttf_render_utf8_blended + +NIF_CALL_HANDLER(thread_ttf_render_utf8_blended) +{ + SDL_Surface* surface; + obj_Surface* res; + ERL_NIF_TERM term; + + surface = TTF_RenderUTF8_Blended(args[0], args[1], *(SDL_Color*)args[2]); + + enif_free(args[1]); + enif_free(args[2]); + + if (!surface) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Surface, surface, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_render_utf8_blended) +{ + void* font_res; + ErlNifBinary bin; + char* text; + SDL_Color* fg; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); + + text = enif_alloc(bin.size + 1); + memcpy(text, bin.data, bin.size); + text[bin.size] = '\0'; + + fg = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[2], fg)) { + enif_free(text); + enif_free(fg); + + return enif_make_badarg(env); + } + + return nif_thread_call(env, thread_ttf_render_utf8_blended, 3, + NIF_RES_GET(Font, font_res), text, fg); +} + +// ttf_render_utf8_blended_wrapped + +NIF_CALL_HANDLER(thread_ttf_render_utf8_blended_wrapped) +{ + SDL_Surface* surface; + obj_Surface* res; + ERL_NIF_TERM term; + + surface = TTF_RenderUTF8_Blended_Wrapped(args[0], args[1], + *(SDL_Color*)args[2], (long)args[3]); + + enif_free(args[1]); + enif_free(args[2]); + + if (!surface) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Surface, surface, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_render_utf8_blended_wrapped) +{ + void* font_res; + ErlNifBinary bin; + char* text; + SDL_Color* fg; + Uint32 wrap_length; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); + BADARG_IF(!enif_get_uint(env, argv[3], &wrap_length)); + + text = enif_alloc(bin.size + 1); + memcpy(text, bin.data, bin.size); + text[bin.size] = '\0'; + + fg = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[2], fg)) { + enif_free(text); + enif_free(fg); + + return enif_make_badarg(env); + } + + return nif_thread_call(env, thread_ttf_render_utf8_blended_wrapped, 4, + NIF_RES_GET(Font, font_res), text, fg, wrap_length); +} + +// ttf_render_utf8_shaded + +NIF_CALL_HANDLER(thread_ttf_render_utf8_shaded) +{ + SDL_Surface* surface; + obj_Surface* res; + ERL_NIF_TERM term; + + surface = TTF_RenderUTF8_Shaded(args[0], args[1], + *(SDL_Color*)args[2], *(SDL_Color*)args[3]); + + enif_free(args[1]); + enif_free(args[2]); + enif_free(args[3]); + + if (!surface) + return sdl_error_tuple(env); + + NIF_RES_TO_PTR_AND_TERM(Surface, surface, res, term); + + return enif_make_tuple2(env, + atom_ok, + term + ); +} + +NIF_FUNCTION(ttf_render_utf8_shaded) +{ + void* font_res; + ErlNifBinary bin; + char* text; + SDL_Color *fg, *bg; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); + + text = enif_alloc(bin.size + 1); + memcpy(text, bin.data, bin.size); + text[bin.size] = '\0'; + + fg = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[2], fg)) { + enif_free(text); + enif_free(fg); + + return enif_make_badarg(env); + } + + bg = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[3], bg)) { + enif_free(text); + enif_free(fg); + enif_free(bg); + + return enif_make_badarg(env); + } + + return nif_thread_call(env, thread_ttf_render_utf8_shaded, 4, + NIF_RES_GET(Font, font_res), text, fg, bg); +} + // ttf_render_utf8_solid NIF_CALL_HANDLER(thread_ttf_render_utf8_solid) @@ -121,7 +581,7 @@ NIF_FUNCTION(ttf_render_utf8_solid) void* font_res; ErlNifBinary bin; char* text; - SDL_Color* color; + SDL_Color* fg; BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); @@ -130,16 +590,129 @@ NIF_FUNCTION(ttf_render_utf8_solid) memcpy(text, bin.data, bin.size); text[bin.size] = '\0'; - color = enif_alloc(sizeof(SDL_Color)); - if (!map_to_color(env, argv[2], color)) { + fg = enif_alloc(sizeof(SDL_Color)); + if (!map_to_color(env, argv[2], fg)) { enif_free(text); - enif_free(color); + enif_free(fg); return enif_make_badarg(env); } return nif_thread_call(env, thread_ttf_render_utf8_solid, 3, - NIF_RES_GET(Font, font_res), text, color); + NIF_RES_GET(Font, font_res), text, fg); +} + +// ttf_set_font_hinting + +NIF_CAST_HANDLER(thread_ttf_set_font_hinting) +{ + TTF_SetFontHinting(args[0], (long)args[1]); +} + +NIF_FUNCTION(ttf_set_font_hinting) +{ + void* font_res; + int hinting; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!atom_to_ttf_hinting(env, argv[1], &hinting)); + + return nif_thread_cast(env, thread_ttf_set_font_hinting, 2, + NIF_RES_GET(Font, font_res), hinting); +} + +// ttf_set_font_kerning + +NIF_CAST_HANDLER(thread_ttf_set_font_kerning) +{ + TTF_SetFontKerning(args[0], (long)args[1]); +} + +NIF_FUNCTION(ttf_set_font_kerning) +{ + void* font_res; + SDL_bool b; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!atom_to_bool(env, argv[1], &b)); + + return nif_thread_cast(env, thread_ttf_set_font_kerning, 2, + NIF_RES_GET(Font, font_res), b); +} + +// ttf_set_font_outline + +NIF_CAST_HANDLER(thread_ttf_set_font_outline) +{ + TTF_SetFontOutline(args[0], (long)args[1]); +} + +NIF_FUNCTION(ttf_set_font_outline) +{ + void* font_res; + int outline; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_get_int(env, argv[1], &outline)); + + return nif_thread_cast(env, thread_ttf_set_font_outline, 2, + NIF_RES_GET(Font, font_res), outline); +} + +// ttf_set_font_style + +NIF_CAST_HANDLER(thread_ttf_set_font_style) +{ + TTF_SetFontStyle(args[0], (long)args[1]); +} + +NIF_FUNCTION(ttf_set_font_style) +{ + void* font_res; + int style = 0; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!list_to_ttf_style_flags(env, argv[1], &style)); + + return nif_thread_cast(env, thread_ttf_set_font_style, 2, + NIF_RES_GET(Font, font_res), style); +} + +// ttf_size_utf8 + +NIF_CALL_HANDLER(thread_ttf_size_utf8) +{ + int error, w, h; + + error = TTF_SizeUTF8(args[0], args[1], &w, &h); + + enif_free(args[1]); + + if (error) + return sdl_error_tuple(env); + + return enif_make_tuple3(env, + atom_ok, + enif_make_int(env, w), + enif_make_int(env, h) + ); +} + +NIF_FUNCTION(ttf_size_utf8) +{ + void* font_res; + ErlNifBinary bin; + char* text; + + BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res)); + BADARG_IF(!enif_inspect_binary(env, argv[1], &bin)); + + text = enif_alloc(bin.size + 1); + memcpy(text, bin.data, bin.size); + text[bin.size] = '\0'; + + return nif_thread_call(env, thread_ttf_size_utf8, 2, + NIF_RES_GET(Font, font_res), text); } // ttf_was_init diff --git a/src/esdl2.erl b/src/esdl2.erl index 52a2ace..308ffe6 100644 --- a/src/esdl2.erl +++ b/src/esdl2.erl @@ -173,10 +173,31 @@ -export([set_texture_color_mod/4]). %% sdl_ttf +-export([ttf_font_ascent/1]). +-export([ttf_font_descent/1]). +-export([ttf_font_face_family_name/1]). +-export([ttf_font_face_is_fixed_width/1]). +-export([ttf_font_face_style_name/1]). +-export([ttf_font_faces/1]). +-export([ttf_font_height/1]). +-export([ttf_font_line_skip/1]). +-export([ttf_get_font_hinting/1]). +-export([ttf_get_font_kerning/1]). +-export([ttf_get_font_outline/1]). +-export([ttf_get_font_style/1]). -export([ttf_init/0]). -export([ttf_open_font/2]). +-export([ttf_open_font_index/3]). -export([ttf_quit/0]). +-export([ttf_render_utf8_blended/3]). +-export([ttf_render_utf8_blended_wrapped/4]). +-export([ttf_render_utf8_shaded/4]). -export([ttf_render_utf8_solid/3]). +-export([ttf_set_font_hinting/2]). +-export([ttf_set_font_kerning/2]). +-export([ttf_set_font_outline/2]). +-export([ttf_set_font_style/2]). +-export([ttf_size_utf8/2]). -export([ttf_was_init/0]). %% sdl_version @@ -661,18 +682,81 @@ set_texture_color_mod(_, _, _, _) -> %% sdl_ttf +ttf_font_ascent(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_descent(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_face_family_name(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_face_is_fixed_width(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_face_style_name(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_faces(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_height(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_font_line_skip(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_get_font_hinting(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_get_font_kerning(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_get_font_outline(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_get_font_style(_) -> + erlang:nif_error({not_loaded, ?MODULE}). + ttf_init() -> erlang:nif_error({not_loaded, ?MODULE}). ttf_open_font(_, _) -> erlang:nif_error({not_loaded, ?MODULE}). +ttf_open_font_index(_, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + ttf_quit() -> erlang:nif_error({not_loaded, ?MODULE}). +ttf_render_utf8_blended(_, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_render_utf8_blended_wrapped(_, _, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_render_utf8_shaded(_, _, _, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + ttf_render_utf8_solid(_, _, _) -> erlang:nif_error({not_loaded, ?MODULE}). +ttf_set_font_hinting(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_set_font_kerning(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_set_font_outline(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_set_font_style(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + +ttf_size_utf8(_, _) -> + erlang:nif_error({not_loaded, ?MODULE}). + ttf_was_init() -> erlang:nif_error({not_loaded, ?MODULE}). diff --git a/src/sdl_ttf.erl b/src/sdl_ttf.erl index 64a84da..314f70a 100644 --- a/src/sdl_ttf.erl +++ b/src/sdl_ttf.erl @@ -14,15 +14,111 @@ -module(sdl_ttf). +-export([disable_kerning/1]). +-export([enable_kerning/1]). +-export([get_ascent/1]). +-export([get_descent/1]). +-export([get_family_name/1]). +-export([get_height/1]). +-export([get_hinting/1]). +-export([get_line_skip/1]). +-export([get_num_faces/1]). +-export([get_outline/1]). +-export([get_style/1]). +-export([get_style_name/1]). +-export([is_fixed_width/1]). +-export([is_kerning_enabled/1]). -export([is_started/0]). -export([open_font/2]). +-export([open_font/3]). +-export([render_blended/3]). +-export([render_blended/4]). +-export([render_shaded/4]). -export([render_solid/3]). +-export([render_size/2]). +-export([set_hinting/2]). +-export([set_outline/2]). +-export([set_style/2]). -export([start/0]). -export([stop/0]). -opaque font() :: reference(). -export_type([font/0]). +-type hinting() :: normal | light | mono | none. +-export_type([hinting/0]). + +-type style() :: [normal | bold | italic | underline | strikethrough]. +-export_type([style/0]). + +-spec disable_kerning(font()) -> ok. +disable_kerning(Font) -> + esdl2:ttf_set_font_kerning(Font, false). + +-spec enable_kerning(font()) -> ok. +enable_kerning(Font) -> + esdl2:ttf_set_font_kerning(Font, true). + +-spec get_ascent(font()) -> non_neg_integer(). +get_ascent(Font) -> + esdl2:ttf_font_ascent(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_descent(font()) -> neg_integer(). +get_descent(Font) -> + esdl2:ttf_font_descent(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_family_name(font()) -> binary(). +get_family_name(Font) -> + esdl2:ttf_font_face_family_name(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_height(font()) -> non_neg_integer(). +get_height(Font) -> + esdl2:ttf_font_height(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_hinting(font()) -> hinting(). +get_hinting(Font) -> + esdl2:ttf_get_font_hinting(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_line_skip(font()) -> non_neg_integer(). +get_line_skip(Font) -> + esdl2:ttf_font_line_skip(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_num_faces(font()) -> non_neg_integer(). +get_num_faces(Font) -> + esdl2:ttf_font_faces(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_outline(font()) -> non_neg_integer(). +get_outline(Font) -> + esdl2:ttf_get_font_outline(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_style(font()) -> style(). +get_style(Font) -> + esdl2:ttf_get_font_style(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec get_style_name(font()) -> binary(). +get_style_name(Font) -> + esdl2:ttf_font_face_style_name(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec is_fixed_width(font()) -> boolean(). +is_fixed_width(Font) -> + esdl2:ttf_font_face_is_fixed_width(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec is_kerning_enabled(font()) -> boolean(). +is_kerning_enabled(Font) -> + esdl2:ttf_get_font_kerning(Font), + receive {'_nif_thread_ret_', Ret} -> Ret end. + -spec is_started() -> boolean(). is_started() -> esdl2:ttf_was_init(), @@ -33,12 +129,53 @@ open_font(Filename, PointSize) -> esdl2:ttf_open_font(Filename, PointSize), receive {'_nif_thread_ret_', Ret} -> Ret end. +-spec open_font(binary(), pos_integer(), non_neg_integer()) -> {ok, font()} | sdl:error(). +open_font(Filename, PointSize, Index) -> + esdl2:ttf_open_font_index(Filename, PointSize, Index), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec render_blended(font(), binary(), sdl_pixels:color()) + -> {ok, sdl_surface:surface()} | sdl:error(). +render_blended(Font, Text, Fg) -> + esdl2:ttf_render_utf8_blended(Font, Text, Fg), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec render_blended(font(), binary(), sdl_pixels:color(), non_neg_integer()) + -> {ok, sdl_surface:surface()} | sdl:error(). +render_blended(Font, Text, Fg, WrapLen) -> + esdl2:ttf_render_utf8_blended_wrapped(Font, Text, Fg, WrapLen), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec render_shaded(font(), binary(), sdl_pixels:color(), sdl_pixels:color()) + -> {ok, sdl_surface:surface()} | sdl:error(). +render_shaded(Font, Text, Fg, Bg) -> + esdl2:ttf_render_utf8_shaded(Font, Text, Fg, Bg), + receive {'_nif_thread_ret_', Ret} -> Ret end. + -spec render_solid(font(), binary(), sdl_pixels:color()) -> {ok, sdl_surface:surface()} | sdl:error(). -render_solid(Font, Text, Color) -> - esdl2:ttf_render_utf8_solid(Font, Text, Color), +render_solid(Font, Text, Fg) -> + esdl2:ttf_render_utf8_solid(Font, Text, Fg), receive {'_nif_thread_ret_', Ret} -> Ret end. +-spec render_size(font(), binary()) + -> {ok, non_neg_integer(), non_neg_integer()} | sdl:error(). +render_size(Font, Text) -> + esdl2:ttf_size_utf8(Font, Text), + receive {'_nif_thread_ret_', Ret} -> Ret end. + +-spec set_hinting(font(), hinting()) -> ok. +set_hinting(Font, Hinting) -> + esdl2:ttf_set_font_hinting(Font, Hinting). + +-spec set_outline(font(), non_neg_integer()) -> ok. +set_outline(Font, Outline) -> + esdl2:ttf_set_font_outline(Font, Outline). + +-spec set_style(font(), style()) -> ok. +set_style(Font, Style) -> + esdl2:ttf_set_font_style(Font, Style). + -spec start() -> ok | sdl:error(). start() -> esdl2:ttf_init(), -- cgit v1.2.3