From edd64aa1323740eb4047836bfed88266d622fa79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Sat, 8 Jan 2011 12:09:45 +0100 Subject: [PATCH] Read terminals from Lua scripts and export them. Also add a missing part of LdSymbol API. --- src/ld-lua-symbol-private.h | 2 ++ src/ld-lua-symbol.c | 16 ++++++++++ src/ld-lua.c | 59 +++++++++++++++++++++++++++++++++++-- src/ld-symbol.c | 36 +++++++++++++++++++++- src/ld-symbol.h | 7 ++--- 5 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/ld-lua-symbol-private.h b/src/ld-lua-symbol-private.h index 0e8800e..83bc646 100644 --- a/src/ld-lua-symbol-private.h +++ b/src/ld-lua-symbol-private.h @@ -22,6 +22,7 @@ G_BEGIN_DECLS * @name: Name of this symbol. * @human_name: Localized human name of this symbol. * @area: Area of this symbol. + * @terminals: Terminals of this symbol. */ struct _LdLuaSymbolPrivate { @@ -29,6 +30,7 @@ struct _LdLuaSymbolPrivate gchar *name; gchar *human_name; LdRectangle area; + LdPointArray *terminals; }; diff --git a/src/ld-lua-symbol.c b/src/ld-lua-symbol.c index a481cff..955bd97 100644 --- a/src/ld-lua-symbol.c +++ b/src/ld-lua-symbol.c @@ -37,6 +37,7 @@ static void ld_lua_symbol_finalize (GObject *gobject); static const gchar *ld_lua_symbol_real_get_name (LdSymbol *symbol); static const gchar *ld_lua_symbol_real_get_human_name (LdSymbol *symbol); static void ld_lua_symbol_real_get_area (LdSymbol *symbol, LdRectangle *area); +static const LdPointArray *ld_lua_symbol_real_get_terminals (LdSymbol *symbol); static void ld_lua_symbol_real_draw (LdSymbol *symbol, cairo_t *cr); @@ -53,6 +54,7 @@ ld_lua_symbol_class_init (LdLuaSymbolClass *klass) klass->parent_class.get_name = ld_lua_symbol_real_get_name; klass->parent_class.get_human_name = ld_lua_symbol_real_get_human_name; klass->parent_class.get_area = ld_lua_symbol_real_get_area; + klass->parent_class.get_terminals = ld_lua_symbol_real_get_terminals; klass->parent_class.draw = ld_lua_symbol_real_draw; g_type_class_add_private (klass, sizeof (LdLuaSymbolPrivate)); @@ -83,6 +85,9 @@ ld_lua_symbol_finalize (GObject *gobject) if (self->priv->human_name) g_free (self->priv->human_name); + if (self->priv->terminals) + ld_point_array_free (self->priv->terminals); + /* Chain up to the parent class. */ G_OBJECT_CLASS (ld_lua_symbol_parent_class)->finalize (gobject); } @@ -114,6 +119,17 @@ ld_lua_symbol_real_get_area (LdSymbol *symbol, LdRectangle *area) *area = self->priv->area; } +static const LdPointArray * +ld_lua_symbol_real_get_terminals (LdSymbol *symbol) +{ + LdLuaSymbol *self; + + g_return_val_if_fail (LD_IS_LUA_SYMBOL (symbol), NULL); + + self = LD_LUA_SYMBOL (symbol); + return self->priv->terminals; +} + static void ld_lua_symbol_real_draw (LdSymbol *symbol, cairo_t *cr) { diff --git a/src/ld-lua.c b/src/ld-lua.c index 746d2f9..47f2a40 100644 --- a/src/ld-lua.c +++ b/src/ld-lua.c @@ -92,6 +92,8 @@ static int ld_lua_logdiag_register (lua_State *L); static int process_registration (lua_State *L); static gchar *get_translation (lua_State *L, int index); static gboolean read_symbol_area (lua_State *L, int index, LdRectangle *area); +static gboolean read_terminals (lua_State *L, int index, + LdPointArray **terminals); static void push_cairo_object (lua_State *L, LdLuaDrawData *draw_data); static gdouble get_cairo_scale (cairo_t *cr); @@ -474,8 +476,8 @@ process_registration (lua_State *L) if (!read_symbol_area (L, 3, &symbol->priv->area)) return luaL_error (L, "Malformed symbol area array."); - - /* TODO: Read and set the terminals. */ + if (!read_terminals (L, 4, &symbol->priv->terminals)) + return luaL_error (L, "Malformed terminals array."); lua_getfield (L, LUA_REGISTRYINDEX, LD_LUA_SYMBOLS_INDEX); lua_pushlightuserdata (L, symbol); @@ -561,9 +563,62 @@ read_symbol_area (lua_State *L, int index, LdRectangle *area) area->width = ABS (x2 - x1); area->height = ABS (y2 - y1); + lua_pop (L, 4); return TRUE; } +/* + * read_terminals: + * @L: A Lua state. + * @index: Stack index of the table. + * @area: Where the point array will be returned. + * + * Read symbol terminals from a Lua table. + * + * Return value: TRUE on success, FALSE on failure. + */ +static gboolean +read_terminals (lua_State *L, int index, LdPointArray **terminals) +{ + LdPointArray *points; + size_t num_points; + unsigned i = 0; + + num_points = lua_objlen (L, index); + points = ld_point_array_new (num_points); + + lua_pushnil (L); + while (lua_next (L, index) != 0) + { + g_assert (i < num_points); + + if (!lua_istable (L, -1) || lua_objlen (L, -1) != 2) + goto read_terminals_fail; + + lua_rawgeti (L, -1, 1); + if (!lua_isnumber (L, -1)) + goto read_terminals_fail; + points->points[i].x = lua_tonumber (L, -1); + lua_pop (L, 1); + + lua_rawgeti (L, -1, 2); + if (!lua_isnumber (L, -1)) + goto read_terminals_fail; + points->points[i].y = lua_tonumber (L, -1); + + lua_pop (L, 2); + i++; + } + *terminals = points; + return TRUE; + +read_terminals_fail: + ld_point_array_free (points); + *terminals = NULL; + return FALSE; +} + + /* ===== Cairo ============================================================= */ static void diff --git a/src/ld-symbol.c b/src/ld-symbol.c index 24a7ab9..cdc59f5 100644 --- a/src/ld-symbol.c +++ b/src/ld-symbol.c @@ -35,7 +35,8 @@ enum PROP_0, PROP_NAME, PROP_HUMAN_NAME, - PROP_AREA + PROP_AREA, + PROP_TERMINALS }; static void ld_symbol_get_property (GObject *object, guint property_id, @@ -85,6 +86,16 @@ ld_symbol_class_init (LdSymbolClass *klass) "The area of this symbol.", LD_TYPE_RECTANGLE, G_PARAM_READABLE); g_object_class_install_property (object_class, PROP_AREA, pspec); + +/** + * LdSymbol:terminals: + * + * A point array that specifies terminals of this symbol. + */ + pspec = g_param_spec_boxed ("terminals", "Terminals", + "A point array that specifies terminals of this symbol.", + LD_TYPE_POINT_ARRAY, G_PARAM_READABLE); + g_object_class_install_property (object_class, PROP_TERMINALS, pspec); } static void @@ -115,6 +126,9 @@ ld_symbol_get_property (GObject *object, guint property_id, g_value_set_boxed (value, &area); } break; + case PROP_TERMINALS: + g_value_set_boxed (value, ld_symbol_get_terminals (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } @@ -184,6 +198,26 @@ ld_symbol_get_area (LdSymbol *self, LdRectangle *area) klass->get_area (self, area); } +/** + * ld_symbol_get_terminals: + * @self: A symbol object. + * + * Get a list of symbol terminals. + * + * Return value: An #LdPointArray structure. + */ +const LdPointArray * +ld_symbol_get_terminals (LdSymbol *self) +{ + LdSymbolClass *klass; + + g_return_val_if_fail (LD_IS_SYMBOL (self), NULL); + + klass = LD_SYMBOL_GET_CLASS (self); + g_return_val_if_fail (klass->get_terminals != NULL, NULL); + return klass->get_terminals (self); +} + /** * ld_symbol_draw: * @self: A symbol object. diff --git a/src/ld-symbol.h b/src/ld-symbol.h index 43ab4df..409eba5 100644 --- a/src/ld-symbol.h +++ b/src/ld-symbol.h @@ -44,6 +44,7 @@ struct _LdSymbol * @get_name: Get the name of the symbol. * @get_human_name: Get the localized human name of the symbol. * @get_area: Get the area of the symbol. + * @get_terminals: Get a list of symbol terminals. * @draw: Draw the symbol on a Cairo surface. */ struct _LdSymbolClass @@ -53,6 +54,7 @@ struct _LdSymbolClass const gchar *(*get_name) (LdSymbol *self); const gchar *(*get_human_name) (LdSymbol *self); void (*get_area) (LdSymbol *self, LdRectangle *area); + const LdPointArray *(*get_terminals) (LdSymbol *self); void (*draw) (LdSymbol *self, cairo_t *cr); }; @@ -62,12 +64,9 @@ GType ld_symbol_get_type (void) G_GNUC_CONST; const gchar *ld_symbol_get_name (LdSymbol *self); const gchar *ld_symbol_get_human_name (LdSymbol *self); void ld_symbol_get_area (LdSymbol *self, LdRectangle *area); +const LdPointArray *ld_symbol_get_terminals (LdSymbol *self); void ld_symbol_draw (LdSymbol *self, cairo_t *cr); -/* TODO: Interface for terminals. - * Something like a list of gdouble pairs (-> a new structure). - */ - G_END_DECLS