// Copyright (c) 2018, Loïc Hoguin <[email protected]>
//
// 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 "esdl2.h"
// @todo These operations should probably occur in the thread.
void dtor_Font(ErlNifEnv* env, void* obj)
{
TTF_Font* font = NIF_RES_GET(Font, 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_kerning_size_glyphs
NIF_CALL_HANDLER(thread_ttf_get_font_kerning_size_glyphs)
{
int size;
size = TTF_GetFontKerningSizeGlyphs(args[0], (long)args[1], (long)args[2]);
if (size < 0)
return sdl_error_tuple(env);
return enif_make_tuple2(env,
atom_ok,
enif_make_int(env, size)
);
}
NIF_FUNCTION(ttf_get_font_kerning_size_glyphs)
{
void* font_res;
unsigned int previous_ch, ch;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &previous_ch));
BADARG_IF(!enif_get_uint(env, argv[2], &ch));
return nif_thread_call(env, thread_ttf_get_font_kerning_size_glyphs, 3,
NIF_RES_GET(Font, font_res), previous_ch, ch);
}
// 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_glyph_is_provided
NIF_CALL_HANDLER(thread_ttf_glyph_is_provided)
{
if (TTF_GlyphIsProvided(args[0], (long)args[1]))
return atom_true;
return atom_false;
}
NIF_FUNCTION(ttf_glyph_is_provided)
{
void* font_res;
unsigned int ch;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &ch));
return nif_thread_call(env, thread_ttf_glyph_is_provided, 2,
NIF_RES_GET(Font, font_res), ch);
}
// ttf_glyph_metrics
NIF_CALL_HANDLER(thread_ttf_glyph_metrics)
{
int minx, maxx, miny, maxy, advance;
if (TTF_GlyphMetrics(args[0], (long)args[1],
&minx, &maxx, &miny, &maxy, &advance)) {
return sdl_error_tuple(env);
}
return enif_make_tuple2(env,
atom_ok,
enif_make_tuple5(env,
enif_make_int(env, minx),
enif_make_int(env, maxx),
enif_make_int(env, miny),
enif_make_int(env, maxy),
enif_make_int(env, advance)
)
);
}
NIF_FUNCTION(ttf_glyph_metrics)
{
void* font_res;
unsigned int ch;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &ch));
return nif_thread_call(env, thread_ttf_glyph_metrics, 2,
NIF_RES_GET(Font, font_res), ch);
}
// ttf_init
NIF_CALL_HANDLER(thread_ttf_init)
{
if (TTF_Init())
return sdl_error_tuple(env);
return atom_ok;
}
NIF_FUNCTION(ttf_init)
{
return nif_thread_call(env, thread_ttf_init, 0);
}
// ttf_open_font
NIF_CALL_HANDLER(thread_ttf_open_font)
{
TTF_Font* font;
obj_Font* res;
ERL_NIF_TERM term;
font = TTF_OpenFont(args[0], (long)args[1]);
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)
{
ErlNifBinary bin;
char* filename;
int ptsize;
BADARG_IF(!enif_get_int(env, argv[1], &ptsize));
// 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, 2,
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)
{
TTF_Quit();
}
NIF_FUNCTION(ttf_quit)
{
return nif_thread_cast(env, thread_ttf_quit, 0);
}
// ttf_render_glyph_blended
NIF_CALL_HANDLER(thread_ttf_render_glyph_blended)
{
SDL_Surface* surface;
obj_Surface* res;
ERL_NIF_TERM term;
surface = TTF_RenderGlyph_Blended(args[0], (long)args[1], *(SDL_Color*)args[2]);
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_glyph_blended)
{
void* font_res;
unsigned int ch;
SDL_Color* fg;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &ch));
fg = enif_alloc(sizeof(SDL_Color));
if (!map_to_color(env, argv[2], fg)) {
enif_free(fg);
return enif_make_badarg(env);
}
return nif_thread_call(env, thread_ttf_render_glyph_blended, 3,
NIF_RES_GET(Font, font_res), ch, fg);
}
// ttf_render_glyph_shaded
NIF_CALL_HANDLER(thread_ttf_render_glyph_shaded)
{
SDL_Surface* surface;
obj_Surface* res;
ERL_NIF_TERM term;
surface = TTF_RenderGlyph_Shaded(args[0], (long)args[1],
*(SDL_Color*)args[2], *(SDL_Color*)args[3]);
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_glyph_shaded)
{
void* font_res;
unsigned int ch;
SDL_Color *fg, *bg;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &ch));
fg = enif_alloc(sizeof(SDL_Color));
if (!map_to_color(env, argv[2], fg)) {
enif_free(fg);
return enif_make_badarg(env);
}
bg = enif_alloc(sizeof(SDL_Color));
if (!map_to_color(env, argv[3], bg)) {
enif_free(fg);
enif_free(bg);
return enif_make_badarg(env);
}
return nif_thread_call(env, thread_ttf_render_glyph_shaded, 4,
NIF_RES_GET(Font, font_res), ch, fg, bg);
}
// ttf_render_glyph_solid
NIF_CALL_HANDLER(thread_ttf_render_glyph_solid)
{
SDL_Surface* surface;
obj_Surface* res;
ERL_NIF_TERM term;
surface = TTF_RenderGlyph_Solid(args[0], (long)args[1], *(SDL_Color*)args[2]);
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_glyph_solid)
{
void* font_res;
unsigned int ch;
SDL_Color* fg;
BADARG_IF(!enif_get_resource(env, argv[0], res_Font, &font_res));
BADARG_IF(!enif_get_uint(env, argv[1], &ch));
fg = enif_alloc(sizeof(SDL_Color));
if (!map_to_color(env, argv[2], fg)) {
enif_free(fg);
return enif_make_badarg(env);
}
return nif_thread_call(env, thread_ttf_render_glyph_solid, 3,
NIF_RES_GET(Font, font_res), ch, fg);
}
// 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)
{
SDL_Surface* surface;
obj_Surface* res;
ERL_NIF_TERM term;
surface = TTF_RenderUTF8_Solid(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_solid)
{
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_solid, 3,
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
NIF_CALL_HANDLER(thread_ttf_was_init)
{
if (TTF_WasInit())
return atom_true;
return atom_false;
}
NIF_FUNCTION(ttf_was_init)
{
return nif_thread_call(env, thread_ttf_was_init, 0);
}