summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luaharfbuzz
diff options
context:
space:
mode:
authorLuigi Scarso <luigi.scarso@gmail.com>2021-12-31 10:38:50 +0000
committerLuigi Scarso <luigi.scarso@gmail.com>2021-12-31 10:38:50 +0000
commitcb71b62afd23fc35a04304858ee2d221b8a51dcb (patch)
tree17511b8aa9976f8420b25c24dc1060b65074257c /Build/source/texk/web2c/luatexdir/luaharfbuzz
parentc46a6d281af96d35e0b0efa75a7aafac88677a8a (diff)
sync luatex with upstream r7476.
git-svn-id: svn://tug.org/texlive/trunk@61453 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luaharfbuzz')
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec1
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec1
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua116
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c195
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c61
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c3
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h2
-rw-r--r--Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c82
8 files changed, 460 insertions, 1 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec
index 17a84532b73..987e9748ff4 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-1.1.0-1.rockspec
@@ -31,6 +31,7 @@ build = {
"src/luaharfbuzz/script.c",
"src/luaharfbuzz/direction.c",
"src/luaharfbuzz/language.c",
+ "src/luaharfbuzz/variation.c",
"src/luaharfbuzz/class_utils.c"
},
libraries = {"harfbuzz"},
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec
index 31ae2ab4fb7..0f0dd8d33bb 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/luaharfbuzz-scm-1.rockspec
@@ -33,6 +33,7 @@ build = {
"src/luaharfbuzz/script.c",
"src/luaharfbuzz/direction.c",
"src/luaharfbuzz/language.c",
+ "src/luaharfbuzz/variation.c",
"src/luaharfbuzz/class_utils.c"
},
libraries = {"harfbuzz"},
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua
index dfae07d8e65..38794372f66 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/spec/harfbuzz_spec.lua
@@ -230,6 +230,64 @@ describe("harfbuzz module", function()
assert.True(r)
assert.are_same(13, i)
end)
+
+ it("can return variation axes", function()
+ local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf')
+
+ assert.is_same(true, f:ot_var_has_data())
+ local axes = f:ot_var_get_axis_infos()
+ assert.are_same(1, #axes)
+ assert.are_same(harfbuzz.Tag.new("wght"), axes[1].tag)
+ assert.are_same(1, axes[1].axis_index)
+ assert.are_same(400, axes[1].min_value)
+ assert.are_same(400, axes[1].default_value)
+ assert.are_same(700, axes[1].max_value)
+ assert.are_same(0, axes[1].flags)
+ assert.are_same("Weight", f:get_name(axes[1].name_id))
+ end)
+
+ it("can find variation axis", function()
+ local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf')
+
+ local axis = f:ot_var_find_axis_info(harfbuzz.Tag.new("wght"))
+ assert.is_not_nil(axis)
+ assert.are_same(harfbuzz.Tag.new("wght"), axis.tag)
+ assert.are_same(1, axis.axis_index)
+ assert.are_same(400, axis.min_value)
+ assert.are_same(400, axis.default_value)
+ assert.are_same(700, axis.max_value)
+ assert.are_same(0, axis.flags)
+ assert.are_same("Weight", f:get_name(axis.name_id))
+ end)
+
+ it("can return named instances", function()
+ local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf')
+
+ local instances = f:ot_var_named_instance_get_infos()
+ assert.are_same(4, #instances)
+ assert.are_same(3, instances[3].index)
+ assert.are_same("SemiBold", f:get_name(instances[3].subfamily_name_id))
+ assert.are_same(nil, f:get_name(instances[3].postscript_name_id))
+ assert.are_same(600, f:ot_var_named_instance_get_design_coords(3))
+ end)
+
+ it("can normalize variations", function()
+ local f = harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf')
+
+ local normalized, after = f:ot_var_normalize_variations(harfbuzz.Variation.new("wght=400"))
+ assert.is_nil(after)
+ assert.are_same(0, normalized)
+
+ normalized = f:ot_var_normalize_variations(harfbuzz.Variation.new("wght=700"))
+ assert.are_same(1<<14, normalized)
+
+ normalized, after = f:ot_var_normalize_coords(700)
+ assert.is_nil(after)
+ assert.are_same(1<<14, normalized)
+
+ normalized = f:ot_var_normalize_coords(400)
+ assert.are_same(0, normalized)
+ end)
end)
describe("harfbuzz.Font", function()
@@ -318,6 +376,25 @@ describe("harfbuzz module", function()
assert.are_same(2857,f:ot_color_glyph_get_png(2):get_length())
assert.are_same("\137PNG",f:ot_color_glyph_get_png(2):get_data():sub(1, 4))
end)
+
+ it("can set variations", function()
+ local f = harfbuzz.Font.new(harfbuzz.Face.new('fonts/STIXTwoText[wght].ttf'))
+
+ f:set_variations(harfbuzz.Variation.new("wght=500"))
+ local normalized, after = f:get_var_coords_normalized()
+ assert.is_nil(after)
+ assert.are_same(5174, normalized)
+
+ f:set_var_coords_design(600)
+ local normalized, after = f:get_var_coords_normalized()
+ assert.is_nil(after)
+ assert.are_same(10348, normalized)
+
+ f:set_var_coords_normalized(1<<13)
+ local normalized, after = f:get_var_coords_normalized()
+ assert.is_nil(after)
+ assert.are_same(1<<13, normalized)
+ end)
end)
describe("harfbuzz.Feature", function()
@@ -339,7 +416,6 @@ describe("harfbuzz module", function()
it("has visible fields", function()
local f = harfbuzz.Feature.new('-kern')
- print(getmetatable(f).__index)
assert.are_equal(tostring(f.tag), 'kern')
assert.are_equal(f.value, 0)
assert.are_equal(f.start, nil)
@@ -362,6 +438,44 @@ describe("harfbuzz module", function()
end)
end)
+ describe("harfbuzz.Variation", function()
+ it("can be initialised with a valid variation string", function()
+ harfbuzz.Variation.new('wght=default')
+ harfbuzz.Variation.new('wght=400')
+ harfbuzz.Variation.new('wght=-20')
+ end)
+
+ it("throws an error when trying to initialise a new variation with an invalid string", function()
+ assert.are_equal(nil, harfbuzz.Variation.new(''))
+ assert.are_equal(nil, harfbuzz.Variation.new('wght'))
+ end)
+
+ it("has a valid tostring value", function()
+ local vs = 'wght=200'
+ local v = harfbuzz.Variation.new(vs)
+ assert.are_equal(vs, tostring(v))
+ end)
+
+ it("has visible fields", function()
+ local v = harfbuzz.Variation.new('wght=400')
+ assert.are_equal(tostring(v.tag), 'wght')
+ assert.are_equal(v.value, 400)
+
+ v = harfbuzz.Variation.new('slnt=-7.5')
+ assert.are_equal(tostring(v.tag), 'slnt')
+ assert.are_equal(v.value, -7.5)
+ end)
+
+ it("has editable fields", function()
+ local f = harfbuzz.Variation.new('slnt=5')
+ f.tag, f.value = harfbuzz.Tag.new"wght", 7
+ assert.are_equal(tostring(f), "wght=7")
+
+ f.tag, f.value = harfbuzz.Tag.new"hght", 0
+ assert.are_equal(tostring(f), "hght=0")
+ end)
+ end)
+
describe("harfbuzz.Tag", function()
it("can be initialised with a valid tag string", function()
harfbuzz.Tag.new('Zyyy')
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c
index 5538c704571..45296e04503 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/face.c
@@ -1,5 +1,20 @@
#include "luaharfbuzz.h"
+#ifdef LuajitTeX
+
+static int lua_absindex (lua_State *L, int i) {
+ if (i < 0 && i > LUA_REGISTRYINDEX)
+ i += lua_gettop(L) + 1;
+ return i;
+}
+static void lua_seti (lua_State *L, int index, lua_Integer i) {
+ index = lua_absindex(L, index);
+ lua_pushinteger(L, i);
+ lua_insert(L, -2);
+ lua_settable(L, index);
+}
+#endif
+
/* Size of static arrays we use to avoid heap allocating memory when reading
* data from HarfBuzz. */
#define STATIC_ARRAY_SIZE 128
@@ -423,6 +438,179 @@ static int face_ot_color_glyph_get_svg(lua_State *L) {
return 1;
}
+static int face_var_has_data(lua_State *L) {
+ Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+
+ lua_pushboolean(L, hb_ot_var_has_data(*f));
+ return 1;
+}
+
+static int push_axis_info(lua_State *L, const hb_ot_var_axis_info_t *info) {
+ lua_createtable(L, 0, 7);
+
+ lua_pushinteger(L, info->axis_index + 1);
+ lua_setfield(L, -2, "axis_index");
+
+ Tag *tp = (Tag *)lua_newuserdata(L, sizeof(*tp));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tp = info->tag;
+ lua_setfield(L, -2, "tag");
+
+ lua_pushinteger(L, info->name_id);
+ lua_setfield(L, -2, "name_id");
+
+ lua_pushinteger(L, info->flags);
+ lua_setfield(L, -2, "flags");
+
+ lua_pushnumber(L, info->min_value);
+ lua_setfield(L, -2, "min_value");
+
+ lua_pushnumber(L, info->default_value);
+ lua_setfield(L, -2, "default_value");
+
+ lua_pushnumber(L, info->max_value);
+ lua_setfield(L, -2, "max_value");
+
+ return 1;
+}
+
+static int face_var_find_axis_info(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ Tag *tag = (Tag *)luaL_checkudata(L, 2, "harfbuzz.Tag");
+ hb_ot_var_axis_info_t axis_info;
+
+ if (hb_ot_var_find_axis_info(*face, *tag, &axis_info))
+ push_axis_info(L, &axis_info);
+ else
+ lua_pushnil(L);
+ return 1;
+}
+
+static int face_var_get_axis_infos(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ lua_Integer start = luaL_optinteger(L, 2, 1) - 1;
+ lua_Integer stop = luaL_optinteger(L, 2, -1);
+ if (start < -1)
+ start += hb_ot_var_get_axis_count(*face) + 1;
+ if (stop < 0)
+ stop += hb_ot_var_get_axis_count(*face) + 1;
+
+ if (start < 0 || stop - start > STATIC_ARRAY_SIZE)
+ lua_pushnil(L);
+ else if (stop <= start)
+ lua_createtable(L, 0, 0);
+ else {
+ unsigned int count = stop - start;
+ hb_ot_var_axis_info_t axis_infos[STATIC_ARRAY_SIZE];
+
+ hb_ot_var_get_axis_infos(*face, start, &count, axis_infos);
+
+ lua_createtable(L, count, 0);
+ for (int i = 0; i != count; i++) {
+ push_axis_info(L, axis_infos + i);
+ lua_seti(L, -2, i + 1);
+ }
+ }
+ return 1;
+}
+
+static int face_var_named_instance_get_infos(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ lua_Integer start = luaL_optinteger(L, 2, 1) - 1;
+ lua_Integer stop = luaL_optinteger(L, 2, -1);
+
+ unsigned int total = hb_ot_var_get_named_instance_count(*face);
+
+ if (start < -1)
+ start += total + 1;
+ if (stop < 0)
+ stop += total + 1;
+ if (stop > total)
+ stop = total;
+
+ if (start < 0)
+ lua_pushnil(L);
+ else if (stop <= start)
+ lua_createtable(L, 0, 0);
+ else {
+ lua_createtable(L, stop - start, 0);
+ for (int i = start; i != stop; i++) {
+ lua_createtable(L, 0, 3);
+
+ lua_pushinteger(L, i + 1);
+ lua_setfield(L, -2, "index");
+
+ lua_pushinteger(L, hb_ot_var_named_instance_get_subfamily_name_id(*face, i));
+ lua_setfield(L, -2, "subfamily_name_id");
+
+ lua_pushinteger(L, hb_ot_var_named_instance_get_subfamily_name_id(*face, i));
+ lua_setfield(L, -2, "subfamily_name_id");
+
+ lua_pushinteger(L, hb_ot_var_named_instance_get_postscript_name_id(*face, i));
+ lua_setfield(L, -2, "postscript_name_id");
+
+ lua_seti(L, -2, i - start + 1);
+ }
+ }
+ return 1;
+}
+
+static int face_var_named_instance_get_design_coords(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ lua_Integer index = luaL_checkinteger(L, 2) - 1;
+
+ float coords[STATIC_ARRAY_SIZE];
+ unsigned int count = STATIC_ARRAY_SIZE;
+ count = hb_ot_var_named_instance_get_design_coords(*face, index, &count, coords);
+
+ for (int i = 0; i != count; i++) {
+ lua_pushnumber(L, coords[i]);
+ }
+ return count;
+}
+
+static int face_var_normalize_variations(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ unsigned int count = lua_gettop(L)-1;
+ if (count > STATIC_ARRAY_SIZE) {
+ return 0;
+ }
+
+ Variation variations[STATIC_ARRAY_SIZE];
+ for (unsigned int i = 0; i != count; i++)
+ variations[i] = *(Variation *)luaL_checkudata(L, i+2, "harfbuzz.Variation");
+
+ unsigned int coord_count = hb_ot_var_get_axis_count(*face);
+ int normalized[STATIC_ARRAY_SIZE];
+ hb_ot_var_normalize_variations(*face, variations, count, normalized, coord_count);
+
+ for (int i = 0; i != coord_count; i++) {
+ lua_pushinteger(L, normalized[i]);
+ }
+ return coord_count;
+}
+
+static int face_var_normalize_coords(lua_State *L) {
+ Face *face = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
+ unsigned int count = lua_gettop(L)-1;
+ if (count > STATIC_ARRAY_SIZE) {
+ return 0;
+ }
+
+ float coords[STATIC_ARRAY_SIZE];
+ for (unsigned int i = 0; i != count; i++)
+ coords[i] = luaL_checknumber(L, i+2);
+
+ int normalized[STATIC_ARRAY_SIZE];
+ hb_ot_var_normalize_coords(*face, count, coords, normalized);
+
+ for (int i = 0; i != count; i++) {
+ lua_pushinteger(L, normalized[i]);
+ }
+ return count;
+}
+
static int face_destroy(lua_State *L) {
Face *f = (Face *)luaL_checkudata(L, 1, "harfbuzz.Face");
@@ -452,6 +640,13 @@ static const struct luaL_Reg face_methods[] = {
{ "ot_layout_find_script", face_ot_layout_find_script },
{ "ot_layout_find_language", face_ot_layout_find_language },
{ "ot_layout_find_feature", face_ot_layout_find_feature },
+ { "ot_var_has_data", face_var_has_data },
+ { "ot_var_find_axis_info", face_var_find_axis_info },
+ { "ot_var_get_axis_infos", face_var_get_axis_infos },
+ { "ot_var_named_instance_get_infos", face_var_named_instance_get_infos },
+ { "ot_var_named_instance_get_design_coords", face_var_named_instance_get_design_coords },
+ { "ot_var_normalize_variations", face_var_normalize_variations },
+ { "ot_var_normalize_coords", face_var_normalize_coords },
{ NULL, NULL }
};
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c
index c601673647e..d369f02f2fa 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/font.c
@@ -192,6 +192,62 @@ static int font_ot_color_glyph_get_png(lua_State *L) {
return 1;
}
+static int font_set_variations(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ unsigned int count = lua_gettop(L) - 1;
+ if (count > 128)
+ count = 128;
+ Variation variations[128];
+ for (int i = 0; i != count; i++)
+ variations[i] = *(Variation *)luaL_checkudata(L, i + 2, "harfbuzz.Variation");
+
+ hb_font_set_variations(*f, variations, count);
+ return 0;
+}
+
+static int font_set_var_coords_design(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ unsigned int count = lua_gettop(L) - 1;
+ if (count > 128)
+ count = 128;
+ float coords[128];
+ for (int i = 0; i != count; i++)
+ coords[i] = luaL_checknumber(L, i + 2);
+
+ hb_font_set_var_coords_design(*f, coords, count);
+ return 0;
+}
+
+static int font_set_var_coords_normalized(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ unsigned int count = lua_gettop(L) - 1;
+ if (count > 128)
+ count = 128;
+ int coords[128];
+ for (int i = 0; i != count; i++)
+ coords[i] = luaL_checkinteger(L, i + 2);
+
+ hb_font_set_var_coords_normalized(*f, coords, count);
+ return 0;
+}
+
+static int font_set_var_named_instance(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ unsigned int instance = luaL_checkinteger(L, 2);
+
+ hb_font_set_var_named_instance(*f, instance - 1);
+ return 0;
+}
+
+static int font_get_var_coords_normalized(lua_State *L) {
+ Font *f = (Font *)luaL_checkudata(L, 1, "harfbuzz.Font");
+ unsigned int count;
+ const int *coords = hb_font_get_var_coords_normalized(*f, &count);
+ for (int i = 0; i != count; i++)
+ lua_pushinteger(L, coords[i]);
+ return count;
+}
+
static const struct luaL_Reg font_methods[] = {
{ "__gc", font_destroy },
{ "set_scale", font_set_scale },
@@ -205,6 +261,11 @@ static const struct luaL_Reg font_methods[] = {
{ "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 },
+ { "set_variations", font_set_variations },
+ { "set_var_coords_design", font_set_var_coords_design },
+ { "set_var_coords_normalized", font_set_var_coords_normalized },
+ { "set_var_named_instance", font_set_var_named_instance },
+ { "get_var_coords_normalized", font_get_var_coords_normalized },
{ NULL, NULL }
};
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
index 176c552aa59..8c841e56322 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.c
@@ -103,6 +103,9 @@ int luaopen_luaharfbuzz (lua_State *L) {
register_language(L);
lua_setfield(L, -2, "Language");
+ register_variation(L);
+ lua_setfield(L, -2, "Variation");
+
register_ot(L);
lua_setfield(L, -2, "ot");
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
index 60f5db9c223..4b3aea6f5c0 100644
--- a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/luaharfbuzz.h
@@ -18,6 +18,7 @@ typedef hb_tag_t Tag;
typedef hb_script_t Script;
typedef hb_direction_t Direction;
typedef hb_language_t Language;
+typedef hb_variation_t Variation;
typedef struct luahb_constant_t {
const char *name;
@@ -35,6 +36,7 @@ int register_tag(lua_State *L);
int register_script(lua_State *L);
int register_direction(lua_State *L);
int register_language(lua_State *L);
+int register_variation(lua_State *L);
int register_ot(lua_State *L);
int register_unicode(lua_State *L);
diff --git a/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c
new file mode 100644
index 00000000000..5683aa607a5
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/luaharfbuzz/src/luaharfbuzz/variation.c
@@ -0,0 +1,82 @@
+// harfbuzz.Variation
+#include "luaharfbuzz.h"
+
+static int variation_new(lua_State *L) {
+ Variation v;
+ const char *variation = luaL_checkstring(L, 1);
+
+ if (hb_variation_from_string(variation, -1, &v)) {
+ Variation *vp = (Variation *)lua_newuserdata(L, sizeof(*vp));
+ luaL_getmetatable(L, "harfbuzz.Variation");
+ lua_setmetatable(L, -2);
+ *vp = v;
+ } else {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static int variation_to_string(lua_State *L) {
+ Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation");
+ char variation[128];
+
+ hb_variation_to_string(v, variation, 128);
+ lua_pushstring(L, variation);
+ return 1;
+}
+
+static const char *variation_tag_ptr;
+static const char *variation_value_ptr;
+
+static int variation_index(lua_State *L) {
+ Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation");
+ const char *key = lua_tostring(L, 2);
+
+ if (key == variation_tag_ptr) {
+ Tag *tag = (Tag *)lua_newuserdata(L, sizeof(*tag));
+ luaL_getmetatable(L, "harfbuzz.Tag");
+ lua_setmetatable(L, -2);
+ *tag = v->tag;
+ } else if (key == variation_value_ptr) {
+ lua_pushnumber(L, v->value);
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+static int variation_newindex(lua_State *L) {
+ Variation* v = (Variation *)luaL_checkudata(L, 1, "harfbuzz.Variation");
+ const char *key = lua_tostring(L, 2);
+
+ if (key == variation_tag_ptr) {
+ v->tag = *(Tag *)luaL_checkudata(L, 3, "harfbuzz.Tag");
+ } else if (key == variation_value_ptr) {
+ v->value = luaL_checknumber(L, 3);
+ }
+ return 0;
+}
+
+static const struct luaL_Reg variation_methods[] = {
+ { "__index", variation_index },
+ { "__newindex", variation_newindex },
+ { "__tostring", variation_to_string },
+ { NULL, NULL },
+};
+
+static const struct luaL_Reg variation_functions[] = {
+ { "new", variation_new },
+ { NULL, NULL }
+};
+
+int register_variation(lua_State *L) {
+ lua_pushliteral(L, "tag");
+ variation_tag_ptr = lua_tostring(L, -1);
+ (void) luaL_ref (L, LUA_REGISTRYINDEX);
+ lua_pushliteral(L, "value");
+ variation_value_ptr = lua_tostring(L, -1);
+ (void) luaL_ref (L, LUA_REGISTRYINDEX);
+
+ return register_class(L, "harfbuzz.Variation", variation_methods, variation_functions, NULL);
+}