diff options
-rw-r--r-- | demo/main.lua | 12 | ||||
-rw-r--r-- | src/cairo_bindings.c | 258 | ||||
-rw-r--r-- | src/cairo_bindings.h | 26 | ||||
-rw-r--r-- | src/common.h | 26 | ||||
-rw-r--r-- | src/honey_lua.c | 48 |
5 files changed, 357 insertions, 13 deletions
diff --git a/demo/main.lua b/demo/main.lua index f28510c..2ab1441 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -19,15 +19,13 @@ end) local tex = honey.texture.load('lowres.png', {minFilter='nearest', magFilter='nearest'}) -local cairo = honey.cairo({minFilter='nearest', magFilter='nearest'}) -cairo:setColor(1, 1, 1) -cairo:moveTo(1024,0) -cairo:lineTo(0,1024) -cairo:stroke() - -cairo:setLineWidth(20) +local cairo = honey.cairo() +cairo:setLinecap('butt') +cairo:setLineWidth(50) cairo:setColor(0,0,0) cairo:arc(512, 512, 256) +cairo:moveTo(256,256) +cairo:lineTo(1024-256,1024-256) cairo:stroke() cairo:updateTexture() diff --git a/src/cairo_bindings.c b/src/cairo_bindings.c index d72597c..3b7bacb 100644 --- a/src/cairo_bindings.c +++ b/src/cairo_bindings.c @@ -9,15 +9,28 @@ int honey_setup_cairo(lua_State* L) { honey_lua_create_table (L, 2, - HONEY_TABLE, "__index", 8, + HONEY_TABLE, "__index", 17, HONEY_FUNCTION, "getTexture", honey_cairo_get_texture, HONEY_FUNCTION, "updateTexture", honey_cairo_update_texture, + + /* config functions */ + HONEY_FUNCTION, "save", honey_cairo_save, + HONEY_FUNCTION, "restore", honey_cairo_restore, + HONEY_FUNCTION, "setOperator", honey_cairo_set_operator, + HONEY_FUNCTION, "getOperator", honey_cairo_get_operator, + HONEY_FUNCTION, "setAntialias", honey_cairo_set_antialias, + HONEY_FUNCTION, "getAntialias", honey_cairo_get_antialias, + HONEY_FUNCTION, "setColor", honey_cairo_set_color, + HONEY_FUNCTION, "setLinecap", honey_cairo_set_linecap, + HONEY_FUNCTION, "getLinecap", honey_cairo_get_linecap, + HONEY_FUNCTION, "setLineWidth", honey_cairo_set_line_width, + + /* drawing functions */ HONEY_FUNCTION, "moveTo", honey_cairo_move_to, HONEY_FUNCTION, "lineTo", honey_cairo_line_to, HONEY_FUNCTION, "arc", honey_cairo_arc, HONEY_FUNCTION, "stroke", honey_cairo_stroke, - HONEY_FUNCTION, "setColor", honey_cairo_set_color, - HONEY_FUNCTION, "setLineWidth", honey_cairo_set_line_width, + HONEY_FUNCTION, "fill", honey_cairo_fill, HONEY_FUNCTION, "__gc", honey_cairo_destroy); honey_cairo_mt_ref = luaL_ref(L, LUA_REGISTRYINDEX); @@ -159,6 +172,234 @@ int honey_cairo_destroy(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * + * Context config functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +int honey_cairo_set_operator(lua_State* L) +{ + cairo_t** cr; + char* op_string; + honey_lua_parse_arguments(L, 1, 2, HONEY_USERDATA, &cr, HONEY_STRING, &op_string); + + cairo_operator_t op; + + bool ok = honey_string_to_enum + (&op, op_string, 29, + "clear", CAIRO_OPERATOR_CLEAR, + "source", CAIRO_OPERATOR_SOURCE, + "over", CAIRO_OPERATOR_OVER, + "in", CAIRO_OPERATOR_IN, + "out", CAIRO_OPERATOR_OUT, + "atop", CAIRO_OPERATOR_ATOP, + "dest", CAIRO_OPERATOR_DEST, + "dest-over", CAIRO_OPERATOR_DEST_OVER, + "dest-in", CAIRO_OPERATOR_DEST_IN, + "dest-out", CAIRO_OPERATOR_DEST_OUT, + "dest-atop", CAIRO_OPERATOR_DEST_ATOP, + "xor", CAIRO_OPERATOR_XOR, + "add", CAIRO_OPERATOR_ADD, + "saturate", CAIRO_OPERATOR_SATURATE, + "multiply", CAIRO_OPERATOR_MULTIPLY, + "screen", CAIRO_OPERATOR_SCREEN, + "overlay", CAIRO_OPERATOR_OVERLAY, + "darken", CAIRO_OPERATOR_DARKEN, + "lighten", CAIRO_OPERATOR_LIGHTEN, + "color-dodge", CAIRO_OPERATOR_COLOR_DODGE, + "color-burn", CAIRO_OPERATOR_COLOR_BURN, + "hard-light", CAIRO_OPERATOR_HARD_LIGHT, + "soft-light", CAIRO_OPERATOR_SOFT_LIGHT, + "difference", CAIRO_OPERATOR_DIFFERENCE, + "exclusion", CAIRO_OPERATOR_EXCLUSION, + "hsl-hue", CAIRO_OPERATOR_HSL_HUE, + "hsl-saturation", CAIRO_OPERATOR_HSL_SATURATION, + "hsl-color", CAIRO_OPERATOR_HSL_COLOR, + "hsl-luminosity", CAIRO_OPERATOR_HSL_LUMINOSITY); + + + if (!ok) + honey_lua_throw_error(L, "unknown cairo operator '%s'", op_string); + + cairo_set_operator(*cr, op); + + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_get_operator(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_operator_t op = cairo_get_operator(*cr); + char* string; + bool ok = honey_enum_to_string + (&string, op, 29, + "clear", CAIRO_OPERATOR_CLEAR, + "source", CAIRO_OPERATOR_SOURCE, + "over", CAIRO_OPERATOR_OVER, + "in", CAIRO_OPERATOR_IN, + "out", CAIRO_OPERATOR_OUT, + "atop", CAIRO_OPERATOR_ATOP, + "dest", CAIRO_OPERATOR_DEST, + "dest-over", CAIRO_OPERATOR_DEST_OVER, + "dest-in", CAIRO_OPERATOR_DEST_IN, + "dest-out", CAIRO_OPERATOR_DEST_OUT, + "dest-atop", CAIRO_OPERATOR_DEST_ATOP, + "xor", CAIRO_OPERATOR_XOR, + "add", CAIRO_OPERATOR_ADD, + "saturate", CAIRO_OPERATOR_SATURATE, + "multiply", CAIRO_OPERATOR_MULTIPLY, + "screen", CAIRO_OPERATOR_SCREEN, + "overlay", CAIRO_OPERATOR_OVERLAY, + "darken", CAIRO_OPERATOR_DARKEN, + "lighten", CAIRO_OPERATOR_LIGHTEN, + "color-dodge", CAIRO_OPERATOR_COLOR_DODGE, + "color-burn", CAIRO_OPERATOR_COLOR_BURN, + "hard-light", CAIRO_OPERATOR_HARD_LIGHT, + "soft-light", CAIRO_OPERATOR_SOFT_LIGHT, + "difference", CAIRO_OPERATOR_DIFFERENCE, + "exclusion", CAIRO_OPERATOR_EXCLUSION, + "hsl-hue", CAIRO_OPERATOR_HSL_HUE, + "hsl-saturation", CAIRO_OPERATOR_HSL_SATURATION, + "hsl-color", CAIRO_OPERATOR_HSL_COLOR, + "hsl-luminosity", CAIRO_OPERATOR_HSL_LUMINOSITY); + + if (!ok) + honey_lua_throw_error(L, "unknown operator '%d'", op); + + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_set_antialias(lua_State* L) +{ + cairo_t** cr; + char* aa_string; + honey_lua_parse_arguments(L, 1, 2, HONEY_USERDATA, &cr, HONEY_STRING, &aa_string); + + cairo_antialias_t aa; + + bool noerror = honey_string_to_enum + (&aa, aa_string, 7, + "default", CAIRO_ANTIALIAS_DEFAULT, + "none", CAIRO_ANTIALIAS_NONE, + "gray", CAIRO_ANTIALIAS_GRAY, + "subpixel", CAIRO_ANTIALIAS_SUBPIXEL, + "fast", CAIRO_ANTIALIAS_FAST, + "good", CAIRO_ANTIALIAS_GOOD, + "best", CAIRO_ANTIALIAS_BEST); + + if (!noerror) + honey_lua_throw_error(L, "unknown antialias type '%s'", aa_string); + + cairo_set_antialias(*cr, aa); + + return 0; + +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_get_antialias(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_antialias_t aa = cairo_get_antialias(*cr); + char* string; + + bool noerror = honey_enum_to_string + (&string, aa, 7, + "default", CAIRO_ANTIALIAS_DEFAULT, + "none", CAIRO_ANTIALIAS_NONE, + "gray", CAIRO_ANTIALIAS_GRAY, + "subpixel", CAIRO_ANTIALIAS_SUBPIXEL, + "fast", CAIRO_ANTIALIAS_FAST, + "good", CAIRO_ANTIALIAS_GOOD, + "best", CAIRO_ANTIALIAS_BEST); + + if (!noerror) + honey_lua_throw_error(L, "unknown antialias type '%d'", aa); + + lua_pushstring(L, string); + + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_save(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_save(*cr); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_restore(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_restore(*cr); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_set_linecap(lua_State* L) +{ + cairo_t** cr; + char* cap_string; + honey_lua_parse_arguments(L, 1, 2, HONEY_USERDATA, &cr, HONEY_STRING, &cap_string); + + cairo_line_cap_t cap; + + bool ok = honey_string_to_enum + (&cap, cap_string, 3, + "butt", CAIRO_LINE_CAP_BUTT, + "round", CAIRO_LINE_CAP_ROUND, + "square", CAIRO_LINE_CAP_SQUARE); + + if (!ok) + honey_lua_throw_error(L, "unknown linecap type '%s'", cap_string); + + cairo_set_line_cap(*cr, cap); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int honey_cairo_get_linecap(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_line_cap_t cap = cairo_get_line_cap(*cr); + char* cap_string; + + bool ok = honey_enum_to_string + (&cap_string, cap, 3, + "butt", CAIRO_LINE_CAP_BUTT, + "round", CAIRO_LINE_CAP_ROUND, + "square", CAIRO_LINE_CAP_SQUARE); + + if (!ok) + honey_lua_throw_error(L, "unknown linecap type '%d'", cap); + + lua_pushstring(L, cap_string); + return 1; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * * Drawing functions * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -225,6 +466,17 @@ int honey_cairo_stroke(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +int honey_cairo_fill(lua_State* L) +{ + cairo_t** cr; + honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &cr); + + cairo_fill(*cr); + return 0; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + int honey_cairo_set_color(lua_State* L) { cairo_t** cr; diff --git a/src/cairo_bindings.h b/src/cairo_bindings.h index 314256b..b2eaa69 100644 --- a/src/cairo_bindings.h +++ b/src/cairo_bindings.h @@ -20,6 +20,28 @@ int honey_cairo_get_texture(lua_State* L); int honey_cairo_destroy(lua_State* L); +/* context config functions */ + +int honey_cairo_save(lua_State* L); + +int honey_cairo_restore(lua_State* L); + +int honey_cairo_set_operator(lua_State* L); + +int honey_cairo_get_operator(lua_State* L); + +int honey_cairo_set_antialias(lua_State* L); + +int honey_cairo_get_antialias(lua_State* L); + +int honey_cairo_set_color(lua_State* L); + +int honey_cairo_set_line_width(lua_State* L); + +int honey_cairo_set_linecap(lua_State* L); + +int honey_cairo_get_linecap(lua_State* L); + /* drawing functions */ int honey_cairo_move_to(lua_State* L); @@ -30,8 +52,6 @@ int honey_cairo_arc(lua_State* L); int honey_cairo_stroke(lua_State* L); -int honey_cairo_set_color(lua_State* L); - -int honey_cairo_set_line_width(lua_State* L); +int honey_cairo_fill(lua_State* L); #endif diff --git a/src/common.h b/src/common.h index 13d3a14..57a9de2 100644 --- a/src/common.h +++ b/src/common.h @@ -202,6 +202,32 @@ typedef struct honey_lua_element { void honey_lua_push_element(lua_State* L, honey_lua_element element); +/** @brief Get an enum value from a string. + * + * This function expects the variadic arguments of the form STR1, VAL1, STR2, VAL2, ... + * + * @param[out] k The result of the conversion. + * @param[in] string The string to check. + * @param[in] n The number of variadic pairs provided. + * @param[in] ... Variadic arguments as described above. + * + * @returns true if the string parsed successfully; false otherwise. + */ +bool honey_string_to_enum(int* k, char* string, int n, ...); + +/** @brief Get an enum value from a string. + * + * This function expects the variadic arguments of the form STR1, VAL1, STR2, VAL2, ... + * + * @param[in] string The resulting string. + * @param[out] k The integer to check. + * @param[in] n The number of variadic pairs provided. + * @param[in] ... Variadic arguments as described above. + * + * @returns true if the integer parsed successfully; false otherwise. + */ +bool honey_enum_to_string(char** string, int k, int n, ...); + /** @brief Create and populate a lua table. * * This function expects a list of the form `type, name, element, type, name, element...`. diff --git a/src/honey_lua.c b/src/honey_lua.c index 50a9710..4b83f27 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -91,7 +91,55 @@ void honey_lua_throw_error(lua_State* L, } lua_error(L); } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +bool honey_string_to_enum(int* k, char* string, int n, ...) +{ + va_list args; + va_start(args, n); + + bool success = false; + + for (int i=0; i<n; i++) { + const char* str = va_arg(args, const char*); + int val = va_arg(args, const char*); + + if (strcmp(str, string) == 0) { + *k = val; + success = true; + break; + } + } + + va_end(args); + return success; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +bool honey_enum_to_string(char** string, int k, int n, ...) +{ + va_list args; + va_start(args, n); + + bool success = false; + for (int i=0; i<n; i++) { + const char* str = va_arg(args, const char*); + int val = va_arg(args, const char*); + + if (k == val) { + *string = str; + success = true; + break; + } + } + + va_end(args); + return success; +} + /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Argument parsing functions |