diff --git a/include/gds-render/output-renderers/external-renderer.h b/include/gds-render/output-renderers/external-renderer.h index 2ded59c..7847f2c 100644 --- a/include/gds-render/output-renderers/external-renderer.h +++ b/include/gds-render/output-renderers/external-renderer.h @@ -24,35 +24,46 @@ */ /** - * @addtogroup external-renderer + * @addtogroup ExternalRenderer * @{ */ #ifndef _EXTERNAL_RENDERER_H_ #define _EXTERNAL_RENDERER_H_ +#include #include -#include + +G_BEGIN_DECLS + +#define GDS_RENDER_TYPE_EXTERNAL_RENDERER (external_renderer_get_type()) + +G_DECLARE_FINAL_TYPE(ExternalRenderer, external_renderer, GDS_RENDER, EXTERNAL_RENDERER, GdsOutputRenderer) /** * @brief function name expected to be found in external library. * * The function has to be defined as follows: * @code - * int function_name(gds_cell *toplevel, GList *layer_info_list, char *output_file_name) + * int EXTERNAL_LIBRARY_FUNCTION(gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale) * @endcode */ #define EXTERNAL_LIBRARY_FUNCTION "render_cell_to_file" /** - * @brief external_renderer_render_cell - * @param toplevel_cell The toplevel cell to render - * @param layer_info_list The layer information. Contains #layer_info elements - * @param output_file Output file - * @param so_path Path to the shared object file containing #EXTERNAL_LIBRARY_FUNCTION - * @return 0 on success + * @brief Create new ExternalRenderer object + * @return New object */ -int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path); +ExternalRenderer *external_renderer_new(); + +/** + * @brief Create new ExternalRenderer object with specified shared object path + * @param so_path Path to shared object, the rendering function is searched in + * @return New object. + */ +ExternalRenderer *external_renderer_new_with_so(const char *so_path); + +G_END_DECLS #endif /* _EXTERNAL_RENDERER_H_ */ diff --git a/output-renderers/external-renderer.c b/output-renderers/external-renderer.c index 66d7f78..4af96aa 100644 --- a/output-renderers/external-renderer.c +++ b/output-renderers/external-renderer.c @@ -24,7 +24,7 @@ */ /** - * @addtogroup external-renderer + * @addtogroup ExternalRenderer * @{ */ @@ -33,10 +33,25 @@ #include -int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, - char *output_file, char *so_path) +struct _ExternalRenderer { + GdsOutputRenderer parent; + const char *shared_object_path; +}; + +G_DEFINE_TYPE(ExternalRenderer, external_renderer, GDS_RENDER_TYPE_OUTPUT_RENDERER) + +/** + * @brief Execute render function in shared object to render the supplied cell + * @param toplevel_cell Cell to render + * @param layer_info_list Layer information (Color etc.) + * @param output_file Destination file + * @param so_path Path to shared object + * @return 0 if successful + */ +static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, + const char *output_file, double scale, const char *so_path) { - int (*so_render_func)(struct gds_cell *, GList *, char *) = NULL; + int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL; void *so_handle = NULL; char *error_msg; int ret = 0; @@ -48,25 +63,53 @@ int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_i /* Load shared object */ so_handle = dlopen(so_path, RTLD_LAZY); if (!so_handle) { - printf("Could not load external library '%s'\nDetailed error is:\n%s\n", so_path, dlerror()); + g_error("Could not load external library '%s'\nDetailed error is:\n%s", so_path, dlerror()); return -2000; } /* Load symbol from library */ - so_render_func = (int (*)(struct gds_cell *, GList *, char *))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION); + so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION); error_msg = dlerror(); if (error_msg != NULL) { - printf("Rendering function not found in library:\n%s\n", error_msg); + g_error("Rendering function not found in library:\n%s\n", error_msg); goto ret_close_so_handle; } /* Execute */ if (so_render_func) - so_render_func(toplevel_cell, layer_info_list, output_file); + ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale); ret_close_so_handle: dlclose(so_handle); return ret; } +static int external_renderer_render_output(GdsOutputRenderer *renderer, + struct gds_cell *cell, + GList *layer_infos, + const char *output_file, + double scale) +{ + ExternalRenderer *ext_renderer = GDS_RENDER_EXTERNAL_RENDERER(renderer); + + return external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path); +} + +static void external_renderer_class_init(ExternalRendererClass *klass) +{ + GdsOutputRendererClass *inherited_parent_class; + + inherited_parent_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass); + + /* Override virtual function */ + inherited_parent_class->render_output = external_renderer_render_output; +} + +static void external_renderer_init(ExternalRenderer *self) +{ + self->shared_object_path = NULL; +} + + + /** @} */