339 lines
9.5 KiB
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);
|
|
}
|