aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-02-07 12:53:11 +0100
committerLoïc Hoguin <[email protected]>2018-02-07 17:26:15 +0100
commit6e2c3832d850497fe715c813869a5e52a454bb1a (patch)
treecc76e7e6fb9fbfa4d4ac87212d46f678f93ffaa8
parent0e6c291c64e77181851b8a3255a3da8827124080 (diff)
downloadesdl2-6e2c3832d850497fe715c813869a5e52a454bb1a.tar.gz
esdl2-6e2c3832d850497fe715c813869a5e52a454bb1a.tar.bz2
esdl2-6e2c3832d850497fe715c813869a5e52a454bb1a.zip
Add most remaining sdl_ttf functions
The only functions left are glyphs and functions I'm not sure should be implemented.
-rw-r--r--README.asciidoc38
-rw-r--r--c_src/esdl2.h27
-rw-r--r--c_src/sdl_ttf.c585
-rw-r--r--src/esdl2.erl84
-rw-r--r--src/sdl_ttf.erl141
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(),