luametalatex-c/luaharfbuzz/src/luaharfbuzz/buffer.c

339 lines
9.5 KiB
C

#include "luaharfbuzz.h"
static int buffer_new(lua_State *L) {
Buffer *b;
b = (Buffer *)lua_newuserdata(L, sizeof(*b));
luaL_getmetatable(L, "harfbuzz.Buffer");
lua_setmetatable(L, -2);
*b = hb_buffer_create();
return 1;
}
static int buffer_guess_segment_properties(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_buffer_guess_segment_properties(*b);
return 0;
}
static int buffer_get_direction(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Direction *dp = (Direction *)lua_newuserdata(L, sizeof(*dp));
luaL_getmetatable(L, "harfbuzz.Direction");
lua_setmetatable(L, -2);
*dp = hb_buffer_get_direction(*b);
return 1;
}
static int buffer_set_direction(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Direction* dir = (Direction *)luaL_checkudata(L, 2, "harfbuzz.Direction");
hb_buffer_set_direction(*b, *dir);
return 0;
}
static int buffer_get_flags(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
lua_pushinteger(L, hb_buffer_get_flags(*b));
return 1;
}
static int buffer_set_flags(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
unsigned int l = luaL_checkinteger(L, 2);
hb_buffer_set_flags(*b, l);
return 0;
}
static int buffer_get_language(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Language *lp = (Language *)lua_newuserdata(L, sizeof(*lp));
luaL_getmetatable(L, "harfbuzz.Language");
lua_setmetatable(L, -2);
*lp = hb_buffer_get_language(*b);
return 1;
}
static int buffer_set_language(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Language *lang = (Language *)luaL_checkudata(L, 2, "harfbuzz.Language");
hb_buffer_set_language(*b, *lang);
return 0;
}
static int buffer_get_script(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Script *sp = (Script *)lua_newuserdata(L, sizeof(*sp));
luaL_getmetatable(L, "harfbuzz.Script");
lua_setmetatable(L, -2);
*sp = hb_buffer_get_script(*b);
return 1;
}
static int buffer_set_script(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
Script *script = (Script *)luaL_checkudata(L, 2, "harfbuzz.Script");
hb_buffer_set_script(*b, *script);
return 0;
}
static int buffer_get_invisible_glyph(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
lua_pushinteger(L, hb_buffer_get_invisible_glyph(*b));
return 1;
}
static int buffer_set_invisible_glyph(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_codepoint_t cp = (hb_codepoint_t) luaL_checkinteger(L, 2);
hb_buffer_set_invisible_glyph(*b, cp);
return 0;
}
static int buffer_get_replacement_codepoint(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
lua_pushinteger(L, hb_buffer_get_replacement_codepoint(*b));
return 1;
}
static int buffer_set_replacement_codepoint(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_codepoint_t cp = (hb_codepoint_t) luaL_checkinteger(L, 2);
hb_buffer_set_replacement_codepoint(*b, cp);
return 0;
}
static int buffer_add(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, 2);
unsigned int cluster = luaL_checkinteger(L, 3);
hb_buffer_add(*b, c, cluster);
return 0;
}
static int buffer_add_codepoints(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
unsigned int item_offset;
int item_length;
luaL_checktype(L, 2, LUA_TTABLE);
item_offset = luaL_optinteger(L, 3, 0);
item_length = luaL_optinteger(L, 4, -1);
int n = lua_rawlen(L, 2);
hb_codepoint_t *text = (hb_codepoint_t *) malloc(n * sizeof(hb_codepoint_t));
for (unsigned int i = 0; i != n; ++i) {
lua_geti(L, 2, i + 1);
hb_codepoint_t c = (hb_codepoint_t) luaL_checkinteger(L, -1);
text[i] = c;
lua_pop(L, 1);
}
hb_buffer_add_codepoints(*b, text, n, item_offset, item_length);
free(text);
return 0;
}
static int buffer_clear_contents(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_buffer_clear_contents(*b);
return 0;
}
static int buffer_reset(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_buffer_reset(*b);
return 0;
}
static int buffer_add_utf8(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
const char *text;
unsigned int item_offset;
int item_length;
text = luaL_checkstring(L, 2);
item_offset = luaL_optinteger(L, 3, 0);
item_length = luaL_optinteger(L, 4, -1);
hb_buffer_add_utf8(*b, text, -1, item_offset, item_length);
return 0;
}
static int buffer_destroy(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_buffer_destroy(*b);
return 0;
}
static int buffer_get_glyphs(lua_State *L) {
Buffer *buf = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
// Get glyph info and positions out of buffer
unsigned int len = hb_buffer_get_length(*buf);
hb_glyph_info_t *info = hb_buffer_get_glyph_infos(*buf, NULL);
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(*buf, NULL);
hb_glyph_flags_t flags;
unsigned int i;
// Create Lua table and push glyph data onto it.
lua_createtable(L, len, 0); // parent table
for (i = 0; i < len; i++) {
lua_pushinteger(L, i+1); // 1-indexed key parent table
lua_createtable(L, 0, 7); // child table
lua_pushinteger(L, info[i].codepoint);
lua_setfield(L, -2, "codepoint");
lua_pushinteger(L, info[i].cluster);
lua_setfield(L, -2, "cluster");
lua_pushnumber(L, pos[i].x_advance);
lua_setfield(L, -2, "x_advance");
lua_pushnumber(L, pos[i].y_advance);
lua_setfield(L, -2, "y_advance");
lua_pushnumber(L, pos[i].x_offset);
lua_setfield(L, -2, "x_offset");
lua_pushnumber(L, pos[i].y_offset);
lua_setfield(L, -2, "y_offset");
flags = hb_glyph_info_get_glyph_flags(&(info[i]));
if (flags & HB_GLYPH_FLAG_DEFINED) {
lua_pushnumber(L, flags);
lua_setfield(L, -2, "flags");
}
lua_settable(L, -3); // Add child table at index i+1 to parent table
}
return 1;
}
static int buffer_reverse(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
hb_buffer_reverse(*b);
return 0;
}
static int buffer_get_length(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
lua_pushinteger(L, hb_buffer_get_length(*b));
return 1;
}
static int buffer_get_cluster_level(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
lua_pushinteger(L, hb_buffer_get_cluster_level(*b));
return 1;
}
static int buffer_set_cluster_level(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
unsigned int l = luaL_checkinteger(L, 2);
hb_buffer_set_cluster_level(*b, l);
return 0;
}
static int buffer_pre_allocate(lua_State *L) {
Buffer *b = (Buffer *)luaL_checkudata(L, 1, "harfbuzz.Buffer");
unsigned int n = luaL_checkinteger(L, 2);
lua_pushboolean(L, hb_buffer_pre_allocate(*b, n));
return 1;
}
static const struct luaL_Reg buffer_methods[] = {
{ "__gc", buffer_destroy },
{ "add", buffer_add },
{ "add_utf8", buffer_add_utf8 },
{ "add_codepoints", buffer_add_codepoints },
{ "clear_contents", buffer_clear_contents },
{ "set_direction", buffer_set_direction },
{ "get_direction", buffer_get_direction },
{ "set_flags", buffer_set_flags },
{ "get_flags", buffer_get_flags },
{ "set_language", buffer_set_language },
{ "get_language", buffer_get_language },
{ "set_script", buffer_set_script },
{ "get_script", buffer_get_script },
{ "set_invisible_glyph", buffer_set_invisible_glyph },
{ "get_invisible_glyph", buffer_get_invisible_glyph },
{ "set_replacement_codepoint", buffer_set_replacement_codepoint },
{ "get_replacement_codepoint", buffer_get_replacement_codepoint },
{ "get_glyphs", buffer_get_glyphs },
{ "guess_segment_properties", buffer_guess_segment_properties },
{ "reset", buffer_reset },
{ "reverse", buffer_reverse },
{ "get_length", buffer_get_length },
{ "get_cluster_level", buffer_get_cluster_level },
{ "set_cluster_level", buffer_set_cluster_level },
{ "pre_allocate", buffer_pre_allocate },
{ NULL, NULL }
};
static const struct luaL_Reg buffer_functions[] = {
{ "new", buffer_new },
{ NULL, NULL }
};
static const struct luahb_constant_t buffer_constants[] = {
{ "CLUSTER_LEVEL_MONOTONE_GRAPHEMES", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES },
{ "CLUSTER_LEVEL_MONOTONE_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS },
{ "CLUSTER_LEVEL_CHARACTERS", HB_BUFFER_CLUSTER_LEVEL_CHARACTERS },
{ "CLUSTER_LEVEL_DEFAULT", HB_BUFFER_CLUSTER_LEVEL_DEFAULT },
{ "FLAG_DEFAULT", HB_BUFFER_FLAG_DEFAULT },
{ "FLAG_BOT", HB_BUFFER_FLAG_BOT },
{ "FLAG_EOT", HB_BUFFER_FLAG_EOT },
{ "FLAG_PRESERVE_DEFAULT_IGNORABLES", HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES },
{ "FLAG_REMOVE_DEFAULT_IGNORABLES", HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES },
{ "FLAG_DO_NOT_INSERT_DOTTED_CIRCLE", HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE },
{ "GLYPH_FLAG_UNSAFE_TO_BREAK", HB_GLYPH_FLAG_UNSAFE_TO_BREAK },
{ "GLYPH_FLAG_DEFINED", HB_GLYPH_FLAG_DEFINED },
{ NULL, 0 }
};
int register_buffer(lua_State *L) {
return register_class(L, "harfbuzz.Buffer", buffer_methods, buffer_functions, buffer_constants);
}