219 lines
5.4 KiB
C
219 lines
5.4 KiB
C
#include "luaharfbuzz.h"
|
|
|
|
static int font_new(lua_State *L) {
|
|
Font *f;
|
|
Face *face = luaL_checkudata(L, 1, "harfbuzz.Face");
|
|
|
|
f = (Font *)lua_newuserdata(L, sizeof(*f));
|
|
luaL_getmetatable(L, "harfbuzz.Font");
|
|
lua_setmetatable(L, -2);
|
|
|
|
*f = hb_font_create(*face);
|
|
|
|
// Set default scale to be the face's upem value
|
|
unsigned int upem = hb_face_get_upem(*face);
|
|
hb_font_set_scale(*f, upem, upem);
|
|
|
|
// Set shaping functions to OpenType functions
|
|
hb_ot_font_set_funcs(*f);
|
|
return 1;
|
|
}
|
|
|
|
static int font_set_scale(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
int x_scale = luaL_checkinteger(L, 2);
|
|
int y_scale = luaL_checkinteger(L, 3);
|
|
|
|
hb_font_set_scale(*f, x_scale, y_scale);
|
|
return 0;
|
|
}
|
|
|
|
static int font_get_scale(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
int x_scale, y_scale;
|
|
|
|
hb_font_get_scale(*f, &x_scale, &y_scale);
|
|
|
|
lua_pushinteger(L, x_scale);
|
|
lua_pushinteger(L, y_scale);
|
|
return 2;
|
|
}
|
|
|
|
static int font_get_h_extents(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_font_extents_t extents;
|
|
|
|
if (hb_font_get_h_extents(*f, &extents)) {
|
|
lua_createtable(L, 0, 3);
|
|
|
|
lua_pushnumber(L, extents.ascender);
|
|
lua_setfield(L, -2, "ascender");
|
|
|
|
lua_pushnumber(L, extents.descender);
|
|
lua_setfield(L, -2, "descender");
|
|
|
|
lua_pushnumber(L, extents.line_gap);
|
|
lua_setfield(L, -2, "line_gap");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_v_extents(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_font_extents_t extents;
|
|
|
|
if (hb_font_get_v_extents(*f, &extents)) {
|
|
lua_createtable(L, 0, 3);
|
|
|
|
lua_pushnumber(L, extents.ascender);
|
|
lua_setfield(L, -2, "ascender");
|
|
|
|
lua_pushnumber(L, extents.descender);
|
|
lua_setfield(L, -2, "descender");
|
|
|
|
lua_pushnumber(L, extents.line_gap);
|
|
lua_setfield(L, -2, "line_gap");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_glyph_extents(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
|
hb_glyph_extents_t extents;
|
|
|
|
if (hb_font_get_glyph_extents(*f, glyph, &extents)) {
|
|
lua_createtable(L, 0, 4);
|
|
|
|
lua_pushnumber(L, extents.x_bearing);
|
|
lua_setfield(L, -2, "x_bearing");
|
|
|
|
lua_pushnumber(L, extents.y_bearing);
|
|
lua_setfield(L, -2, "y_bearing");
|
|
|
|
lua_pushnumber(L, extents.width);
|
|
lua_setfield(L, -2, "width");
|
|
|
|
lua_pushnumber(L, extents.height);
|
|
lua_setfield(L, -2, "height");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_glyph_name(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
|
|
|
#define NAME_LEN 128
|
|
char name[NAME_LEN];
|
|
if (hb_font_get_glyph_name(*f, glyph, name, NAME_LEN))
|
|
lua_pushstring(L, name);
|
|
else
|
|
lua_pushnil(L);
|
|
#undef NAME_LEN
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_glyph_from_name(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
const char *name = luaL_checkstring(L, 2);
|
|
hb_codepoint_t glyph;
|
|
|
|
if (hb_font_get_glyph_from_name(*f, name, -1, &glyph))
|
|
lua_pushinteger(L, glyph);
|
|
else
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_glyph_h_advance(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
|
|
|
lua_pushinteger(L, hb_font_get_glyph_h_advance(*f, glyph));
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_glyph_v_advance(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t glyph = luaL_checkinteger(L, 2);
|
|
|
|
lua_pushinteger(L, hb_font_get_glyph_v_advance(*f, glyph));
|
|
return 1;
|
|
}
|
|
|
|
static int font_get_nominal_glyph(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t uni = luaL_checkinteger(L, 2);
|
|
hb_codepoint_t glyph;
|
|
|
|
if (hb_font_get_nominal_glyph(*f, uni, &glyph))
|
|
lua_pushinteger(L, glyph);
|
|
else
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
static int font_destroy(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
|
|
hb_font_destroy(*f);
|
|
return 0;
|
|
}
|
|
|
|
static int font_ot_color_glyph_get_png(lua_State *L) {
|
|
Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
|
|
hb_codepoint_t gid = (hb_codepoint_t) luaL_checkinteger(L, 2);
|
|
hb_blob_t* blob = hb_ot_color_glyph_reference_png(*f, gid);
|
|
|
|
if (hb_blob_get_length(blob) != 0) {
|
|
Blob *b = (Blob *)lua_newuserdata(L, sizeof(*b));
|
|
luaL_getmetatable(L, "harfbuzz.Blob");
|
|
lua_setmetatable(L, -2);
|
|
|
|
*b = blob;
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static const struct luaL_Reg font_methods[] = {
|
|
{ "__gc", font_destroy },
|
|
{ "set_scale", font_set_scale },
|
|
{ "get_scale", font_get_scale },
|
|
{ "get_h_extents", font_get_h_extents },
|
|
{ "get_v_extents", font_get_v_extents },
|
|
{ "get_glyph_extents", font_get_glyph_extents },
|
|
{ "get_glyph_name", font_get_glyph_name },
|
|
{ "get_glyph_from_name", font_get_glyph_from_name },
|
|
{ "get_glyph_h_advance", font_get_glyph_h_advance },
|
|
{ "get_glyph_v_advance", font_get_glyph_v_advance },
|
|
{ "get_nominal_glyph", font_get_nominal_glyph },
|
|
{ "ot_color_glyph_get_png", font_ot_color_glyph_get_png },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
static const struct luaL_Reg font_functions[] = {
|
|
{ "new", font_new },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
int register_font(lua_State *L) {
|
|
return register_class(L, "harfbuzz.Font", font_methods, font_functions, NULL);
|
|
}
|