diff options
Diffstat (limited to 'c_src')
-rw-r--r-- | c_src/esdl2.h | 27 | ||||
-rw-r--r-- | c_src/sdl_ttf.c | 585 |
2 files changed, 606 insertions, 6 deletions
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 |