Add support for external shared object renderer
This commit is contained in:
parent
f025a0233d
commit
f54ff7ded6
@ -19,7 +19,7 @@ aux_source_directory("gds-parser" PARSER_SOURCES)
|
|||||||
aux_source_directory("latex-output" LATEX_SOURCES)
|
aux_source_directory("latex-output" LATEX_SOURCES)
|
||||||
aux_source_directory("cairo-output" CAIRO_SOURCES)
|
aux_source_directory("cairo-output" CAIRO_SOURCES)
|
||||||
aux_source_directory("trigonometric" TRIG_SOURCES)
|
aux_source_directory("trigonometric" TRIG_SOURCES)
|
||||||
set(SOURCE "main.c" "layer-selector.c" "mapping-parser.c" "command-line.c" "main-window.c")
|
set(SOURCE "main.c" "layer-selector.c" "mapping-parser.c" "command-line.c" "main-window.c" "external-renderer.c")
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
${SOURCE}
|
${SOURCE}
|
||||||
@ -36,6 +36,6 @@ add_compile_options(-Wall)
|
|||||||
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
|
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
|
||||||
add_dependencies(${PROJECT_NAME} glib-resources)
|
add_dependencies(${PROJECT_NAME} glib-resources)
|
||||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
|
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
|
||||||
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m)
|
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m ${CMAKE_DL_LIBS})
|
||||||
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "mapping-parser.h"
|
#include "mapping-parser.h"
|
||||||
#include "cairo-output/cairo-output.h"
|
#include "cairo-output/cairo-output.h"
|
||||||
#include "latex-output/latex-output.h"
|
#include "latex-output/latex-output.h"
|
||||||
|
#include "external-renderer.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Delete layer_info and free nem element.
|
* @brief Delete layer_info and free nem element.
|
||||||
@ -52,7 +53,7 @@ static void delete_layer_info_with_name(struct layer_info *info)
|
|||||||
|
|
||||||
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
||||||
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
||||||
gboolean pdf_standalone, gboolean svg, char *svg_name)
|
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file)
|
||||||
{
|
{
|
||||||
GList *libs = NULL;
|
GList *libs = NULL;
|
||||||
FILE *tex_file;
|
FILE *tex_file;
|
||||||
@ -71,7 +72,7 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
|
|||||||
struct gds_cell *toplevel_cell = NULL, *temp_cell;
|
struct gds_cell *toplevel_cell = NULL, *temp_cell;
|
||||||
|
|
||||||
/* Check if parameters are valid */
|
/* Check if parameters are valid */
|
||||||
if (!gds_name || ! pdf_name || !tex_name || !layer_file || !cell_name) {
|
if (!gds_name || (!pdf_name && pdf) || (!tex_name && tex) || !layer_file || !cell_name) {
|
||||||
printf("Probably missing argument. Check --help option\n");
|
printf("Probably missing argument. Check --help option\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -144,6 +145,16 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
|
|||||||
fclose(tex_file);
|
fclose(tex_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (so_name && so_out_file) {
|
||||||
|
if (strlen(so_name) == 0 || strlen(so_out_file) == 0)
|
||||||
|
goto ret_clear_list;
|
||||||
|
|
||||||
|
/* Render output using external renderer */
|
||||||
|
printf("Invoking external renderer!\n");
|
||||||
|
external_renderer_render_cell(toplevel_cell, layer_info_list, so_out_file, so_name);
|
||||||
|
printf("External renderer finished!\n");
|
||||||
|
}
|
||||||
|
|
||||||
ret_clear_list:
|
ret_clear_list:
|
||||||
g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name);
|
g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name);
|
||||||
|
|
||||||
|
@ -45,11 +45,13 @@
|
|||||||
* @param pdf_layers TikZ creates OCG layers
|
* @param pdf_layers TikZ creates OCG layers
|
||||||
* @param pdf_standalone LaTeX document is standalone7
|
* @param pdf_standalone LaTeX document is standalone7
|
||||||
* @param svg Render to SVG file
|
* @param svg Render to SVG file
|
||||||
|
* @param so_name Path to shared object of custom renderer
|
||||||
|
* @param so_out_file Output file path for custom renderer
|
||||||
* @param svg_name SVG file name
|
* @param svg_name SVG file name
|
||||||
*/
|
*/
|
||||||
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
||||||
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
||||||
gboolean pdf_standalone, gboolean svg, char *svg_name);
|
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file);
|
||||||
|
|
||||||
#endif /* _COMMAND_LINE_H_ */
|
#endif /* _COMMAND_LINE_H_ */
|
||||||
|
|
||||||
|
70
external-renderer.c
Normal file
70
external-renderer.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*
|
||||||
|
* This file is part of GDSII-Converter.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file external-renderer.c
|
||||||
|
* @brief This file implements the dynamic library loading for the external rendering feature
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MainApplication
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "external-renderer.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path)
|
||||||
|
{
|
||||||
|
int (*so_render_func)(struct gds_cell *, GList *, char *) = NULL;
|
||||||
|
void *so_handle = NULL;
|
||||||
|
char *error_msg;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
/* Check parameter sanity */
|
||||||
|
if (!output_file || !so_path || !toplevel_cell || !layer_info_list) {
|
||||||
|
return -3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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());
|
||||||
|
return -2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load symbol from library */
|
||||||
|
so_render_func = (int (*)(struct gds_cell *, GList *, char *))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
|
||||||
|
if ((error_msg = dlerror()) != NULL) {
|
||||||
|
printf("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_close_so_handle:
|
||||||
|
dlclose(so_handle);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
58
external-renderer.h
Normal file
58
external-renderer.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*
|
||||||
|
* This file is part of GDSII-Converter.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file command-line.c
|
||||||
|
* @brief Render according to command line parameters
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup MainApplication
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EXTERNAL_RENDERER_H_
|
||||||
|
#define _EXTERNAL_RENDERER_H_
|
||||||
|
|
||||||
|
#include "gds-parser/gds-types.h"
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief function name expected to be found in external library.
|
||||||
|
* @detail The function has to be defined as follows:
|
||||||
|
* @code
|
||||||
|
* int function_name(gds_cell *toplevel, GList *layer_info_list, char *output_file_name)
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path);
|
||||||
|
|
||||||
|
#endif /* _EXTERNAL_RENDERER_H_ */
|
||||||
|
|
||||||
|
/** @} */
|
30
main.c
30
main.c
@ -22,6 +22,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include "main-window.h"
|
#include "main-window.h"
|
||||||
#include "command-line.h"
|
#include "command-line.h"
|
||||||
|
#include "external-renderer.h"
|
||||||
|
|
||||||
struct application_data {
|
struct application_data {
|
||||||
GtkApplication *app;
|
GtkApplication *app;
|
||||||
@ -116,22 +117,26 @@ int main(int argc, char **argv)
|
|||||||
gchar *basename;
|
gchar *basename;
|
||||||
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
|
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
|
||||||
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE, svg = FALSE;
|
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE, svg = FALSE;
|
||||||
|
gchar *custom_library_path = NULL;
|
||||||
|
gchar *custom_library_file_name = NULL;
|
||||||
int scale = 1000;
|
int scale = 1000;
|
||||||
int app_status;
|
int app_status;
|
||||||
|
|
||||||
|
|
||||||
GOptionEntry entries[] = {
|
GOptionEntry entries[] = {
|
||||||
{ "tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
|
{"tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
|
||||||
{ "pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", NULL },
|
{"pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", NULL },
|
||||||
//{ "svg", 'S', 0, G_OPTION_ARG_NONE, &svg, "Output SVG image", NULL },
|
//{"svg", 'S', 0, G_OPTION_ARG_NONE, &svg, "Output SVG image", NULL },
|
||||||
{ "scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by <SCALE>", "<SCALE>" },
|
{"scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by <SCALE>", "<SCALE>" },
|
||||||
{ "tex-output", 'o', 0, G_OPTION_ARG_FILENAME, &texname, "Optional path for TeX file", "PATH" },
|
{"tex-output", 'o', 0, G_OPTION_ARG_FILENAME, &texname, "Optional path for TeX file", "PATH" },
|
||||||
{ "pdf-output", 'O', 0, G_OPTION_ARG_FILENAME, &pdfname, "Optional path for PDF file", "PATH" },
|
{"pdf-output", 'O', 0, G_OPTION_ARG_FILENAME, &pdfname, "Optional path for PDF file", "PATH" },
|
||||||
//{ "svg-output", 0, 0, G_OPTION_ARG_FILENAME, &svgname, "Optional path for PDF file", "PATH"},
|
//{"svg-output", 0, 0, G_OPTION_ARG_FILENAME, &svgname, "Optional path for PDF file", "PATH"},
|
||||||
{ "mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
|
{"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
|
||||||
{ "cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
|
{"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
|
||||||
{ "tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
|
{"tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
|
||||||
{ "tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create PDF Layers (OCG)", NULL },
|
{"tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create PDF Layers (OCG)", NULL },
|
||||||
|
{"custom-render-lib", 'P', 0, G_OPTION_ARG_FILENAME, &custom_library_path, "Path to a custom shared object, that implements the " EXTERNAL_LIBRARY_FUNCTION " function", "PATH"},
|
||||||
|
{"external-lib-output", 'e', 0, G_OPTION_ARG_FILENAME, &custom_library_file_name, "Output path for external render library", "PATH"},
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,7 +176,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
|
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
|
||||||
mappingname, cellname, (double)scale,
|
mappingname, cellname, (double)scale,
|
||||||
pdf_layers, pdf_standalone, svg, svgname);
|
pdf_layers, pdf_standalone, svg, svgname,
|
||||||
|
custom_library_path, custom_library_file_name);
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
g_free(pdfname);
|
g_free(pdfname);
|
||||||
g_free(texname);
|
g_free(texname);
|
||||||
|
Loading…
Reference in New Issue
Block a user