Compare commits
No commits in common. "ea27443b39ba61110beb152175f5f28bad514e96" and "74bdbe6d7959fee0a54d8b7b50aa66a94b16153e" have entirely different histories.
ea27443b39
...
74bdbe6d79
@ -6,7 +6,7 @@ pkg_search_module(GLIB REQUIRED glib-2.0)
|
|||||||
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
|
||||||
pkg_check_modules(CAIRO REQUIRED cairo)
|
pkg_check_modules(CAIRO REQUIRED cairo)
|
||||||
|
|
||||||
add_subdirectory(resources)
|
add_subdirectory(glade)
|
||||||
add_subdirectory(doxygen)
|
add_subdirectory(doxygen)
|
||||||
add_subdirectory(version)
|
add_subdirectory(version)
|
||||||
|
|
||||||
@ -15,29 +15,31 @@ link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
|
|||||||
add_definitions(${GLIB2_CFLAGS_OTHER})
|
add_definitions(${GLIB2_CFLAGS_OTHER})
|
||||||
|
|
||||||
aux_source_directory("widgets" LAYER_SOURCES)
|
aux_source_directory("widgets" LAYER_SOURCES)
|
||||||
aux_source_directory("cell-selector" CELL_SELECTOR_SOURCES)
|
aux_source_directory("tree-renderer" RENDERER_SOURCES)
|
||||||
aux_source_directory("gds-utils" GDS_SOURCES)
|
aux_source_directory("gds-utils" GDS_SOURCES)
|
||||||
aux_source_directory("output-renderers" OUTPUT_RENDERER_SOURCES)
|
aux_source_directory("latex-renderer" LATEX_SOURCES)
|
||||||
|
aux_source_directory("cairo-renderer" CAIRO_SOURCES)
|
||||||
aux_source_directory("geometric" GEOMETRIC_SOURCES)
|
aux_source_directory("geometric" GEOMETRIC_SOURCES)
|
||||||
aux_source_directory("layer" LAYER_SELECTOR_SOURCES)
|
aux_source_directory("layer" LAYER_SELECTOR_SOURCES)
|
||||||
set(SOURCE "main.c" "command-line.c" "gds-render-gui.c")
|
set(SOURCE "main.c" "command-line.c" "gds-render-gui.c" "external-renderer.c")
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
${SOURCE}
|
${SOURCE}
|
||||||
${LAYER_SOURCES}
|
${LAYER_SOURCES}
|
||||||
${CELL_SELECTOR_SOURCES}
|
${RENDERER_SOURCES}
|
||||||
${GDS_SOURCES}
|
${GDS_SOURCES}
|
||||||
${OUTPUT_RENDERER_SOURCES}
|
${LATEX_SOURCES}
|
||||||
|
${CAIRO_SOURCES}
|
||||||
${GEOMETRIC_SOURCES}
|
${GEOMETRIC_SOURCES}
|
||||||
${LAYER_SELECTOR_SOURCES}
|
${LAYER_SELECTOR_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_compile_options(-Wall)
|
add_compile_options(-Wall)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/resources/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)
|
||||||
add_dependencies(${PROJECT_NAME} version)
|
add_dependencies(${PROJECT_NAME} version)
|
||||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/resources/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 version ${CMAKE_DL_LIBS})
|
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})
|
||||||
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @addtogroup CairoRenderer
|
/** @addtogroup Cairo-Renderer
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -32,16 +32,7 @@
|
|||||||
#include <cairo-pdf.h>
|
#include <cairo-pdf.h>
|
||||||
#include <cairo-svg.h>
|
#include <cairo-svg.h>
|
||||||
|
|
||||||
#include <gds-render/output-renderers/cairo-renderer.h>
|
#include <gds-render/cairo-renderer/cairo-output.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
struct _CairoRenderer {
|
|
||||||
GdsOutputRenderer parent;
|
|
||||||
gboolean svg; /**< @brief TRUE: SVG output, FALSE: PDF output */
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(CairoRenderer, cairo_renderer, GDS_RENDER_TYPE_OUTPUT_RENDERER)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The cairo_layer struct
|
* @brief The cairo_layer struct
|
||||||
@ -74,7 +65,7 @@ static void revert_inherited_transform(struct cairo_layer *layers)
|
|||||||
* @param origin Origin translation
|
* @param origin Origin translation
|
||||||
* @param magnification Scaling
|
* @param magnification Scaling
|
||||||
* @param flipping Mirror image on x-axis before rotating
|
* @param flipping Mirror image on x-axis before rotating
|
||||||
* @param rotation Rotation in degrees
|
* @param rotation Rotattion in degrees
|
||||||
* @param scale Scale the image down by. Only used for sclaing origin coordinates. Not applied to layer.
|
* @param scale Scale the image down by. Only used for sclaing origin coordinates. Not applied to layer.
|
||||||
*/
|
*/
|
||||||
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
|
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
|
||||||
@ -140,9 +131,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
/* Get layer renderer */
|
/* Get layer renderer */
|
||||||
if (gfx->layer >= MAX_LAYERS)
|
if (gfx->layer >= MAX_LAYERS)
|
||||||
continue;
|
continue;
|
||||||
|
if ((cr = layers[gfx->layer].cr) == NULL)
|
||||||
cr = layers[gfx->layer].cr;
|
|
||||||
if (cr == NULL)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Apply settings */
|
/* Apply settings */
|
||||||
@ -169,6 +158,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
cairo_move_to(cr, vertex->x/scale, vertex->y/scale);
|
cairo_move_to(cr, vertex->x/scale, vertex->y/scale);
|
||||||
else
|
else
|
||||||
cairo_line_to(cr, vertex->x/scale, vertex->y/scale);
|
cairo_line_to(cr, vertex->x/scale, vertex->y/scale);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create graphics object */
|
/* Create graphics object */
|
||||||
@ -184,23 +174,15 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} /* for gfx list */
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale)
|
||||||
* @brief Render \p cell to a PDF file specified by \p pdf_file
|
|
||||||
* @param cell Toplevel cell to @ref Cairo-Renderer
|
|
||||||
* @param layer_infos List of layer information. Specifies color and layer stacking
|
|
||||||
* @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated
|
|
||||||
* @param svg_file SVG output file. Set to NULL if no SVG file has to be generated
|
|
||||||
* @param scale Scale the output image down by \p scale
|
|
||||||
* @return Error
|
|
||||||
*/
|
|
||||||
static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, const char *pdf_file,
|
|
||||||
const char *svg_file, double scale)
|
|
||||||
{
|
{
|
||||||
cairo_surface_t *pdf_surface = NULL, *svg_surface = NULL;
|
cairo_surface_t *pdf_surface, *svg_surface;
|
||||||
cairo_t *pdf_cr = NULL, *svg_cr = NULL;
|
cairo_t *pdf_cr, *svg_cr;
|
||||||
struct layer_info *linfo;
|
struct layer_info *linfo;
|
||||||
struct cairo_layer *layers;
|
struct cairo_layer *layers;
|
||||||
struct cairo_layer *lay;
|
struct cairo_layer *lay;
|
||||||
@ -208,27 +190,10 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
int i;
|
int i;
|
||||||
double rec_x0, rec_y0, rec_width, rec_height;
|
double rec_x0, rec_y0, rec_width, rec_height;
|
||||||
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
|
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
|
||||||
pid_t process_id;
|
|
||||||
|
|
||||||
if (pdf_file == NULL && svg_file == NULL) {
|
if (pdf_file == NULL && svg_file == NULL) {
|
||||||
/* No output specified */
|
/* No output specified */
|
||||||
return -1;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fork to a new child process. This ensures the memory leaks (see issue #16) in Cairo don't
|
|
||||||
* brick everything.
|
|
||||||
*
|
|
||||||
* And by the way: This now bricks all Windows compatibility. Deal with it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Use fork for production code and -1 as value for debugging */
|
|
||||||
process_id = fork();
|
|
||||||
//process_id = -1;
|
|
||||||
if (process_id < 0) {
|
|
||||||
/* Well... shit... We have to run it in our process. */
|
|
||||||
} else if (process_id > 0) {
|
|
||||||
/* Woohoo... Successfully dumped the shitty code to an unknowing victim */
|
|
||||||
goto ret_parent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
|
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
|
||||||
@ -243,10 +208,6 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
|
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
|
||||||
linfo = (struct layer_info *)info_list->data;
|
linfo = (struct layer_info *)info_list->data;
|
||||||
if (linfo->layer < MAX_LAYERS) {
|
if (linfo->layer < MAX_LAYERS) {
|
||||||
/* Layer shall not be rendered */
|
|
||||||
if (!linfo->render)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
lay = &(layers[(unsigned int)linfo->layer]);
|
lay = &(layers[(unsigned int)linfo->layer]);
|
||||||
lay->linfo = linfo;
|
lay->linfo = linfo;
|
||||||
lay->rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
|
lay->rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
|
||||||
@ -272,9 +233,6 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!linfo->render)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Print size */
|
/* Print size */
|
||||||
cairo_recording_surface_ink_extents(layers[linfo->layer].rec, &rec_x0, &rec_y0,
|
cairo_recording_surface_ink_extents(layers[linfo->layer].rec, &rec_x0, &rec_y0,
|
||||||
&rec_width, &rec_height);
|
&rec_width, &rec_height);
|
||||||
@ -318,18 +276,16 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!linfo->render)
|
if (pdf_file) {
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pdf_file && pdf_cr) {
|
|
||||||
cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
|
cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
|
||||||
cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);
|
cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (svg_file && svg_cr) {
|
if (svg_file) {
|
||||||
cairo_set_source_surface(svg_cr, layers[linfo->layer].rec, -xmin, -ymin);
|
cairo_set_source_surface(svg_cr, layers[linfo->layer].rec, -xmin, -ymin);
|
||||||
cairo_paint_with_alpha(svg_cr, linfo->color.alpha);
|
cairo_paint_with_alpha(svg_cr, linfo->color.alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pdf_file) {
|
if (pdf_file) {
|
||||||
@ -354,86 +310,7 @@ ret_clear_layers:
|
|||||||
}
|
}
|
||||||
free(layers);
|
free(layers);
|
||||||
|
|
||||||
printf("Cairo export finished. It might still be buggy!\n");
|
printf("cairo export finished. It might still be buggy!\n");
|
||||||
|
|
||||||
/* If forked, suspend process */
|
|
||||||
if (process_id == 0)
|
|
||||||
exit(0);
|
|
||||||
|
|
||||||
/* Fork didn't work. Just return here */
|
|
||||||
return 0;
|
|
||||||
ret_parent:
|
|
||||||
waitpid(process_id, NULL, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cairo_renderer_init(CairoRenderer *self)
|
|
||||||
{
|
|
||||||
/* PDF default */
|
|
||||||
self->svg = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
CairoRenderer *c_renderer = GDS_RENDER_CAIRO_RENDERER(renderer);
|
|
||||||
const char *pdf_file = NULL;
|
|
||||||
const char *svg_file = NULL;
|
|
||||||
LayerSettings *settings;
|
|
||||||
GList *layer_infos = NULL;
|
|
||||||
const char *output_file;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!c_renderer)
|
|
||||||
return -2000;
|
|
||||||
|
|
||||||
output_file = gds_output_renderer_get_output_file(renderer);
|
|
||||||
settings = gds_output_renderer_get_and_ref_layer_settings(renderer);
|
|
||||||
|
|
||||||
/* Set layer info list. In case of failure it remains NULL */
|
|
||||||
if (settings)
|
|
||||||
layer_infos = layer_settings_get_layer_info_list(settings);
|
|
||||||
|
|
||||||
if (c_renderer->svg == TRUE)
|
|
||||||
svg_file = output_file;
|
|
||||||
else
|
|
||||||
pdf_file = output_file;
|
|
||||||
|
|
||||||
gds_output_renderer_update_gui_status_from_async(renderer, "Rendering Cairo Output...");
|
|
||||||
ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale);
|
|
||||||
|
|
||||||
if (settings)
|
|
||||||
g_object_unref(settings);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cairo_renderer_class_init(CairoRendererClass *klass)
|
|
||||||
{
|
|
||||||
GdsOutputRendererClass *renderer_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass);
|
|
||||||
|
|
||||||
renderer_class->render_output = cairo_renderer_render_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
CairoRenderer *cairo_renderer_new_pdf()
|
|
||||||
{
|
|
||||||
CairoRenderer *renderer;
|
|
||||||
|
|
||||||
renderer = GDS_RENDER_CAIRO_RENDERER(g_object_new(GDS_RENDER_TYPE_CAIRO_RENDERER, NULL));
|
|
||||||
renderer->svg = FALSE;
|
|
||||||
|
|
||||||
return renderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
CairoRenderer *cairo_renderer_new_svg()
|
|
||||||
{
|
|
||||||
CairoRenderer *renderer;
|
|
||||||
|
|
||||||
renderer = GDS_RENDER_CAIRO_RENDERER(g_object_new(GDS_RENDER_TYPE_CAIRO_RENDERER, NULL));
|
|
||||||
renderer->svg = TRUE;
|
|
||||||
|
|
||||||
return renderer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
250
command-line.c
250
command-line.c
@ -33,179 +33,128 @@
|
|||||||
#include <gds-render/command-line.h>
|
#include <gds-render/command-line.h>
|
||||||
#include <gds-render/gds-utils/gds-parser.h>
|
#include <gds-render/gds-utils/gds-parser.h>
|
||||||
#include <gds-render/layer/mapping-parser.h>
|
#include <gds-render/layer/mapping-parser.h>
|
||||||
#include <gds-render/layer/layer-settings.h>
|
#include <gds-render/layer/layer-info.h>
|
||||||
#include <gds-render/output-renderers/cairo-renderer.h>
|
#include <gds-render/cairo-renderer/cairo-output.h>
|
||||||
#include <gds-render/output-renderers/latex-renderer.h>
|
#include <gds-render/latex-renderer/latex-output.h>
|
||||||
#include <gds-render/output-renderers/external-renderer.h>
|
#include <gds-render/external-renderer.h>
|
||||||
#include <gds-render/gds-utils/gds-tree-checker.h>
|
#include <gds-render/gds-utils/gds-tree-checker.h>
|
||||||
|
|
||||||
static int string_array_count(char **string_array)
|
/**
|
||||||
|
* @brief Delete layer_info and free nem element.
|
||||||
|
*
|
||||||
|
* Like delete_layer_info_struct() but also frees layer_info::name
|
||||||
|
* @param info
|
||||||
|
* @warning This function must not be used if the layer_info::name field references the internal storage strings if e.g. an entry field
|
||||||
|
*/
|
||||||
|
static void delete_layer_info_with_name(struct layer_info *info)
|
||||||
{
|
{
|
||||||
int count;
|
if (info) {
|
||||||
|
if (info->name)
|
||||||
if (!string_array)
|
g_free(info->name);
|
||||||
return 0;
|
free(info);
|
||||||
|
}
|
||||||
for (count = 0; *string_array; string_array++)
|
|
||||||
count++;
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_renderers(char **renderers,
|
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
||||||
char **output_file_names,
|
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
||||||
gboolean tex_layers,
|
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file)
|
||||||
gboolean tex_standalone,
|
|
||||||
const char *so_path,
|
|
||||||
GList **renderer_list,
|
|
||||||
LayerSettings *layer_settings)
|
|
||||||
{
|
{
|
||||||
char **renderer_iter;
|
|
||||||
char *current_renderer;
|
|
||||||
int idx;
|
|
||||||
char *current_out_file;
|
|
||||||
int count_render, count_out;
|
|
||||||
GdsOutputRenderer *output_renderer;
|
|
||||||
|
|
||||||
if (!renderer_list)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (!renderers || !output_file_names) {
|
|
||||||
fprintf(stderr, "Please specify renderers and file names\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
count_render = string_array_count(renderers);
|
|
||||||
count_out = string_array_count(output_file_names);
|
|
||||||
if (count_render != count_out) {
|
|
||||||
fprintf(stderr, "Count of renderers %d does not match count of output file names %d\n",
|
|
||||||
count_render, count_out);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse cmd line parameters */
|
|
||||||
for (renderer_iter = renderers, idx = 0; *renderer_iter; renderer_iter++, idx++) {
|
|
||||||
current_renderer = *renderer_iter;
|
|
||||||
current_out_file = output_file_names[idx];
|
|
||||||
|
|
||||||
/* File valid ? */
|
|
||||||
if (!current_out_file || !current_out_file[0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!strcmp(current_renderer, "tikz")) {
|
|
||||||
output_renderer = GDS_RENDER_OUTPUT_RENDERER(latex_renderer_new_with_options(tex_layers,
|
|
||||||
tex_standalone));
|
|
||||||
} else if (!strcmp(current_renderer, "pdf")) {
|
|
||||||
output_renderer = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_pdf());
|
|
||||||
} else if (!strcmp(current_renderer, "svg")) {
|
|
||||||
output_renderer = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_svg());
|
|
||||||
} else if (!strcmp(current_renderer, "ext")) {
|
|
||||||
if (!so_path) {
|
|
||||||
fprintf(stderr, "Please specify shared object for external renderer. Will ignore this renderer.\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
output_renderer = GDS_RENDER_OUTPUT_RENDERER(external_renderer_new_with_so(so_path));
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
gds_output_renderer_set_output_file(output_renderer, current_out_file);
|
|
||||||
gds_output_renderer_set_layer_settings(output_renderer, layer_settings);
|
|
||||||
*renderer_list = g_list_append(*renderer_list, output_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct gds_cell *find_gds_cell_in_lib(struct gds_library *lib, const char *cell_name)
|
|
||||||
{
|
|
||||||
GList *cell_list;
|
|
||||||
struct gds_cell *return_cell = NULL;
|
|
||||||
struct gds_cell *temp_cell;
|
|
||||||
|
|
||||||
for (cell_list = lib->cells; cell_list; cell_list = g_list_next(cell_list)) {
|
|
||||||
temp_cell = (struct gds_cell *)cell_list->data;
|
|
||||||
if (!strncmp(temp_cell->name, cell_name, CELL_NAME_MAX)) {
|
|
||||||
return_cell = temp_cell;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return return_cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
int command_line_convert_gds(const char *gds_name,
|
|
||||||
const char *cell_name,
|
|
||||||
char **renderers,
|
|
||||||
char **output_file_names,
|
|
||||||
const char *layer_file,
|
|
||||||
const char *so_path,
|
|
||||||
gboolean tex_standalone,
|
|
||||||
gboolean tex_layers,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
GList *libs = NULL;
|
GList *libs = NULL;
|
||||||
|
FILE *tex_file;
|
||||||
int res;
|
int res;
|
||||||
GList *renderer_list = NULL;
|
GFile *file;
|
||||||
GList *list_iter;
|
int i;
|
||||||
|
GFileInputStream *stream;
|
||||||
|
GDataInputStream *dstream;
|
||||||
|
gboolean layer_export;
|
||||||
|
GdkRGBA layer_color;
|
||||||
|
int layer;
|
||||||
|
char *layer_name;
|
||||||
|
GList *layer_info_list = NULL;
|
||||||
|
GList *cell_list;
|
||||||
|
struct layer_info *linfo_temp;
|
||||||
struct gds_library *first_lib;
|
struct gds_library *first_lib;
|
||||||
struct gds_cell *toplevel_cell = NULL;
|
struct gds_cell *toplevel_cell = NULL, *temp_cell;
|
||||||
LayerSettings *layer_sett;
|
|
||||||
GdsOutputRenderer *current_renderer;
|
|
||||||
|
|
||||||
/* Check if parameters are valid */
|
/* Check if parameters are valid */
|
||||||
if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) {
|
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 -2;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load layer_settings */
|
|
||||||
layer_sett = layer_settings_new();
|
|
||||||
layer_settings_load_from_csv(layer_sett, layer_file);
|
|
||||||
|
|
||||||
/* Create renderers */
|
|
||||||
if (create_renderers(renderers, output_file_names, tex_layers, tex_standalone,
|
|
||||||
so_path, &renderer_list, layer_sett))
|
|
||||||
goto ret_destroy_layer_mapping;
|
|
||||||
|
|
||||||
|
|
||||||
/* Load GDS */
|
/* Load GDS */
|
||||||
clear_lib_list(&libs);
|
clear_lib_list(&libs);
|
||||||
res = parse_gds_from_file(gds_name, &libs);
|
res = parse_gds_from_file(gds_name, &libs);
|
||||||
if (res)
|
if (res)
|
||||||
goto ret_destroy_library_list;
|
goto ret_destroy_library_list;
|
||||||
|
|
||||||
|
file = g_file_new_for_path(layer_file);
|
||||||
|
stream = g_file_read(file, NULL, NULL);
|
||||||
|
|
||||||
|
if (!stream) {
|
||||||
|
printf("Layer mapping not readable!\n");
|
||||||
|
goto ret_destroy_file;
|
||||||
|
}
|
||||||
|
dstream = g_data_input_stream_new(G_INPUT_STREAM(stream));
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
res = mapping_parser_load_line(dstream, &layer_export, &layer_name, &layer, &layer_color);
|
||||||
|
if (res == 0) {
|
||||||
|
if (!layer_export)
|
||||||
|
continue;
|
||||||
|
linfo_temp = (struct layer_info *)malloc(sizeof(struct layer_info));
|
||||||
|
if (!linfo_temp) {
|
||||||
|
printf("Out of memory\n");
|
||||||
|
goto ret_clear_layer_list;
|
||||||
|
}
|
||||||
|
linfo_temp->color.alpha = layer_color.alpha;
|
||||||
|
linfo_temp->color.red = layer_color.red;
|
||||||
|
linfo_temp->color.green = layer_color.green;
|
||||||
|
linfo_temp->color.blue = layer_color.blue;
|
||||||
|
linfo_temp->name = layer_name;
|
||||||
|
linfo_temp->stacked_position = i++;
|
||||||
|
linfo_temp->layer = layer;
|
||||||
|
layer_info_list = g_list_append(layer_info_list, (gpointer)linfo_temp);
|
||||||
|
}
|
||||||
|
} while(res >= 0);
|
||||||
|
|
||||||
|
|
||||||
/* find_cell in first library. */
|
/* find_cell in first library. */
|
||||||
if (!libs)
|
if (!libs)
|
||||||
goto ret_clear_renderers;
|
goto ret_clear_layer_list;
|
||||||
|
|
||||||
first_lib = (struct gds_library *)libs->data;
|
first_lib = (struct gds_library *)libs->data;
|
||||||
if (!first_lib) {
|
if (!first_lib) {
|
||||||
fprintf(stderr, "No library in library list. This should not happen.\n");
|
fprintf(stderr, "No library in library list. This should not happen.\n");
|
||||||
/* This is safe. Library destruction can handle an empty list element */
|
goto ret_clear_layer_list;
|
||||||
goto ret_destroy_library_list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find cell in first library */
|
for (cell_list = first_lib->cells; cell_list != NULL; cell_list = g_list_next(cell_list)) {
|
||||||
toplevel_cell = find_gds_cell_in_lib(first_lib, cell_name);
|
temp_cell = (struct gds_cell *)cell_list->data;
|
||||||
|
if (!strcmp(temp_cell->name, cell_name)) {
|
||||||
|
toplevel_cell = temp_cell;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!toplevel_cell) {
|
if (!toplevel_cell) {
|
||||||
printf("Couldn't find cell in first library!\n");
|
printf("Couldn't find cell in first library!\n");
|
||||||
goto ret_destroy_library_list;
|
goto ret_clear_layer_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if cell passes vital checks */
|
/* Check if cell passes vital checks */
|
||||||
res = gds_tree_check_reference_loops(toplevel_cell->parent_library);
|
res = gds_tree_check_reference_loops(toplevel_cell->parent_library);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Checking library %s failed.\n", first_lib->name);
|
fprintf(stderr, "Checking library %s failed.\n", first_lib->name);
|
||||||
goto ret_destroy_library_list;
|
goto ret_clear_layer_list;
|
||||||
} else if (res > 0) {
|
} else if (res > 0) {
|
||||||
fprintf(stderr, "%d reference loops found.\n", res);
|
fprintf(stderr, "%d reference loops found.\n", res);
|
||||||
|
|
||||||
/* do further checking if the specified cell and/or its subcells are affected */
|
/* do further checking if the specified cell and/or its subcells are affected */
|
||||||
if (toplevel_cell->checks.affected_by_reference_loop == 1) {
|
if (toplevel_cell->checks.affected_by_reference_loop == 1) {
|
||||||
fprintf(stderr, "Cell is affected by reference loop. Abort!\n");
|
fprintf(stderr, "Cell is affected by reference loop. Abort!\n");
|
||||||
goto ret_destroy_library_list;
|
goto ret_clear_layer_list;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,21 +165,40 @@ int command_line_convert_gds(const char *gds_name,
|
|||||||
* Deal with it.
|
* Deal with it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Execute all rendererer instances */
|
/* Render outputs */
|
||||||
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) {
|
if (pdf == TRUE || svg == TRUE) {
|
||||||
current_renderer = GDS_RENDER_OUTPUT_RENDERER(list_iter->data);
|
cairo_render_cell_to_vector_file(toplevel_cell, layer_info_list, (pdf == TRUE ? pdf_name : NULL),
|
||||||
gds_output_renderer_render_output(current_renderer, toplevel_cell, scale);
|
(svg == TRUE ? svg_name : NULL), scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tex == TRUE) {
|
||||||
|
tex_file = fopen(tex_name, "w");
|
||||||
|
if (!tex_file)
|
||||||
|
goto ret_clear_layer_list;
|
||||||
|
latex_render_cell_to_code(toplevel_cell, layer_info_list, tex_file, scale, pdf_layers, pdf_standalone);
|
||||||
|
fclose(tex_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (so_name && so_out_file) {
|
||||||
|
if (strlen(so_name) == 0 || strlen(so_out_file) == 0)
|
||||||
|
goto ret_clear_layer_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_layer_list:
|
||||||
|
g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name);
|
||||||
|
|
||||||
|
g_object_unref(dstream);
|
||||||
|
g_object_unref(stream);
|
||||||
|
ret_destroy_file:
|
||||||
|
g_object_unref(file);
|
||||||
|
/* Delete all allocated libraries */
|
||||||
ret_destroy_library_list:
|
ret_destroy_library_list:
|
||||||
clear_lib_list(&libs);
|
clear_lib_list(&libs);
|
||||||
ret_clear_renderers:
|
|
||||||
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) {
|
|
||||||
g_object_unref(list_iter->data);
|
|
||||||
}
|
|
||||||
ret_destroy_layer_mapping:
|
|
||||||
g_object_unref(layer_sett);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -244,7 +244,7 @@ SEPARATE_MEMBER_PAGES = NO
|
|||||||
# uses this value to replace tabs by spaces in code fragments.
|
# uses this value to replace tabs by spaces in code fragments.
|
||||||
# Minimum value: 1, maximum value: 16, default value: 4.
|
# Minimum value: 1, maximum value: 16, default value: 4.
|
||||||
|
|
||||||
TAB_SIZE = 8
|
TAB_SIZE = 4
|
||||||
|
|
||||||
# This tag can be used to specify a number of aliases that act as commands in
|
# This tag can be used to specify a number of aliases that act as commands in
|
||||||
# the documentation. An alias has the form:
|
# the documentation. An alias has the form:
|
||||||
@ -2419,7 +2419,7 @@ DIRECTORY_GRAPH = YES
|
|||||||
# The default value is: png.
|
# The default value is: png.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
DOT_IMAGE_FORMAT = svg
|
DOT_IMAGE_FORMAT = png
|
||||||
|
|
||||||
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
|
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
|
||||||
# enable generation of interactive SVG images that allow zooming and panning.
|
# enable generation of interactive SVG images that allow zooming and panning.
|
||||||
@ -2431,7 +2431,7 @@ DOT_IMAGE_FORMAT = svg
|
|||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||||
|
|
||||||
INTERACTIVE_SVG = YES
|
INTERACTIVE_SVG = NO
|
||||||
|
|
||||||
# The DOT_PATH tag can be used to specify the path where the dot tool can be
|
# The DOT_PATH tag can be used to specify the path where the dot tool can be
|
||||||
# found. If left blank, it is assumed the dot tool can be found in the path.
|
# found. If left blank, it is assumed the dot tool can be found in the path.
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* @defgroup ActivityBar Activity Bar
|
|
||||||
* @ingroup Widgets
|
|
||||||
*
|
|
||||||
* Activity Status Bar
|
|
||||||
*/
|
|
@ -1,4 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* @defgroup Cairo-Renderer Cairo Renderer
|
* @defgroup Cairo-Renderer Cairo Renderer
|
||||||
* @ingroup GdsOutputRenderer
|
* @ingroup renderers
|
||||||
*/
|
*/
|
||||||
|
@ -1,15 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* @defgroup ExternalRenderer External Shared Object Renderer
|
* @defgroup external-renderer External Shared Object Renderer
|
||||||
* @ingroup GdsOutputRenderer
|
* @ingroup renderers
|
||||||
*
|
|
||||||
* @subsection ExternalRendererProps Properties
|
|
||||||
* This class inherits all properties from its parent @ref GdsOutputRenderer.
|
|
||||||
* In addition to that, it implements the following properties:
|
|
||||||
*
|
|
||||||
* Property Name | Description
|
|
||||||
* -----------------|----------------------------------------------------------------
|
|
||||||
* shared-object-path | Path to the shared object used for rendering
|
|
||||||
*
|
|
||||||
* All these properties have to be set for rendering.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* @defgroup GdsOutputRenderer GDS Output Renderer base class
|
|
||||||
*
|
|
||||||
* The renderers are used to convert the cell structures read from the GDS layout file
|
|
||||||
* into different output formats.
|
|
||||||
*
|
|
||||||
* The GdsOutputRenderer base class is used to derive all renderers from.
|
|
||||||
*
|
|
||||||
* @warning Although the GdsOutputRenderer class provides compatibility for asynchronous rendering,
|
|
||||||
* the class is not thread safe / re-entrant. Only use it from a signle context. Not even the rendering function called is allowed to modifiy this object.
|
|
||||||
*
|
|
||||||
* A allowed function to be called from the async rendering thread is #gds_output_renderer_update_gui_status_from_async and the get functions for the properties.
|
|
||||||
*
|
|
||||||
* @note The context that owned the renderer has to ensure that only one rendering is active at a time for a single instance of a renderer.
|
|
||||||
*
|
|
||||||
* By default this class implements the following features:
|
|
||||||
*
|
|
||||||
* @subsection GdsOutputRendererProps Properties
|
|
||||||
* Property Name | Description
|
|
||||||
* -----------------|----------------------------------------------------------------
|
|
||||||
* layer-settings | LayerSettings object containing the layer rendering information
|
|
||||||
* output-file | Output file name for rendering
|
|
||||||
*
|
|
||||||
* All these properties have to be set for rendering.
|
|
||||||
*
|
|
||||||
* @subsection GdsOutputRendererSignals Signals / Events
|
|
||||||
* Signal Name | Description | Callback prototype
|
|
||||||
* -----------------|-------------------------------------------------|-----------------------------------------------------------
|
|
||||||
* async-finished | The asynchronous rendering is finished | void callback(GdsOutputRenderer *src, gpointer user_data)
|
|
||||||
* progress-changed | The asynchronous rendering progress changed | void callback(GdsOutputRenderer *src, const char *progress, gpointer user_data)
|
|
||||||
*
|
|
||||||
* @note The `char *progress` supplied to the callback function must not be modified or freed.
|
|
||||||
*
|
|
||||||
*/
|
|
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 35 KiB |
@ -1,16 +1,4 @@
|
|||||||
/**
|
/**
|
||||||
* @defgroup LaTeX-Renderer LaTeX/TikZ Renderer
|
* @defgroup LaTeX-Renderer LaTeX/TikZ Renderer
|
||||||
* @ingroup GdsOutputRenderer
|
* @ingroup renderers
|
||||||
*
|
|
||||||
* This is the class implementing the Latex / tikz output rendering
|
|
||||||
|
|
||||||
* @subsection LaTeXRendererProps Properties
|
|
||||||
* This class inherits all properties from its parent @ref GdsOutputRenderer.
|
|
||||||
* In addition to that, it implements the following properties:
|
|
||||||
*
|
|
||||||
* Property Name | Description
|
|
||||||
* -----------------|----------------------------------------------------------------
|
|
||||||
* standalone | Configure output LaTeX document to be standalone compilable (requires standalone documentclass)
|
|
||||||
* pdf-layers | Create OCG layers in LaTeX output
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
9
doxygen/renderers.dox
Normal file
9
doxygen/renderers.dox
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @defgroup renderers Output Renderers
|
||||||
|
*
|
||||||
|
* The renderers are used to convert the cell structures read from the GDS layout file
|
||||||
|
* into different output formats.
|
||||||
|
*
|
||||||
|
* Currently the renders are statically implemented without the use of GObjects.
|
||||||
|
* This will probably change in future releases in order to make it easier to integrate new rendering methods.
|
||||||
|
*/
|
@ -3,25 +3,19 @@
|
|||||||
@section cmd Command Line Interface
|
@section cmd Command Line Interface
|
||||||
To use the application on the command line check 'gds-render `--`help'.
|
To use the application on the command line check 'gds-render `--`help'.
|
||||||
|
|
||||||
Usage:
|
|
||||||
gds-render [OPTION…] FILE - Convert GDS file <FILE> to graphic
|
|
||||||
|
|
||||||
Help Options:
|
|
||||||
-h, '--'help Show help options
|
|
||||||
'--'help-all Show all help options
|
|
||||||
'--'help-gtk Show GTK+ Options
|
|
||||||
|
|
||||||
Application Options:
|
Application Options:
|
||||||
-v, '--'version Print version
|
- -t, `--`tikz Output TikZ code
|
||||||
-r, '--'renderer=pdf|svg|tikz|ext Renderer to use
|
- -p, `--`pdf Output PDF document
|
||||||
-s, '--'scale=<SCALE> Divide output coordinates by <SCALE>
|
- -s, `--`scale=SCALE Divide output coordinates by SCALE
|
||||||
-o, '--'output-file=PATH Output file path
|
- -o, `--`tex-output=PATH Optional path for TeX file
|
||||||
-m, '--'mapping=PATH Path for Layer Mapping File
|
- -O, `--`pdf-output=PATH Optional path for PDF file
|
||||||
-c, '--'cell=NAME Cell to render
|
- -m, `--`mapping=PATH Path for Layer Mapping File
|
||||||
-a, '--'tex-standalone Create standalone PDF
|
- -c, `--`cell=NAME Cell to render
|
||||||
-l, '--'tex-layers Create PDF Layers (OCG)
|
- -a, `--`tex-standalone Create standalone PDF
|
||||||
-P, '--'custom-render-lib=PATH Path to a custom shared object, that implements the render_cell_to_file function
|
- -l, `--`tex-layers Create PDF Layers (OCG)
|
||||||
'--'display=DISPLAY X display to use
|
- -P, `--`custom-render-lib=PATH Path to a custom shared object, that implements the render_cell_to_file function
|
||||||
|
- -e, `--`external-lib-output=PATH Output path for external render library
|
||||||
|
- `--`display=DISPLAY X display to use
|
||||||
|
|
||||||
|
|
||||||
@section gui Graphical User Interface
|
@section gui Graphical User Interface
|
||||||
@ -33,7 +27,7 @@ It is possible to export the layer configurations so they can be used later on.
|
|||||||
@image html gui.png
|
@image html gui.png
|
||||||
@image latex gui.png
|
@image latex gui.png
|
||||||
|
|
||||||
The cell selector on the left shows the GDS Libraries and Cells. The cells are marked green if all references inside the cell could be found. If not all references could be found, the cell is marked orange. This doens't show if child cells have missing childs. Only one level of the hierarchy is checked in order to make it easier to spot an errorneous cell. Cells with missing child cells are still renderable but '--' obviously '--' faulty. If a cell or any sub-cell contains a reference loop, the cell is marked red. In this case it can't be selected for rendering.
|
The cell selector on the left shows the GDS Libraries and Cells. The cells are marked green if all references inside the cell could be found. If not all references could be found, the cell is marked orange. This doens't show if child cells have missing childs. Only one level of the hierarchy is checked in order to make it easier to spot an errorneous cell. Cells with missing child cells are still renderable but -- obviously -- faulty. If a cell or any sub-cell contains a reference loop, the cell is marked red. In this case it can't be selected for rendering.
|
||||||
|
|
||||||
In the above image the cell is green; so everything is okay.
|
In the above image the cell is green; so everything is okay.
|
||||||
|
|
||||||
|
@ -31,6 +31,6 @@ In tabular form: *v1.0-rc4-41-gaa41373-dirty*
|
|||||||
| 1.0-rc4 | 41 | aa41373 | yes |
|
| 1.0-rc4 | 41 | aa41373 | yes |
|
||||||
|
|
||||||
|
|
||||||
This git-based version number is automatically put into the application and this documentation during the application's compilation / the documentation's generation. For this *git* is needed. Therefore, it is highly recommended to have 'git' installed for compilation although it is no build dependency. In case of a missing git installation, the string "! version not set !" is compiled into the application.
|
This git-based version number is automatically put into the application and this doxumentation during the application's compilation / the documentation's generation. For this *git* is needed. Therefore, it is highly recommended to have 'git' installed for compilation although it is no build dependency. In case of a missing git installation, the string "! version not set !" is compiled into the application.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
72
external-renderer.c
Normal file
72
external-renderer.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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 external-renderer
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <gds-render/external-renderer.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);
|
||||||
|
error_msg = dlerror();
|
||||||
|
if (error_msg != 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
182
gds-render-gui.c
182
gds-render-gui.c
@ -34,11 +34,10 @@
|
|||||||
#include <gds-render/gds-utils/gds-parser.h>
|
#include <gds-render/gds-utils/gds-parser.h>
|
||||||
#include <gds-render/gds-utils/gds-tree-checker.h>
|
#include <gds-render/gds-utils/gds-tree-checker.h>
|
||||||
#include <gds-render/layer/layer-selector.h>
|
#include <gds-render/layer/layer-selector.h>
|
||||||
#include <gds-render/widgets/activity-bar.h>
|
#include <gds-render/tree-renderer/tree-store.h>
|
||||||
#include <gds-render/cell-selector/tree-store.h>
|
#include <gds-render/tree-renderer/lib-cell-renderer.h>
|
||||||
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
#include <gds-render/latex-renderer/latex-output.h>
|
||||||
#include <gds-render/output-renderers/latex-renderer.h>
|
#include <gds-render/cairo-renderer/cairo-output.h>
|
||||||
#include <gds-render/output-renderers/cairo-renderer.h>
|
|
||||||
#include <gds-render/widgets/conv-settings-dialog.h>
|
#include <gds-render/widgets/conv-settings-dialog.h>
|
||||||
#include <gds-render/geometric/cell-geometrics.h>
|
#include <gds-render/geometric/cell-geometrics.h>
|
||||||
#include <gds-render/version.h>
|
#include <gds-render/version.h>
|
||||||
@ -47,11 +46,6 @@ enum gds_render_gui_signal_sig_ids {SIGNAL_WINDOW_CLOSED = 0, SIGNAL_COUNT};
|
|||||||
|
|
||||||
static guint gds_render_gui_signals[SIGNAL_COUNT];
|
static guint gds_render_gui_signals[SIGNAL_COUNT];
|
||||||
|
|
||||||
struct gui_button_states {
|
|
||||||
gboolean rendering_active;
|
|
||||||
gboolean valid_cell_selected;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _GdsRenderGui {
|
struct _GdsRenderGui {
|
||||||
/* Parent GObject */
|
/* Parent GObject */
|
||||||
GObject parent;
|
GObject parent;
|
||||||
@ -59,18 +53,12 @@ struct _GdsRenderGui {
|
|||||||
/* Custom fields */
|
/* Custom fields */
|
||||||
GtkWindow *main_window;
|
GtkWindow *main_window;
|
||||||
GtkWidget *convert_button;
|
GtkWidget *convert_button;
|
||||||
GtkWidget *open_button;
|
|
||||||
GtkWidget *load_layer_button;
|
|
||||||
GtkWidget *save_layer_button;
|
|
||||||
GtkTreeStore *cell_tree_store;
|
GtkTreeStore *cell_tree_store;
|
||||||
GtkWidget *cell_search_entry;
|
GtkWidget *cell_search_entry;
|
||||||
LayerSelector *layer_selector;
|
LayerSelector *layer_selector;
|
||||||
GtkTreeView *cell_tree_view;
|
GtkTreeView *cell_tree_view;
|
||||||
GList *gds_libraries;
|
GList *gds_libraries;
|
||||||
ActivityBar *activity_status_bar;
|
|
||||||
struct render_settings render_dialog_settings;
|
struct render_settings render_dialog_settings;
|
||||||
ColorPalette *palette;
|
|
||||||
struct gui_button_states button_state_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT)
|
G_DEFINE_TYPE(GdsRenderGui, gds_render_gui, G_TYPE_OBJECT)
|
||||||
@ -249,60 +237,6 @@ end_destroy:
|
|||||||
gtk_widget_destroy(open_dialog);
|
gtk_widget_destroy(open_dialog);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_button_state_changes(GdsRenderGui *self)
|
|
||||||
{
|
|
||||||
gboolean convert_button_state = FALSE;
|
|
||||||
gboolean open_gds_button_state = FALSE;
|
|
||||||
|
|
||||||
/* Calculate states */
|
|
||||||
if (!self->button_state_data.rendering_active) {
|
|
||||||
open_gds_button_state = TRUE;
|
|
||||||
if (self->button_state_data.valid_cell_selected)
|
|
||||||
convert_button_state = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply states */
|
|
||||||
gtk_widget_set_sensitive(self->convert_button, convert_button_state);
|
|
||||||
gtk_widget_set_sensitive(self->open_button, open_gds_button_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Callback for auto coloring button
|
|
||||||
* @param button
|
|
||||||
* @param user
|
|
||||||
*/
|
|
||||||
static void on_auto_color_clicked(gpointer button, gpointer user)
|
|
||||||
{
|
|
||||||
GdsRenderGui *self;
|
|
||||||
(void)button;
|
|
||||||
|
|
||||||
self = RENDERER_GUI(user);
|
|
||||||
layer_selector_auto_color_layers(self->layer_selector, self->palette, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpointer gui)
|
|
||||||
{
|
|
||||||
GdsRenderGui *self;
|
|
||||||
|
|
||||||
self = RENDERER_GUI(gui);
|
|
||||||
|
|
||||||
self->button_state_data.rendering_active = FALSE;
|
|
||||||
process_button_state_changes(self);
|
|
||||||
activity_bar_set_ready(self->activity_status_bar);
|
|
||||||
|
|
||||||
g_object_unref(renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer, const char *status_message, gpointer data)
|
|
||||||
{
|
|
||||||
GdsRenderGui *gui;
|
|
||||||
(void)renderer;
|
|
||||||
|
|
||||||
gui = RENDERER_GUI(data);
|
|
||||||
|
|
||||||
activity_bar_set_busy(gui->activity_status_bar, status_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert button callback
|
* @brief Convert button callback
|
||||||
* @param button
|
* @param button
|
||||||
@ -315,7 +249,9 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
|||||||
GtkTreeSelection *selection;
|
GtkTreeSelection *selection;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
GtkTreeModel *model;
|
GtkTreeModel *model;
|
||||||
|
GList *layer_list;
|
||||||
struct gds_cell *cell_to_render;
|
struct gds_cell *cell_to_render;
|
||||||
|
FILE *output_file;
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
RendererSettingsDialog *settings;
|
RendererSettingsDialog *settings;
|
||||||
GtkFileFilter *filter;
|
GtkFileFilter *filter;
|
||||||
@ -324,18 +260,12 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
|||||||
union bounding_box cell_box;
|
union bounding_box cell_box;
|
||||||
unsigned int height, width;
|
unsigned int height, width;
|
||||||
struct render_settings *sett;
|
struct render_settings *sett;
|
||||||
LayerSettings *layer_settings;
|
|
||||||
GdsOutputRenderer *render_engine;
|
|
||||||
|
|
||||||
self = RENDERER_GUI(user);
|
self = RENDERER_GUI(user);
|
||||||
|
|
||||||
if (!self)
|
if (!self)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Abort if rendering is already active */
|
|
||||||
if (self->button_state_data.rendering_active == TRUE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sett = &self->render_dialog_settings;
|
sett = &self->render_dialog_settings;
|
||||||
|
|
||||||
/* Get selected cell */
|
/* Get selected cell */
|
||||||
@ -349,7 +279,7 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* Get layers that are rendered */
|
/* Get layers that are rendered */
|
||||||
layer_settings = layer_selector_export_rendered_layer_info(self->layer_selector);
|
layer_list = layer_selector_export_rendered_layer_info(self->layer_selector);
|
||||||
|
|
||||||
/* Calculate cell size in DB units */
|
/* Calculate cell size in DB units */
|
||||||
bounding_box_prepare_empty(&cell_box);
|
bounding_box_prepare_empty(&cell_box);
|
||||||
@ -412,52 +342,30 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
|||||||
|
|
||||||
switch (sett->renderer) {
|
switch (sett->renderer) {
|
||||||
case RENDERER_LATEX_TIKZ:
|
case RENDERER_LATEX_TIKZ:
|
||||||
render_engine =
|
output_file = fopen(file_name, "w");
|
||||||
GDS_RENDER_OUTPUT_RENDERER(latex_renderer_new_with_options(sett->tex_pdf_layers,
|
latex_render_cell_to_code(cell_to_render, layer_list, output_file, sett->scale,
|
||||||
sett->tex_standalone));
|
sett->tex_pdf_layers, sett->tex_standalone);
|
||||||
|
fclose(output_file);
|
||||||
break;
|
break;
|
||||||
case RENDERER_CAIROGRAPHICS_SVG:
|
case RENDERER_CAIROGRAPHICS_SVG:
|
||||||
render_engine = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_svg());
|
|
||||||
break;
|
|
||||||
case RENDERER_CAIROGRAPHICS_PDF:
|
case RENDERER_CAIROGRAPHICS_PDF:
|
||||||
render_engine = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_pdf());
|
cairo_render_cell_to_vector_file(cell_to_render, layer_list,
|
||||||
break;
|
(sett->renderer == RENDERER_CAIROGRAPHICS_PDF
|
||||||
default:
|
? file_name
|
||||||
/* Abort rendering */
|
: NULL),
|
||||||
render_engine = NULL;
|
(sett->renderer == RENDERER_CAIROGRAPHICS_SVG
|
||||||
|
? file_name
|
||||||
|
: NULL),
|
||||||
|
sett->scale);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (render_engine) {
|
|
||||||
gds_output_renderer_set_output_file(render_engine, file_name);
|
|
||||||
gds_output_renderer_set_layer_settings(render_engine, layer_settings);
|
|
||||||
/* Prevent user from overwriting library or triggering additional conversion */
|
|
||||||
self->button_state_data.rendering_active = TRUE;
|
|
||||||
process_button_state_changes(self);
|
|
||||||
|
|
||||||
g_signal_connect(render_engine, "async-finished", G_CALLBACK(async_rendering_finished_callback),
|
|
||||||
self);
|
|
||||||
|
|
||||||
activity_bar_set_busy(self->activity_status_bar, "Rendering cell...");
|
|
||||||
/* TODO: Replace this with asynchronous rendering. However, this fixes issue #19 */
|
|
||||||
|
|
||||||
g_signal_connect(render_engine, "progress-changed",
|
|
||||||
G_CALLBACK(async_rendering_status_update_callback), self);
|
|
||||||
gds_output_renderer_render_output_async(render_engine, cell_to_render, sett->scale);
|
|
||||||
|
|
||||||
|
|
||||||
//self->button_state_data.rendering_active = FALSE;
|
|
||||||
|
|
||||||
//g_object_unref(render_engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(file_name);
|
g_free(file_name);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
gtk_widget_destroy(dialog);
|
gtk_widget_destroy(dialog);
|
||||||
}
|
}
|
||||||
ret_layer_destroy:
|
ret_layer_destroy:
|
||||||
g_object_unref(layer_settings);
|
g_list_free_full(layer_list, (GDestroyNotify)layer_info_delete_struct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -477,6 +385,7 @@ static void cell_tree_view_activated(gpointer tree_view, GtkTreePath *path,
|
|||||||
on_convert_clicked(NULL, user);
|
on_convert_clicked(NULL, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback for cell-selection change event
|
* @brief Callback for cell-selection change event
|
||||||
*
|
*
|
||||||
@ -492,12 +401,10 @@ static void cell_selection_changed(GtkTreeSelection *sel, GdsRenderGui *self)
|
|||||||
|
|
||||||
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
|
if (gtk_tree_selection_get_selected(sel, &model, &iter)) {
|
||||||
/* Node selected. Show button */
|
/* Node selected. Show button */
|
||||||
self->button_state_data.valid_cell_selected = TRUE;
|
gtk_widget_set_sensitive(self->convert_button, TRUE);
|
||||||
} else {
|
} else {
|
||||||
self->button_state_data.valid_cell_selected = FALSE;
|
gtk_widget_set_sensitive(self->convert_button, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
process_button_state_changes(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sort_up_callback(GtkWidget *widget, gpointer user)
|
static void sort_up_callback(GtkWidget *widget, gpointer user)
|
||||||
@ -535,11 +442,6 @@ static void gds_render_gui_dispose(GObject *gobject)
|
|||||||
g_clear_object(&self->layer_selector);
|
g_clear_object(&self->layer_selector);
|
||||||
g_clear_object(&self->cell_tree_store);
|
g_clear_object(&self->cell_tree_store);
|
||||||
g_clear_object(&self->cell_search_entry);
|
g_clear_object(&self->cell_search_entry);
|
||||||
g_clear_object(&self->activity_status_bar);
|
|
||||||
g_clear_object(&self->palette);
|
|
||||||
g_clear_object(&self->load_layer_button);
|
|
||||||
g_clear_object(&self->save_layer_button);
|
|
||||||
g_clear_object(&self->open_button);
|
|
||||||
|
|
||||||
if (self->main_window) {
|
if (self->main_window) {
|
||||||
g_signal_handlers_destroy(self->main_window);
|
g_signal_handlers_destroy(self->main_window);
|
||||||
@ -582,10 +484,8 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
struct tree_stores *cell_selector_stores;
|
struct tree_stores *cell_selector_stores;
|
||||||
GtkWidget *sort_up_button;
|
GtkWidget *sort_up_button;
|
||||||
GtkWidget *sort_down_button;
|
GtkWidget *sort_down_button;
|
||||||
GtkWidget *activity_bar_box;
|
|
||||||
GtkWidget *auto_color_button;
|
|
||||||
|
|
||||||
main_builder = gtk_builder_new_from_resource("/gui/main.glade");
|
main_builder = gtk_builder_new_from_resource("/main.glade");
|
||||||
|
|
||||||
self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
|
self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
|
||||||
self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
|
self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
|
||||||
@ -595,8 +495,7 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
self->cell_tree_store = cell_selector_stores->base_store;
|
self->cell_tree_store = cell_selector_stores->base_store;
|
||||||
|
|
||||||
self->main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
|
self->main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
|
||||||
self->open_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds"));
|
g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")),
|
||||||
g_signal_connect(self->open_button,
|
|
||||||
"clicked", G_CALLBACK(on_load_gds), (gpointer)self);
|
"clicked", G_CALLBACK(on_load_gds), (gpointer)self);
|
||||||
|
|
||||||
self->convert_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button"));
|
self->convert_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button"));
|
||||||
@ -606,7 +505,6 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
/* Create layer selector */
|
/* Create layer selector */
|
||||||
self->layer_selector = layer_selector_new(GTK_LIST_BOX(listbox));
|
self->layer_selector = layer_selector_new(GTK_LIST_BOX(listbox));
|
||||||
|
|
||||||
activity_bar_box = GTK_WIDGET(gtk_builder_get_object(main_builder, "activity-bar"));
|
|
||||||
|
|
||||||
/* Callback for selection change of cell selector */
|
/* Callback for selection change of cell selector */
|
||||||
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(self->cell_tree_view)), "changed",
|
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(self->cell_tree_view)), "changed",
|
||||||
@ -625,25 +523,17 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), self);
|
g_signal_connect(sort_down_button, "clicked", G_CALLBACK(sort_down_callback), self);
|
||||||
|
|
||||||
/* Set buttons for loading and saving */
|
/* Set buttons for loading and saving */
|
||||||
self->load_layer_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping"));
|
layer_selector_set_load_mapping_button(self->layer_selector,
|
||||||
self->save_layer_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping"));
|
GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-mapping")),
|
||||||
layer_selector_set_load_mapping_button(self->layer_selector, self->load_layer_button, self->main_window);
|
self->main_window);
|
||||||
layer_selector_set_save_mapping_button(self->layer_selector, self->save_layer_button, self->main_window);
|
layer_selector_set_save_mapping_button(self->layer_selector, GTK_WIDGET(gtk_builder_get_object(main_builder, "button-save-mapping")),
|
||||||
|
self->main_window);
|
||||||
|
|
||||||
/* Connect delete-event */
|
/* Connect delete-event */
|
||||||
g_signal_connect(GTK_WIDGET(self->main_window), "delete-event",
|
g_signal_connect(GTK_WIDGET(self->main_window), "delete-event",
|
||||||
G_CALLBACK(on_window_close), self);
|
G_CALLBACK(on_window_close), self);
|
||||||
|
|
||||||
/* Create and apply ActivityBar */
|
g_object_unref(main_builder);
|
||||||
self->activity_status_bar = activity_bar_new();
|
|
||||||
gtk_container_add(GTK_CONTAINER(activity_bar_box), GTK_WIDGET(self->activity_status_bar));
|
|
||||||
gtk_widget_show(GTK_WIDGET(self->activity_status_bar));
|
|
||||||
|
|
||||||
/* Create color palette */
|
|
||||||
self->palette = color_palette_new_from_resource("/data/color-palette.txt");
|
|
||||||
auto_color_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "auto-color-button"));
|
|
||||||
g_signal_connect(auto_color_button, "clicked", G_CALLBACK(on_auto_color_clicked), self);
|
|
||||||
|
|
||||||
|
|
||||||
/* Set default conversion/rendering settings */
|
/* Set default conversion/rendering settings */
|
||||||
self->render_dialog_settings.scale = 1000;
|
self->render_dialog_settings.scale = 1000;
|
||||||
@ -651,24 +541,14 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
self->render_dialog_settings.tex_pdf_layers = FALSE;
|
self->render_dialog_settings.tex_pdf_layers = FALSE;
|
||||||
self->render_dialog_settings.tex_standalone = FALSE;
|
self->render_dialog_settings.tex_standalone = FALSE;
|
||||||
|
|
||||||
g_object_unref(main_builder);
|
|
||||||
|
|
||||||
/* Setup default button sensibility data */
|
|
||||||
self->button_state_data.rendering_active = FALSE;
|
|
||||||
self->button_state_data.valid_cell_selected = FALSE;
|
|
||||||
|
|
||||||
/* Reference all objects referenced by this object */
|
/* Reference all objects referenced by this object */
|
||||||
g_object_ref(self->activity_status_bar);
|
|
||||||
g_object_ref(self->main_window);
|
g_object_ref(self->main_window);
|
||||||
g_object_ref(self->cell_tree_view);
|
g_object_ref(self->cell_tree_view);
|
||||||
g_object_ref(self->convert_button);
|
g_object_ref(self->convert_button);
|
||||||
g_object_ref(self->layer_selector);
|
g_object_ref(self->layer_selector);
|
||||||
g_object_ref(self->cell_tree_store);
|
g_object_ref(self->cell_tree_store);
|
||||||
g_object_ref(self->cell_search_entry);
|
g_object_ref(self->cell_search_entry);
|
||||||
g_object_ref(self->palette);
|
|
||||||
g_object_ref(self->open_button);
|
|
||||||
g_object_ref(self->load_layer_button);
|
|
||||||
g_object_ref(self->save_layer_button);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdsRenderGui *gds_render_gui_new()
|
GdsRenderGui *gds_render_gui_new()
|
||||||
|
@ -53,8 +53,7 @@
|
|||||||
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
|
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
|
||||||
|
|
||||||
#if GDS_PRINT_DEBUG_INFOS
|
#if GDS_PRINT_DEBUG_INFOS
|
||||||
/**< @brief standard printf. But can be disabled in code. */
|
#define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But can be disabled in code */
|
||||||
#define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
|
||||||
#else
|
#else
|
||||||
#define GDS_INF(fmt, ...)
|
#define GDS_INF(fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
@ -980,7 +979,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
|
|||||||
} else if (current_a_reference) {
|
} else if (current_a_reference) {
|
||||||
name_array_cell_ref(current_a_reference, (unsigned int)read, workbuff);
|
name_array_cell_ref(current_a_reference, (unsigned int)read, workbuff);
|
||||||
} else {
|
} else {
|
||||||
GDS_ERROR("Reference name set outside of cell reference");
|
GDS_ERROR("reference name set outside of cell reference.\n");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WIDTH:
|
case WIDTH:
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* @file gds-tree-checker.c
|
* @file gds-tree-checker.c
|
||||||
* @brief Checking functions of a cell tree
|
* @brief Checking functions of a cell tree
|
||||||
*
|
*
|
||||||
* This file contains checking functions for the GDS cell tree.
|
* This file contains cehcking functions for the GDS cell tree.
|
||||||
* These functions include checks if all child references could be resolved,
|
* These functions include checks if all child references could be resolved,
|
||||||
* and if the cell tree contains loops.
|
* and if the cell tree contains loops.
|
||||||
*
|
*
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#include <gds-render/geometric/vector-operations.h>
|
#include <gds-render/geometric/vector-operations.h>
|
||||||
|
|
||||||
#define ABS_DBL(a) ((a) < 0.0 ? -(a) : (a))
|
#define ABS_DBL(a) ((a) < 0 ? -(a) : (a))
|
||||||
|
|
||||||
double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b)
|
double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@ add_custom_target(glib-resources DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
|||||||
add_custom_command(DEPENDS
|
add_custom_command(DEPENDS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/*.glade
|
${CMAKE_CURRENT_SOURCE_DIR}/*.glade
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/resources.xml
|
${CMAKE_CURRENT_SOURCE_DIR}/resources.xml
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/color-palette.txt
|
|
||||||
OUTPUT
|
OUTPUT
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
${CMAKE_CURRENT_BINARY_DIR}/resources.c
|
||||||
COMMAND
|
COMMAND
|
@ -2,20 +2,15 @@
|
|||||||
<!-- Generated with glade 3.22.1 -->
|
<!-- Generated with glade 3.22.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.20"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
<object class="GtkImage" id="color-img">
|
<object class="GtkImage" id="image1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-select-color</property>
|
<property name="stock">gtk-go-up</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="load-mapping-img">
|
<object class="GtkImage" id="image2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-open</property>
|
<property name="stock">gtk-go-down</property>
|
||||||
</object>
|
|
||||||
<object class="GtkImage" id="save-mapping-img">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="stock">gtk-save-as</property>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkWindow" id="main-window">
|
<object class="GtkWindow" id="main-window">
|
||||||
<property name="height_request">250</property>
|
<property name="height_request">250</property>
|
||||||
@ -48,8 +43,6 @@
|
|||||||
<property name="sensitive">False</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="image">load-mapping-img</property>
|
|
||||||
<property name="always_show_image">True</property>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="suggested-action"/>
|
<class name="suggested-action"/>
|
||||||
</style>
|
</style>
|
||||||
@ -65,8 +58,6 @@
|
|||||||
<property name="sensitive">False</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">True</property>
|
<property name="receives_default">True</property>
|
||||||
<property name="image">save-mapping-img</property>
|
|
||||||
<property name="always_show_image">True</property>
|
|
||||||
<style>
|
<style>
|
||||||
<class name="suggested-action"/>
|
<class name="suggested-action"/>
|
||||||
</style>
|
</style>
|
||||||
@ -99,144 +90,42 @@
|
|||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkSearchEntry" id="cell-search">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="primary_icon_name">edit-find-symbolic</property>
|
||||||
<child>
|
<property name="primary_icon_activatable">False</property>
|
||||||
<object class="GtkSearchEntry" id="cell-search">
|
<property name="primary_icon_sensitive">False</property>
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="primary_icon_name">edit-find-symbolic</property>
|
|
||||||
<property name="primary_icon_activatable">False</property>
|
|
||||||
<property name="primary_icon_sensitive">False</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="hscrollbar_policy">never</property>
|
|
||||||
<property name="shadow_type">in</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkTreeView" id="cell-tree">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="enable_search">False</property>
|
|
||||||
<property name="enable_grid_lines">both</property>
|
|
||||||
<child internal-child="selection">
|
|
||||||
<object class="GtkTreeSelection"/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">True</property>
|
<property name="expand">False</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkScrolledWindow">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="hscrollbar_policy">never</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkTreeView" id="cell-tree">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="button-up-sort">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="image">sort-up-img</property>
|
|
||||||
<property name="always_show_image">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="button-down-sort">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="image">sort-down-img</property>
|
|
||||||
<property name="always_show_image">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="auto-color-button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
<property name="image">color-img</property>
|
|
||||||
<property name="always_show_image">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">False</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<object class="GtkScrolledWindow">
|
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="hscrollbar_policy">never</property>
|
<property name="headers_clickable">False</property>
|
||||||
<property name="shadow_type">in</property>
|
<property name="enable_search">False</property>
|
||||||
<child>
|
<property name="enable_grid_lines">both</property>
|
||||||
<object class="GtkViewport">
|
<child internal-child="selection">
|
||||||
<property name="visible">True</property>
|
<object class="GtkTreeSelection"/>
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkListBox" id="layer-list">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="selection_mode">none</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">1</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@ -253,31 +142,83 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="activity-bar">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<object class="GtkBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-up-sort">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image1</property>
|
||||||
|
<property name="always_show_image">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="button-down-sort">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="image">image2</property>
|
||||||
|
<property name="always_show_image">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="hscrollbar_policy">never</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkViewport">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkListBox" id="layer-list">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="selection_mode">none</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">False</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="sort-down-img">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="stock">gtk-sort-ascending</property>
|
|
||||||
</object>
|
|
||||||
<object class="GtkImage" id="sort-up-img">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="stock">gtk-sort-descending</property>
|
|
||||||
</object>
|
|
||||||
</interface>
|
</interface>
|
12
glade/resources.xml
Normal file
12
glade/resources.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<gresources>
|
||||||
|
<gresource prefix="/">
|
||||||
|
<file compressed="true">main.glade</file>
|
||||||
|
<file compressed="true">about.glade</file>
|
||||||
|
<file>layer-widget.glade</file>
|
||||||
|
<file>dialog.glade</file>
|
||||||
|
<file compressed="true" alias="logo.svg">../icon/gds-render.svg</file>
|
||||||
|
</gresource>
|
||||||
|
</gresources>
|
||||||
|
|
||||||
|
|
@ -25,36 +25,24 @@
|
|||||||
#define _CAIRO_OUTPUT_H_
|
#define _CAIRO_OUTPUT_H_
|
||||||
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
#include <gds-render/output-renderers/gds-output-renderer.h>
|
#include <gds-render/layer/layer-info.h>
|
||||||
#include <glib-object.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
/** @addtogroup Cairo-Renderer
|
||||||
|
|
||||||
/** @addtogroup CairoRenderer
|
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(CairoRenderer, cairo_renderer, GDS_RENDER, CAIRO_RENDERER, GdsOutputRenderer)
|
|
||||||
|
|
||||||
#define GDS_RENDER_TYPE_CAIRO_RENDERER (cairo_renderer_get_type())
|
|
||||||
|
|
||||||
#define MAX_LAYERS (300) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/
|
#define MAX_LAYERS (300) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create new CairoRenderer for SVG output
|
* @brief Render \p cell to a PDF file specified by \p pdf_file
|
||||||
* @return New object
|
* @param cell Toplevel cell to @ref Cairo-Renderer
|
||||||
|
* @param layer_infos List of layer information. Specifies color and layer stacking
|
||||||
|
* @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated
|
||||||
|
* @param svg_file SVG output file. Set to NULL if no SVG file has to be generated
|
||||||
|
* @param scale Scale the output image down by \p scale
|
||||||
*/
|
*/
|
||||||
CairoRenderer *cairo_renderer_new_svg();
|
void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create new CairoRenderer for PDF output
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
CairoRenderer *cairo_renderer_new_pdf();
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* _CAIRO_OUTPUT_H_ */
|
#endif /* _CAIRO_OUTPUT_H_ */
|
@ -34,27 +34,27 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert GDS according to command line parameters
|
* @brief Convert GDS according to supplied parameters
|
||||||
* @param gds_name Path to GDS File
|
* @param gds_name GDS File path
|
||||||
* @param cell_name Cell name
|
* @param pdf_name Cairo-PDF path
|
||||||
* @param renderers Renderer ids
|
* @param tex_name TeX/TikZ path
|
||||||
* @param output_file_names Output file names
|
* @param pdf Render Cairo
|
||||||
|
* @param tex Render LaTeX
|
||||||
* @param layer_file Layer mapping file
|
* @param layer_file Layer mapping file
|
||||||
* @param so_path Shared object
|
* @param cell_name Cell name to render
|
||||||
* @param tex_standalone Standalone TeX
|
* @param scale Scale image down by this value
|
||||||
* @param tec_layers TeX OCR layers
|
* @param pdf_layers TikZ creates OCG layers
|
||||||
* @param scale Scale value
|
* @param pdf_standalone LaTeX document is standalone7
|
||||||
* @return Error code, 0 if successful
|
* @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
|
||||||
|
*
|
||||||
|
* @note This function is pretty damn retarded (Lots of parameters). Will be reworked when generating GObjects for renderers.
|
||||||
*/
|
*/
|
||||||
int command_line_convert_gds(const char *gds_name,
|
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
|
||||||
const char *cell_name,
|
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
|
||||||
char **renderers,
|
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file);
|
||||||
char **output_file_names,
|
|
||||||
const char *layer_file,
|
|
||||||
const char *so_path,
|
|
||||||
gboolean tex_standalone,
|
|
||||||
gboolean tex_layers,
|
|
||||||
double scale);
|
|
||||||
|
|
||||||
#endif /* _COMMAND_LINE_H_ */
|
#endif /* _COMMAND_LINE_H_ */
|
||||||
|
|
||||||
|
@ -24,46 +24,35 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup ExternalRenderer
|
* @addtogroup external-renderer
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _EXTERNAL_RENDERER_H_
|
#ifndef _EXTERNAL_RENDERER_H_
|
||||||
#define _EXTERNAL_RENDERER_H_
|
#define _EXTERNAL_RENDERER_H_
|
||||||
|
|
||||||
#include <gds-render/output-renderers/gds-output-renderer.h>
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
|
#include <glib.h>
|
||||||
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.
|
* @brief function name expected to be found in external library.
|
||||||
*
|
*
|
||||||
* The function has to be defined as follows:
|
* The function has to be defined as follows:
|
||||||
* @code
|
* @code
|
||||||
* int EXTERNAL_LIBRARY_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale)
|
* int function_name(gds_cell *toplevel, GList *layer_info_list, char *output_file_name)
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
#define EXTERNAL_LIBRARY_FUNCTION "render_cell_to_file"
|
#define EXTERNAL_LIBRARY_FUNCTION "render_cell_to_file"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create new ExternalRenderer object
|
* @brief external_renderer_render_cell
|
||||||
* @return New object
|
* @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
|
||||||
*/
|
*/
|
||||||
ExternalRenderer *external_renderer_new();
|
int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path);
|
||||||
|
|
||||||
/**
|
|
||||||
* @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_ */
|
#endif /* _EXTERNAL_RENDERER_H_ */
|
||||||
|
|
@ -23,35 +23,21 @@
|
|||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GDSPARSER_H_
|
|
||||||
#define _GDSPARSER_H_
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup GDS-Utilities
|
* @addtogroup GDS-Utilities
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _GDSPARSER_H_
|
||||||
|
#define _GDSPARSER_H_
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
|
|
||||||
#define GDS_PRINT_DEBUG_INFOS (0) /**< @brief 1: Print infos, 0: Don't print */
|
#define GDS_PRINT_DEBUG_INFOS (0) /**< @brief 1: Print infos, 0: Don't print */
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Parse a GDS file
|
|
||||||
*
|
|
||||||
* This function parses a GDS File and creates a list of libraries,
|
|
||||||
* which then contain the different cells.
|
|
||||||
*
|
|
||||||
* The function appends The detected libraries to the \p library_array list.
|
|
||||||
* The library array may be empty, meaning *library_list may be NULL.
|
|
||||||
*
|
|
||||||
* @param[in] filename Path to the GDS file
|
|
||||||
* @param[in,out] library_array GList Pointer.
|
|
||||||
* @return 0 if successful
|
|
||||||
*/
|
|
||||||
int parse_gds_from_file(const char *filename, GList **library_array);
|
int parse_gds_from_file(const char *filename, GList **library_array);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deletes all libraries including cells, references etc.
|
* @brief Deletes all libraries including cells, references etc.
|
||||||
* @param library_list Pointer to a list of #gds_library. Is set to NULL after completion.
|
* @param library_list Pointer to a list of #gds_library. Is set to NULL after completion.
|
||||||
@ -61,4 +47,4 @@ int clear_lib_list(GList **library_list);
|
|||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* _GDSPARSER_H_ */
|
#endif /* _GDSPARSE_H_ */
|
||||||
|
@ -58,7 +58,7 @@ enum graphics_type
|
|||||||
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2}; /**< Path line caps */
|
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2}; /**< Path line caps */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A point in the 2D plane. Sometimes reffered to as vertex
|
* @brief A point in the 2D plane. Sometimes references as vertex
|
||||||
*/
|
*/
|
||||||
struct gds_point {
|
struct gds_point {
|
||||||
int x;
|
int x;
|
||||||
|
56
include/gds-render/latex-renderer/latex-output.h
Normal file
56
include/gds-render/latex-renderer/latex-output.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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 latex-output.h
|
||||||
|
* @brief LaTeX output renderer
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __LATEX_OUTPUT_H__
|
||||||
|
#define __LATEX_OUTPUT_H__
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup LaTeX-Renderer
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "gds-render/layer/layer-info.h"
|
||||||
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
|
|
||||||
|
#define LATEX_LINE_BUFFER_KB (10) /**< @brief Buffer for LaTeX Code line in KiB */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Render \p cell to LateX/TikZ code
|
||||||
|
* @param cell Cell to render
|
||||||
|
* @param layer_infos Layer information
|
||||||
|
* @param tex_file Already opened file to write data in
|
||||||
|
* @param scale Scale image down by this value
|
||||||
|
* @param create_pdf_layers Optional content groups used
|
||||||
|
* @param standalone_document document can be compiled standalone
|
||||||
|
*/
|
||||||
|
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
|
||||||
|
gboolean create_pdf_layers, gboolean standalone_document);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#endif /* __LATEX_OUTPUT_H__ */
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 color-palette.h
|
|
||||||
* @brief Class representing a color palette
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _COLOR_PALETTE_H_
|
|
||||||
#define _COLOR_PALETTE_H_
|
|
||||||
|
|
||||||
#include <glib.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(ColorPalette, color_palette, GDS_RENDER, COLOR_PALETTE, GObject);
|
|
||||||
|
|
||||||
#define TYPE_GDS_RENDER_COLOR_PALETTE (color_palette_get_type())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a new object with from a resource containing the html hex color scheme
|
|
||||||
* @param resource_name Name of the resource
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
ColorPalette *color_palette_new_from_resource(char *resource_name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the n-th color in the palette identified by the index.
|
|
||||||
*
|
|
||||||
* This function fills the nth color into the supplied \p color.
|
|
||||||
* \p color is returned.
|
|
||||||
*
|
|
||||||
* If \p color is NULL, a new GdkRGBA is created and returned.
|
|
||||||
* This element must be freed afterwards.
|
|
||||||
*
|
|
||||||
* @param palette Color palette
|
|
||||||
* @param color GdkRGBA struct to fill data in. May be NULL.
|
|
||||||
* @param index Index of color. Starts at 0
|
|
||||||
* @return GdkRGBA color. If \p color is NULL, the returned color must be freed afterwards
|
|
||||||
*/
|
|
||||||
GdkRGBA *color_palette_get_color(ColorPalette *palette, GdkRGBA *color, unsigned int index);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return amount of stored colors in \p palette
|
|
||||||
* @param palette Color palette
|
|
||||||
* @return Count of colors
|
|
||||||
*/
|
|
||||||
unsigned int color_palette_get_color_count(ColorPalette *palette);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* _COLOR_PALETTE_H_ */
|
|
51
include/gds-render/layer/layer-info.h
Normal file
51
include/gds-render/layer/layer-info.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2019 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 layer-info.h
|
||||||
|
* @brief Helper functions and definition of layer info struct
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LAYER_INFO_H_
|
||||||
|
#define _LAYER_INFO_H_
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Layer information.
|
||||||
|
*
|
||||||
|
* This structs contains information on how to render a layer
|
||||||
|
*/
|
||||||
|
struct layer_info
|
||||||
|
{
|
||||||
|
int layer; /**< @brief Layer number */
|
||||||
|
char *name; /**< @brief Layer name */
|
||||||
|
int stacked_position; ///< @brief Position of layer in output @warning This parameter is not used by any renderer so far @note Lower is bottom, higher is top
|
||||||
|
GdkRGBA color; /**< @brief RGBA color used to render this layer */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delete a layer_info struct
|
||||||
|
* @param info Struct to be deleted.
|
||||||
|
* @note The layer_info::name Element has to be freed manually
|
||||||
|
*/
|
||||||
|
void layer_info_delete_struct(struct layer_info *info);
|
||||||
|
|
||||||
|
#endif // _LAYER_INFO_H_
|
@ -33,8 +33,6 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <gds-render/layer/color-palette.h>
|
|
||||||
#include <gds-render/layer/layer-settings.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -81,9 +79,9 @@ void layer_selector_set_save_mapping_button(LayerSelector *selector, GtkWidget *
|
|||||||
/**
|
/**
|
||||||
* @brief Get a list of all layers that shall be exported when rendering the cells
|
* @brief Get a list of all layers that shall be exported when rendering the cells
|
||||||
* @param selector Layer selector instance
|
* @param selector Layer selector instance
|
||||||
* @return LayerSettings containing the layer information
|
* @return List of layer_info structures containing the layer information
|
||||||
*/
|
*/
|
||||||
LayerSettings *layer_selector_export_rendered_layer_info(LayerSelector *selector);
|
GList *layer_selector_export_rendered_layer_info(LayerSelector *selector);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Force the layer selector list to be sorted according to \p sort_function
|
* @brief Force the layer selector list to be sorted according to \p sort_function
|
||||||
@ -92,14 +90,6 @@ LayerSettings *layer_selector_export_rendered_layer_info(LayerSelector *selector
|
|||||||
*/
|
*/
|
||||||
void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort_algo sort_function);
|
void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort_algo sort_function);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Apply colors from palette to all layers. Aditionally set alpha
|
|
||||||
* @param layer_selector LayerSelector object
|
|
||||||
* @param palette Color palette to use
|
|
||||||
* @param global_alpha Additional alpha value that is applied to all layers
|
|
||||||
*/
|
|
||||||
void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalette *palette, double global_alpha);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __LAYER_SELECTOR_H__ */
|
#endif /* __LAYER_SELECTOR_H__ */
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 layer-info.h
|
|
||||||
* @brief LayerSettings class heade file
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LAYER_INFO_H_
|
|
||||||
#define _LAYER_INFO_H_
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Layer information.
|
|
||||||
*
|
|
||||||
* This structs contains information on how to render a layer
|
|
||||||
* @note You probably don't want to use this struct standalone but in combination
|
|
||||||
* with a LayerSettings object.
|
|
||||||
*/
|
|
||||||
struct layer_info
|
|
||||||
{
|
|
||||||
int layer; /**< @brief Layer number */
|
|
||||||
char *name; /**< @brief Layer name. */
|
|
||||||
int stacked_position; ///< @brief Position of layer in output @warning This parameter is not used by any renderer so far @note Lower is bottom, higher is top
|
|
||||||
GdkRGBA color; /**< @brief RGBA color used to render this layer */
|
|
||||||
int render; /**< @brief true: Render to output */
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(LayerSettings, layer_settings, GDS_RENDER, LAYER_SETTINGS, GObject)
|
|
||||||
|
|
||||||
#define GDS_RENDER_TYPE_LAYER_SETTINGS (layer_settings_get_type())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum length of a layer mapping CSV line
|
|
||||||
*/
|
|
||||||
#define CSV_LINE_MAX_LEN (1024)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief New LayerSettings object
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
LayerSettings *layer_settings_new();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief layer_settings_append_layer_info
|
|
||||||
* @param settings LayerSettings object.
|
|
||||||
* @param info Info to append
|
|
||||||
* @return Error code. 0 if successful
|
|
||||||
* @note \p info is copied internally. You can free this struct afterwards.
|
|
||||||
*/
|
|
||||||
int layer_settings_append_layer_info(LayerSettings *settings, struct layer_info *info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clear all layers in this settings object
|
|
||||||
* @param settings LayerSettings object
|
|
||||||
*/
|
|
||||||
void layer_settings_clear(LayerSettings *settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Remove a specific layer number from the layer settings.
|
|
||||||
* @param settings LayerSettings object
|
|
||||||
* @param layer Layer number
|
|
||||||
* @return Error code. 0 if successful
|
|
||||||
*/
|
|
||||||
int layer_settings_remove_layer(LayerSettings *settings, int layer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get a GList with layer_info structs
|
|
||||||
*
|
|
||||||
* This function returns a GList with all layer_info structs in rendering order
|
|
||||||
* (bottom to top) that shall be rendered.
|
|
||||||
*
|
|
||||||
* @param settings LayerSettings object
|
|
||||||
* @return GList with struct layer_info elements.
|
|
||||||
*/
|
|
||||||
GList *layer_settings_get_layer_info_list(LayerSettings *settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write layer settings to a CSV file
|
|
||||||
* @param path
|
|
||||||
* @return 0 if successful
|
|
||||||
*/
|
|
||||||
int layer_settings_to_csv(LayerSettings *settings, const char *path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load new layer Settings from CSV
|
|
||||||
*
|
|
||||||
* This function loads the layer information from a CSV file.
|
|
||||||
* All data inside the \p settings is cleared beforehand.
|
|
||||||
*
|
|
||||||
* @param settings Settings to write to.
|
|
||||||
* @param path CSV file path
|
|
||||||
* @return 0 if successful
|
|
||||||
*/
|
|
||||||
int layer_settings_load_from_csv(LayerSettings *settings, const char *path);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif // _LAYER_INFO_H_
|
|
@ -34,7 +34,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <gds-render/widgets/layer-element.h>
|
#include <gds-render/widgets/layer-element.h>
|
||||||
#include <gds-render/layer/layer-settings.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load a line from \p stream and parse try to parse it as layer information
|
* @brief Load a line from \p stream and parse try to parse it as layer information
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 gds-output-renderer.h
|
|
||||||
* @brief Header for output renderer base class
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup GdsOutputRenderer
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _GDS_OUTPUT_RENDERER_H_
|
|
||||||
#define _GDS_OUTPUT_RENDERER_H_
|
|
||||||
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
|
||||||
#include <glib-object.h>
|
|
||||||
#include <glib.h>
|
|
||||||
#include <gds-render/layer/layer-settings.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
#define GDS_RENDER_TYPE_OUTPUT_RENDERER (gds_output_renderer_get_type())
|
|
||||||
|
|
||||||
G_DECLARE_DERIVABLE_TYPE(GdsOutputRenderer, gds_output_renderer, GDS_RENDER, OUTPUT_RENDERER, GObject);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Base output renderer class structure.
|
|
||||||
* @note This structure is only used for internal inheritance of GObjects. Do not use in code outside of these classes.
|
|
||||||
*/
|
|
||||||
struct _GdsOutputRendererClass {
|
|
||||||
GObjectClass parent_class;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Virtual render output function. Overwritten by final class implementation
|
|
||||||
*/
|
|
||||||
int (*render_output)(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale);
|
|
||||||
gpointer padding[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
GDS_OUTPUT_RENDERER_GEN_ERR = -100, /**< @brief Error set by the _GdsOutputRendererClass::render_output virtual function, if renderer is invalid. */
|
|
||||||
GDS_OUTPUT_RENDERER_PARAM_ERR = -200 /**< @brief Error set by the _GdsOutputRendererClass::render_output virtual function, if parameters are faulty. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a new GdsOutputRenderer GObject.
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
GdsOutputRenderer *gds_output_renderer_new();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create a new GdsOutputRenderer GObject with its properties
|
|
||||||
* @param output_file Output file of the renderer
|
|
||||||
* @param layer_settings Layer settings object
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
GdsOutputRenderer *gds_output_renderer_new_with_props(const char *output_file, LayerSettings *layer_settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief gds_output_renderer_render_output
|
|
||||||
* @param renderer Renderer object
|
|
||||||
* @param cell Cell to render
|
|
||||||
* @param scale scale value. The output is scaled *down* by this value
|
|
||||||
* @return 0 if successful
|
|
||||||
*/
|
|
||||||
int gds_output_renderer_render_output(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convenience function for setting the "output-file" property
|
|
||||||
* @param renderer Renderer object
|
|
||||||
* @param file_name Output file path
|
|
||||||
*/
|
|
||||||
void gds_output_renderer_set_output_file(GdsOutputRenderer *renderer, const gchar *file_name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convenience function for getting the "output-file" property
|
|
||||||
* @param renderer
|
|
||||||
* @return Output file path. This must not be freed
|
|
||||||
*/
|
|
||||||
const char *gds_output_renderer_get_output_file(GdsOutputRenderer *renderer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get layer settings
|
|
||||||
*
|
|
||||||
* This is a convenience function for getting the
|
|
||||||
* "layer-settings" property. This also references it.
|
|
||||||
* This is to prevent race conditions with another thread that might
|
|
||||||
* alter the layer settings before they are read out.
|
|
||||||
*
|
|
||||||
* @param renderer Renderer
|
|
||||||
* @return Layer settings object
|
|
||||||
*/
|
|
||||||
LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer *renderer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set layer settings
|
|
||||||
*
|
|
||||||
* This is a convenience function for setting the
|
|
||||||
* "layer-settings" property.
|
|
||||||
*
|
|
||||||
* If another Layer settings has previously been supplied,
|
|
||||||
* it is unref'd.
|
|
||||||
*
|
|
||||||
* @param renderer Renderer
|
|
||||||
* @param settings LayerSettings object
|
|
||||||
*/
|
|
||||||
void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSettings *settings);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Render output asynchronously
|
|
||||||
*
|
|
||||||
* This function will render in a separate thread.
|
|
||||||
* To wait for the completion of the rendering process.
|
|
||||||
*
|
|
||||||
* @note A second async thread cannot be spawned.
|
|
||||||
*
|
|
||||||
* @param renderer Output renderer
|
|
||||||
* @param cell Cell to render
|
|
||||||
* @param scale Scale
|
|
||||||
* @return 0 if successful. In case no thread can be spawned < 0
|
|
||||||
*/
|
|
||||||
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function emits the 'progress-changed' in the thread/context that triggered an asynchronous rendering
|
|
||||||
*
|
|
||||||
* If the rendering is not asynchronous, this function has no effect.
|
|
||||||
*
|
|
||||||
* @param renderer GdsOutputrenderer object
|
|
||||||
* @param status Status to supply to signal emission
|
|
||||||
*/
|
|
||||||
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* _GDS_OUTPUT_RENDERER_H_ */
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 latex-output.h
|
|
||||||
* @brief LaTeX output renderer
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup LaTeX-Renderer
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LATEX_OUTPUT_H_
|
|
||||||
#define _LATEX_OUTPUT_H_
|
|
||||||
|
|
||||||
#include <gds-render/output-renderers/gds-output-renderer.h>
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(LatexRenderer, latex_renderer, GDS_RENDER, LATEX_RENDERER, GdsOutputRenderer)
|
|
||||||
|
|
||||||
#define GDS_RENDER_TYPE_LATEX_RENDERER (latex_renderer_get_type())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Buffer for LaTeX Code line in KiB
|
|
||||||
*/
|
|
||||||
#define LATEX_LINE_BUFFER_KB (10)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create new LatexRenderer object
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
LatexRenderer *latex_renderer_new();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create new LatexRenderer object
|
|
||||||
*
|
|
||||||
* This function sets the 'pdf-layers' and 'standalone'
|
|
||||||
* properties for the newly created object.
|
|
||||||
*
|
|
||||||
* They can later be changes by modifying the properties again.
|
|
||||||
* On top of that, The options can be changed in the resulting
|
|
||||||
* LaTeX output file if needed.
|
|
||||||
*
|
|
||||||
* @param pdf_layers If PDF OCR layers should be enabled
|
|
||||||
* @param standalone If output TeX file should be standalone compilable
|
|
||||||
* @return New object
|
|
||||||
*/
|
|
||||||
LatexRenderer *latex_renderer_new_with_options(gboolean pdf_layers, gboolean standalone);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* _LATEX_OUTPUT_H_ */
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 activity-bar.h
|
|
||||||
* @brief Header file for activity bar widget
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup ActivityBar
|
|
||||||
* @ingroup Widgets
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LAYER_ELEMENT_H__
|
|
||||||
#define __LAYER_ELEMENT_H__
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
|
||||||
|
|
||||||
/* Creates Class structure etc */
|
|
||||||
G_DECLARE_FINAL_TYPE(ActivityBar, activity_bar, ACTIVITY, BAR, GtkBox)
|
|
||||||
|
|
||||||
#define TYPE_ACTIVITY_BAR (activity_bar_get_type())
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create new Object ActivityBar
|
|
||||||
* @return New object. In case of error: NULL.
|
|
||||||
*/
|
|
||||||
ActivityBar *activity_bar_new();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deletes all applied tasks and sets bar to "Ready".
|
|
||||||
* @param[in] bar AcitivityBar object.
|
|
||||||
*/
|
|
||||||
void activity_bar_set_ready(ActivityBar *bar);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable spinner and set \p text. If text is NULL, 'Working...' is displayed
|
|
||||||
* @param bar Activity bar object
|
|
||||||
* @param text Text to display, may be NULL
|
|
||||||
|
|
||||||
*/
|
|
||||||
void activity_bar_set_busy(ActivityBar *bar, const char *text);
|
|
||||||
|
|
||||||
G_END_DECLS
|
|
||||||
|
|
||||||
#endif /* __LAYER_ELEMENT_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @file layer-element.h
|
* @file layer-element.h
|
||||||
* @brief Implementation of the layer element used for configuring layer colors etc.
|
* @brief Omplementation of the layer element used for configuring layer colors etc.
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -24,37 +24,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <gds-render/output-renderers/latex-renderer.h>
|
#include <gds-render/latex-renderer/latex-output.h>
|
||||||
#include <gdk/gdk.h>
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup LaTeX-Renderer
|
* @addtogroup LaTeX-Renderer
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/** @brief Writes a GString \p buffer to the fixed file tex_file */
|
||||||
* @brief Struct representing the LaTeX-Renderer object.
|
|
||||||
*
|
|
||||||
* This struct holds the LaTeX renderer internal data. It is only used inside the @ref LatexRenderer class.
|
|
||||||
*/
|
|
||||||
struct _LatexRenderer {
|
|
||||||
GdsOutputRenderer parent;
|
|
||||||
gboolean tex_standalone;
|
|
||||||
gboolean pdf_layers;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(LatexRenderer, latex_renderer, GDS_RENDER_TYPE_OUTPUT_RENDERER)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_STANDALONE = 1,
|
|
||||||
PROP_PDF_LAYERS,
|
|
||||||
N_PROPERTIES
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Writes a GString \p buffer to the fixed file tex_file
|
|
||||||
* @note This is a convinience macro. Do not use this anywhere else. It might change behavior in futurtre releases
|
|
||||||
*/
|
|
||||||
#define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file)
|
#define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,13 +51,10 @@ static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString
|
|||||||
{
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
struct layer_info *lifo;
|
struct layer_info *lifo;
|
||||||
|
char *end_str;
|
||||||
|
|
||||||
for (list = layer_infos; list != NULL; list = list->next) {
|
for (list = layer_infos; list != NULL; list = list->next) {
|
||||||
lifo = (struct layer_info *)list->data;
|
lifo = (struct layer_info *)list->data;
|
||||||
|
|
||||||
if (!lifo->render)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_string_printf(buffer, "\\pgfdeclarelayer{l%d}\n\\definecolor{c%d}{rgb}{%lf,%lf,%lf}\n",
|
g_string_printf(buffer, "\\pgfdeclarelayer{l%d}\n\\definecolor{c%d}{rgb}{%lf,%lf,%lf}\n",
|
||||||
lifo->layer, lifo->layer,
|
lifo->layer, lifo->layer,
|
||||||
lifo->color.red, lifo->color.green, lifo->color.blue);
|
lifo->color.red, lifo->color.green, lifo->color.blue);
|
||||||
@ -92,14 +67,14 @@ static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString
|
|||||||
for (list = layer_infos; list != NULL; list = list->next) {
|
for (list = layer_infos; list != NULL; list = list->next) {
|
||||||
lifo = (struct layer_info *)list->data;
|
lifo = (struct layer_info *)list->data;
|
||||||
|
|
||||||
if (!lifo->render)
|
if (list->next == NULL)
|
||||||
continue;
|
end_str = ",main}";
|
||||||
|
else
|
||||||
g_string_printf(buffer, "l%d,", lifo->layer);
|
end_str = ",";
|
||||||
|
g_string_printf(buffer, "l%d%s", lifo->layer, end_str);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
}
|
}
|
||||||
g_string_printf(buffer, "main}\n");
|
fwrite("\n", sizeof(char), 1, tex_file);
|
||||||
WRITEOUT_BUFFER(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +110,7 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
|
|||||||
|
|
||||||
for (temp = linfo; temp != NULL; temp = temp->next) {
|
for (temp = linfo; temp != NULL; temp = temp->next) {
|
||||||
inf = (struct layer_info *)temp->data;
|
inf = (struct layer_info *)temp->data;
|
||||||
if (inf->layer == layer && inf->render) {
|
if (inf->layer == layer) {
|
||||||
color->alpha = inf->color.alpha;
|
color->alpha = inf->color.alpha;
|
||||||
color->red = inf->color.red;
|
color->red = inf->color.red;
|
||||||
color->green = inf->color.green;
|
color->green = inf->color.green;
|
||||||
@ -230,20 +205,13 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
|||||||
* @param tex_file File to write to
|
* @param tex_file File to write to
|
||||||
* @param buffer Working buffer
|
* @param buffer Working buffer
|
||||||
* @param scale Scale output down by this value
|
* @param scale Scale output down by this value
|
||||||
* @param renderer The current renderer as GdsOutputRenderer. This is used to emit the status updates to the GUI
|
|
||||||
*/
|
*/
|
||||||
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale,
|
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale)
|
||||||
GdsOutputRenderer *renderer)
|
|
||||||
{
|
{
|
||||||
GString *status;
|
|
||||||
GList *list_child;
|
GList *list_child;
|
||||||
struct gds_cell_instance *inst;
|
struct gds_cell_instance *inst;
|
||||||
|
|
||||||
status = g_string_new(NULL);
|
|
||||||
g_string_printf(status, "Generating cell %s", cell->name);
|
|
||||||
gds_output_renderer_update_gui_status_from_async(renderer, status->str);
|
|
||||||
g_string_free(status, TRUE);
|
|
||||||
|
|
||||||
/* Draw polygons of current cell */
|
/* Draw polygons of current cell */
|
||||||
generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer, scale);
|
generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer, scale);
|
||||||
|
|
||||||
@ -267,7 +235,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
inst->magnification);
|
inst->magnification);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
render_cell(inst->cell_ref, layer_infos, tex_file, buffer, scale, renderer);
|
render_cell(inst->cell_ref, layer_infos, tex_file, buffer, scale);
|
||||||
|
|
||||||
g_string_printf(buffer, "\\end{scope}\n");
|
g_string_printf(buffer, "\\end{scope}\n");
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
@ -281,14 +249,14 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
|
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
|
||||||
gboolean create_pdf_layers, gboolean standalone_document, GdsOutputRenderer *renderer)
|
gboolean create_pdf_layers, gboolean standalone_document)
|
||||||
{
|
{
|
||||||
GString *working_line;
|
GString *working_line;
|
||||||
|
|
||||||
|
|
||||||
if (!tex_file || !layer_infos || !cell)
|
if (!tex_file || !layer_infos || !cell)
|
||||||
return -1;
|
return;
|
||||||
|
|
||||||
/* 10 kB Line working buffer should be enough */
|
/* 10 kB Line working buffer should be enough */
|
||||||
working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024);
|
working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024);
|
||||||
@ -315,7 +283,7 @@ static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos,
|
|||||||
WRITEOUT_BUFFER(working_line);
|
WRITEOUT_BUFFER(working_line);
|
||||||
|
|
||||||
/* Generate graphics output */
|
/* Generate graphics output */
|
||||||
render_cell(cell, layer_infos, tex_file, working_line, scale, renderer);
|
render_cell(cell, layer_infos, tex_file, working_line, scale);
|
||||||
|
|
||||||
|
|
||||||
g_string_printf(working_line, "\\end{tikzpicture}\n");
|
g_string_printf(working_line, "\\end{tikzpicture}\n");
|
||||||
@ -330,125 +298,6 @@ static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos,
|
|||||||
|
|
||||||
fflush(tex_file);
|
fflush(tex_file);
|
||||||
g_string_free(working_line, TRUE);
|
g_string_free(working_line, TRUE);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int latex_renderer_render_output(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
LatexRenderer *l_renderer = GDS_RENDER_LATEX_RENDERER(renderer);
|
|
||||||
FILE *tex_file;
|
|
||||||
int ret = -2;
|
|
||||||
LayerSettings *settings;
|
|
||||||
GList *layer_infos = NULL;
|
|
||||||
const char *output_file;
|
|
||||||
|
|
||||||
output_file = gds_output_renderer_get_output_file(renderer);
|
|
||||||
settings = gds_output_renderer_get_and_ref_layer_settings(renderer);
|
|
||||||
|
|
||||||
/* Set layer info list. In case of failure it remains NULL */
|
|
||||||
if (settings)
|
|
||||||
layer_infos = layer_settings_get_layer_info_list(settings);
|
|
||||||
|
|
||||||
tex_file = fopen(output_file, "w");
|
|
||||||
if (tex_file) {
|
|
||||||
ret = latex_render_cell_to_code(cell, layer_infos, tex_file, scale,
|
|
||||||
l_renderer->pdf_layers, l_renderer->tex_standalone, renderer);
|
|
||||||
fclose(tex_file);
|
|
||||||
} else {
|
|
||||||
g_error("Could not open LaTeX output file");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (settings) {
|
|
||||||
g_object_unref(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void latex_renderer_init(LatexRenderer *self)
|
|
||||||
{
|
|
||||||
self->pdf_layers = FALSE;
|
|
||||||
self->tex_standalone = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void latex_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
LatexRenderer *self = GDS_RENDER_LATEX_RENDERER(obj);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_STANDALONE:
|
|
||||||
g_value_set_boolean(value, self->tex_standalone);
|
|
||||||
break;
|
|
||||||
case PROP_PDF_LAYERS:
|
|
||||||
g_value_set_boolean(value, self->pdf_layers);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void latex_renderer_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
LatexRenderer *self = GDS_RENDER_LATEX_RENDERER(obj);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_STANDALONE:
|
|
||||||
self->tex_standalone = g_value_get_boolean(value);
|
|
||||||
break;
|
|
||||||
case PROP_PDF_LAYERS:
|
|
||||||
self->pdf_layers = g_value_get_boolean(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec *latex_renderer_properties[N_PROPERTIES] = {NULL};
|
|
||||||
|
|
||||||
static void latex_renderer_class_init(LatexRendererClass *klass)
|
|
||||||
{
|
|
||||||
GdsOutputRendererClass *render_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass);
|
|
||||||
GObjectClass *oclass = G_OBJECT_CLASS(klass);
|
|
||||||
|
|
||||||
/* Overwrite virtual function */
|
|
||||||
render_class->render_output = latex_renderer_render_output;
|
|
||||||
|
|
||||||
/* Property stuff */
|
|
||||||
oclass->get_property = latex_renderer_get_property;
|
|
||||||
oclass->set_property = latex_renderer_set_property;
|
|
||||||
|
|
||||||
latex_renderer_properties[PROP_STANDALONE] =
|
|
||||||
g_param_spec_boolean("standalone",
|
|
||||||
"Standalone TeX file",
|
|
||||||
"Generate a standalone LaTeX file.",
|
|
||||||
FALSE,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
latex_renderer_properties[PROP_PDF_LAYERS] =
|
|
||||||
g_param_spec_boolean("pdf-layers",
|
|
||||||
"PDF OCR layers",
|
|
||||||
"Generate OCR layers",
|
|
||||||
FALSE,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
|
|
||||||
g_object_class_install_properties(oclass, N_PROPERTIES, latex_renderer_properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
LatexRenderer *latex_renderer_new()
|
|
||||||
{
|
|
||||||
return GDS_RENDER_LATEX_RENDERER(g_object_new(GDS_RENDER_TYPE_LATEX_RENDERER, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
LatexRenderer *latex_renderer_new_with_options(gboolean pdf_layers, gboolean standalone)
|
|
||||||
{
|
|
||||||
GObject *obj;
|
|
||||||
|
|
||||||
obj = g_object_new(GDS_RENDER_TYPE_LATEX_RENDERER, "standalone", standalone, "pdf-layers", pdf_layers, NULL);
|
|
||||||
return GDS_RENDER_LATEX_RENDERER(obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
@ -1,258 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 color-palette.c
|
|
||||||
* @brief Class representing a color palette
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/layer/color-palette.h>
|
|
||||||
|
|
||||||
struct _ColorPalette {
|
|
||||||
/* Inheritance */
|
|
||||||
GObject parent;
|
|
||||||
|
|
||||||
/* Custom fields */
|
|
||||||
/** @brief The internal array to store the colors */
|
|
||||||
GdkRGBA *color_array;
|
|
||||||
/** @brief The length of the _ColorPalette::color_array array */
|
|
||||||
unsigned int color_array_length;
|
|
||||||
|
|
||||||
/* Dummy bytes to ensure ABI compatibility in future versions */
|
|
||||||
gpointer dummy[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(ColorPalette, color_palette, G_TYPE_OBJECT)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Return the number of non empty lines in array
|
|
||||||
*
|
|
||||||
* This function returns the number of non empty lines in an
|
|
||||||
* array. The scanning is either terminated by the given length
|
|
||||||
* or if a \0 terminator is found.
|
|
||||||
*
|
|
||||||
* @param[in] data Array to count lines in
|
|
||||||
* @param[in] length Length of \p data
|
|
||||||
* @return < 0: Error, >=0: Lines
|
|
||||||
*/
|
|
||||||
static int count_non_empty_lines_in_array(const char *data, size_t length)
|
|
||||||
{
|
|
||||||
unsigned int idx;
|
|
||||||
int non_empty_lines;
|
|
||||||
char last_char = '\n';
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Count each '\n' as a new line if it is not directly preceded by another '\n' */
|
|
||||||
for (idx = 0; idx < length && data[idx]; idx++) {
|
|
||||||
if (data[idx] == '\n' && last_char != '\n')
|
|
||||||
non_empty_lines++;
|
|
||||||
last_char = data[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Count the last line in case the data does not end with a '\n' */
|
|
||||||
if (data[idx-1] != '\n')
|
|
||||||
non_empty_lines++;
|
|
||||||
|
|
||||||
return non_empty_lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief color_palette_fill_with_resource
|
|
||||||
* @param palette
|
|
||||||
* @param resource_name
|
|
||||||
* @return 0 if successful
|
|
||||||
*/
|
|
||||||
static int color_palette_fill_with_resource(ColorPalette *palette, char *resource_name)
|
|
||||||
{
|
|
||||||
GBytes *data;
|
|
||||||
char line[10];
|
|
||||||
int line_idx;
|
|
||||||
unsigned int color_idx;
|
|
||||||
int idx;
|
|
||||||
const char *char_array;
|
|
||||||
gsize byte_count;
|
|
||||||
int lines;
|
|
||||||
GRegex *regex;
|
|
||||||
GMatchInfo *mi;
|
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!palette || !resource_name)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
data = g_resources_lookup_data(resource_name, 0, NULL);
|
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
char_array = (const char *)g_bytes_get_data(data, &byte_count);
|
|
||||||
|
|
||||||
if (!char_array || !byte_count)
|
|
||||||
goto ret_unref;
|
|
||||||
|
|
||||||
/* Get maximum lenght of color palette, assuming all entries are valid */
|
|
||||||
lines = count_non_empty_lines_in_array(char_array, byte_count);
|
|
||||||
|
|
||||||
if (lines <= 0)
|
|
||||||
goto ret_unref;
|
|
||||||
|
|
||||||
palette->color_array = (GdkRGBA *)malloc(sizeof(GdkRGBA) * (unsigned int)lines);
|
|
||||||
|
|
||||||
/* Setup regex for hexadecimal RGB colors like 'A0CB3F' */
|
|
||||||
regex = g_regex_new("^(?<red>[0-9A-Fa-f][0-9A-Fa-f])(?<green>[0-9A-Fa-f][0-9A-Fa-f])(?<blue>[0-9A-Fa-f][0-9A-Fa-f])$",
|
|
||||||
0, 0, NULL);
|
|
||||||
|
|
||||||
/* Reset line */
|
|
||||||
line_idx = 0;
|
|
||||||
line[0] = '\0';
|
|
||||||
|
|
||||||
/* Set color index */
|
|
||||||
color_idx = 0;
|
|
||||||
|
|
||||||
/* interate over lines and match */
|
|
||||||
for (idx = 0 ; idx < byte_count; idx++) {
|
|
||||||
/* Fillup line. */
|
|
||||||
line[line_idx] = char_array[idx];
|
|
||||||
|
|
||||||
|
|
||||||
/* If end of line/string is reached, process */
|
|
||||||
if (line[line_idx] == '\n' || line[line_idx] == '\0') {
|
|
||||||
line[line_idx] = '\0';
|
|
||||||
|
|
||||||
/* Match the line */
|
|
||||||
g_regex_match(regex, line, 0, &mi);
|
|
||||||
if (g_match_info_matches(mi) && color_idx < lines) {
|
|
||||||
match = g_match_info_fetch_named(mi, "red");
|
|
||||||
palette->color_array[color_idx].red = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "green");
|
|
||||||
palette->color_array[color_idx].green = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "blue");
|
|
||||||
palette->color_array[color_idx].blue = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
|
||||||
g_free(match);
|
|
||||||
|
|
||||||
/* Only RGB supported so far. Fix alpha channel to 1.0 */
|
|
||||||
palette->color_array[color_idx].alpha = 1.0;
|
|
||||||
|
|
||||||
color_idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_match_info_free(mi);
|
|
||||||
|
|
||||||
/* End of string */
|
|
||||||
if (char_array[idx] == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
line_idx = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* increment line index. If end is reached write all bytes to the line end
|
|
||||||
* line is longer than required for parsing. This ensures, that everything works as expected
|
|
||||||
*/
|
|
||||||
line_idx += (line_idx < sizeof(line)-1 ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Data read; Shrink array in case of invalid lines */
|
|
||||||
palette->color_array = realloc(palette->color_array, (size_t)color_idx * sizeof(GdkRGBA));
|
|
||||||
palette->color_array_length = color_idx;
|
|
||||||
|
|
||||||
g_regex_unref(regex);
|
|
||||||
ret_unref:
|
|
||||||
g_bytes_unref(data);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorPalette *color_palette_new_from_resource(char *resource_name)
|
|
||||||
{
|
|
||||||
ColorPalette *palette;
|
|
||||||
|
|
||||||
palette = GDS_RENDER_COLOR_PALETTE(g_object_new(TYPE_GDS_RENDER_COLOR_PALETTE, NULL));
|
|
||||||
if (palette)
|
|
||||||
(void)color_palette_fill_with_resource(palette, resource_name);
|
|
||||||
|
|
||||||
return palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdkRGBA *color_palette_get_color(ColorPalette *palette, GdkRGBA *color, unsigned int index)
|
|
||||||
{
|
|
||||||
GdkRGBA *c = NULL;
|
|
||||||
|
|
||||||
if (!palette)
|
|
||||||
goto ret_c;
|
|
||||||
|
|
||||||
if (index >= palette->color_array_length)
|
|
||||||
goto ret_c;
|
|
||||||
|
|
||||||
if (color)
|
|
||||||
c = color;
|
|
||||||
else
|
|
||||||
c = (GdkRGBA *)malloc(sizeof(GdkRGBA));
|
|
||||||
|
|
||||||
/* Copy color */
|
|
||||||
c->red = palette->color_array[index].red;
|
|
||||||
c->green = palette->color_array[index].green;
|
|
||||||
c->blue = palette->color_array[index].blue;
|
|
||||||
c->alpha = palette->color_array[index].alpha;
|
|
||||||
ret_c:
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int color_palette_get_color_count(ColorPalette *palette)
|
|
||||||
{
|
|
||||||
unsigned int return_val = 0;
|
|
||||||
|
|
||||||
if (palette)
|
|
||||||
return_val = palette->color_array_length;
|
|
||||||
|
|
||||||
return return_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void color_palette_dispose(GObject *gobj)
|
|
||||||
{
|
|
||||||
ColorPalette *palette;
|
|
||||||
|
|
||||||
palette = GDS_RENDER_COLOR_PALETTE(gobj);
|
|
||||||
if (palette->color_array)
|
|
||||||
{
|
|
||||||
palette->color_array_length = 0;
|
|
||||||
free(palette->color_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Chain up to parent class */
|
|
||||||
G_OBJECT_CLASS(color_palette_parent_class)->dispose(gobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void color_palette_class_init(ColorPaletteClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *gclass;
|
|
||||||
|
|
||||||
gclass = G_OBJECT_CLASS(klass);
|
|
||||||
gclass->dispose = color_palette_dispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void color_palette_init(ColorPalette *self)
|
|
||||||
{
|
|
||||||
self->color_array = NULL;
|
|
||||||
self->color_array_length = 0;
|
|
||||||
}
|
|
33
layer/layer-info.c
Normal file
33
layer/layer-info.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* GDSII-Converter
|
||||||
|
* Copyright (C) 2019 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 layer-info.c
|
||||||
|
* @brief Helper functions for layer info struct
|
||||||
|
* @author Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <gds-render/layer/layer-info.h>
|
||||||
|
|
||||||
|
void layer_info_delete_struct(struct layer_info *info)
|
||||||
|
{
|
||||||
|
if (info)
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
|
@ -34,6 +34,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <gds-render/layer/layer-selector.h>
|
#include <gds-render/layer/layer-selector.h>
|
||||||
|
#include <gds-render/layer/layer-info.h>
|
||||||
#include <gds-render/gds-utils/gds-parser.h>
|
#include <gds-render/gds-utils/gds-parser.h>
|
||||||
#include <gds-render/widgets/layer-element.h>
|
#include <gds-render/widgets/layer-element.h>
|
||||||
#include <gds-render/layer/mapping-parser.h>
|
#include <gds-render/layer/mapping-parser.h>
|
||||||
@ -370,39 +371,39 @@ LayerSelector *layer_selector_new(GtkListBox *list_box)
|
|||||||
return selector;
|
return selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerSettings *layer_selector_export_rendered_layer_info(LayerSelector *selector)
|
GList *layer_selector_export_rendered_layer_info(LayerSelector *selector)
|
||||||
{
|
{
|
||||||
LayerSettings *layer_settings;
|
GList *info_list = NULL;
|
||||||
struct layer_info linfo;
|
|
||||||
GList *row_list;
|
|
||||||
GList *iterator;
|
|
||||||
LayerElement *le;
|
LayerElement *le;
|
||||||
|
struct layer_info *linfo;
|
||||||
|
GList *row_list;
|
||||||
|
GList *temp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
layer_settings = layer_settings_new();
|
if (!selector)
|
||||||
if (!layer_settings)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
row_list = gtk_container_get_children(GTK_CONTAINER(selector->list_box));
|
row_list = gtk_container_get_children(GTK_CONTAINER(selector->list_box));
|
||||||
|
|
||||||
for (i = 0,iterator = row_list; iterator != NULL; iterator = g_list_next(iterator), i++) {
|
/* Iterate through widgets and add layers that shall be exported */
|
||||||
le = LAYER_ELEMENT(iterator->data);
|
for (i = 0, temp = row_list; temp != NULL; temp = temp->next, i++) {
|
||||||
|
|
||||||
/* Get name from layer element. This must not be freed */
|
le = LAYER_ELEMENT(temp->data);
|
||||||
linfo.name =(char *)layer_element_get_name(le);
|
|
||||||
|
|
||||||
layer_element_get_color(le, &linfo.color);
|
if (layer_element_get_export(le) == TRUE) {
|
||||||
linfo.render = (layer_element_get_export(le) ? 1 : 0);
|
/* Allocate new info and fill with info */
|
||||||
linfo.stacked_position = i;
|
linfo = (struct layer_info *)malloc(sizeof(struct layer_info));
|
||||||
linfo.layer = layer_element_get_layer(le);
|
layer_element_get_color(le, &linfo->color);
|
||||||
|
linfo->layer = layer_element_get_layer(le);
|
||||||
|
linfo->stacked_position = i;
|
||||||
|
linfo->name = (char *)layer_element_get_name(le);
|
||||||
|
|
||||||
/* This function copies the entire layer info struct including the name string.
|
/* Append to list */
|
||||||
* Therefore, using the same layer_info struct over and over is safe.
|
info_list = g_list_append(info_list, (gpointer)linfo);
|
||||||
*/
|
}
|
||||||
layer_settings_append_layer_info(layer_settings, &linfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return layer_settings;
|
return info_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void layer_selector_clear_widgets(LayerSelector *self)
|
static void layer_selector_clear_widgets(LayerSelector *self)
|
||||||
@ -780,44 +781,4 @@ void layer_selector_force_sort(LayerSelector *selector, enum layer_selector_sort
|
|||||||
gtk_list_box_set_sort_func(box, NULL, NULL, NULL);
|
gtk_list_box_set_sort_func(box, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalette *palette, double global_alpha)
|
|
||||||
{
|
|
||||||
GList *le_list;
|
|
||||||
GList *le_list_ptr;
|
|
||||||
LayerElement *le;
|
|
||||||
unsigned int color_index = 0;
|
|
||||||
unsigned int color_count;
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
if (GDS_RENDER_IS_COLOR_PALETTE(palette) == FALSE || LAYER_IS_SELECTOR(layer_selector) == FALSE)
|
|
||||||
return;
|
|
||||||
if (global_alpha <= 0)
|
|
||||||
return;
|
|
||||||
if (GTK_IS_LIST_BOX(layer_selector->list_box) == FALSE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
|
|
||||||
|
|
||||||
/* iterate over layer elements and fill colors */
|
|
||||||
color_index = 0;
|
|
||||||
color_count = color_palette_get_color_count(palette);
|
|
||||||
if (color_count == 0)
|
|
||||||
goto ret_free_le_list;
|
|
||||||
|
|
||||||
for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = le_list_ptr->next) {
|
|
||||||
le = LAYER_ELEMENT(le_list_ptr->data);
|
|
||||||
if (le) {
|
|
||||||
color_palette_get_color(palette, &color, color_index++);
|
|
||||||
color.alpha *= global_alpha;
|
|
||||||
layer_element_set_color(le, &color);
|
|
||||||
|
|
||||||
if (color_index >= color_count)
|
|
||||||
color_index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_free_le_list:
|
|
||||||
g_list_free(le_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -1,347 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 layer-info.c
|
|
||||||
* @brief Implementation of the LayerSettings class
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/layer/layer-settings.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
struct _LayerSettings {
|
|
||||||
GObject parent;
|
|
||||||
GList *layer_infos;
|
|
||||||
gpointer padding[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(LayerSettings, layer_settings, G_TYPE_OBJECT)
|
|
||||||
|
|
||||||
static void layer_settings_init(LayerSettings *self)
|
|
||||||
{
|
|
||||||
self->layer_infos = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void layer_info_delete_with_name(struct layer_info *const info)
|
|
||||||
{
|
|
||||||
if (!info)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (info->name)
|
|
||||||
free(info->name);
|
|
||||||
free(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void layer_settings_dispose(GObject *obj)
|
|
||||||
{
|
|
||||||
LayerSettings *self;
|
|
||||||
|
|
||||||
self = GDS_RENDER_LAYER_SETTINGS(obj);
|
|
||||||
|
|
||||||
if (self->layer_infos) {
|
|
||||||
g_list_free_full(self->layer_infos, (GDestroyNotify)layer_info_delete_with_name);
|
|
||||||
self->layer_infos = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(layer_settings_parent_class)->dispose(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void layer_settings_class_init(LayerSettingsClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *oclass;
|
|
||||||
|
|
||||||
oclass = G_OBJECT_CLASS(klass);
|
|
||||||
oclass->dispose = layer_settings_dispose;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Copy layer_info struct
|
|
||||||
*
|
|
||||||
* This function copies a layer info struct.
|
|
||||||
* Be aware, that it does not only copy the pointer to the
|
|
||||||
* layer name, but instead duplicates the string.
|
|
||||||
*
|
|
||||||
* @param info Info to copy
|
|
||||||
* @return new layer_info struct
|
|
||||||
*/
|
|
||||||
static struct layer_info *layer_info_copy(const struct layer_info * const info)
|
|
||||||
{
|
|
||||||
struct layer_info *copy;
|
|
||||||
|
|
||||||
if (!info)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
copy = (struct layer_info *)malloc(sizeof(struct layer_info));
|
|
||||||
if (!copy)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Copy data */
|
|
||||||
memcpy(copy, info, sizeof(struct layer_info));
|
|
||||||
/* Duplicate string */
|
|
||||||
if (info->name)
|
|
||||||
copy->name = strdup(info->name);
|
|
||||||
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerSettings *layer_settings_new()
|
|
||||||
{
|
|
||||||
return g_object_new(GDS_RENDER_TYPE_LAYER_SETTINGS, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int layer_settings_append_layer_info(LayerSettings *settings, struct layer_info *info)
|
|
||||||
{
|
|
||||||
struct layer_info *info_copy;
|
|
||||||
|
|
||||||
g_return_val_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings), -1);
|
|
||||||
if (!info)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
/* Copy layer info */
|
|
||||||
info_copy = layer_info_copy(info);
|
|
||||||
|
|
||||||
/* Append to list */
|
|
||||||
settings->layer_infos = g_list_append(settings->layer_infos, info_copy);
|
|
||||||
|
|
||||||
return (settings->layer_infos ? 0 : -3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void layer_settings_clear(LayerSettings *settings)
|
|
||||||
{
|
|
||||||
g_return_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings));
|
|
||||||
|
|
||||||
/* Clear list and delete layer_info structs including the name field */
|
|
||||||
g_list_free_full(settings->layer_infos, (GDestroyNotify)layer_info_delete_with_name);
|
|
||||||
settings->layer_infos = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int layer_settings_remove_layer(LayerSettings *settings, int layer)
|
|
||||||
{
|
|
||||||
GList *list_iter;
|
|
||||||
GList *found = NULL;
|
|
||||||
struct layer_info *inf;
|
|
||||||
|
|
||||||
g_return_val_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings), -1);
|
|
||||||
|
|
||||||
/* Find in list */
|
|
||||||
for (list_iter = settings->layer_infos; list_iter; list_iter = list_iter->next) {
|
|
||||||
inf = (struct layer_info *)list_iter->data;
|
|
||||||
|
|
||||||
if (!inf)
|
|
||||||
continue;
|
|
||||||
if (inf->layer == layer)
|
|
||||||
found = list_iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
/* Free the layer_info struct */
|
|
||||||
layer_info_delete_with_name((struct layer_info *)found->data);
|
|
||||||
/* Delete the list element */
|
|
||||||
settings->layer_infos = g_list_delete_link(settings->layer_infos, found);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
GList *layer_settings_get_layer_info_list(LayerSettings *settings)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings), NULL);
|
|
||||||
return settings->layer_infos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Generate a layer mapping CSV line for a given layer_info struct
|
|
||||||
* @param string Buffer to write to
|
|
||||||
* @param linfo Layer information
|
|
||||||
*/
|
|
||||||
static void layer_settings_gen_csv_line(GString *string, struct layer_info *linfo)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
g_string_printf(string, "%d:%lf:%lf:%lf:%lf:%d:%s\n",
|
|
||||||
linfo->layer, linfo->color.red, linfo->color.green,
|
|
||||||
linfo->color.blue, linfo->color.alpha, (linfo->render ? 1 : 0), linfo->name);
|
|
||||||
/* Fix broken locale settings */
|
|
||||||
for (i = 0; string->str[i]; i++) {
|
|
||||||
if (string->str[i] == ',')
|
|
||||||
string->str[i] = '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; string->str[i]; i++) {
|
|
||||||
if (string->str[i] == ':')
|
|
||||||
string->str[i] = ',';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int layer_settings_to_csv(LayerSettings *settings, const char *path)
|
|
||||||
{
|
|
||||||
GFile *file;
|
|
||||||
GOutputStream *w_fstream;
|
|
||||||
GString *string;
|
|
||||||
GList *info_iter;
|
|
||||||
struct layer_info *linfo;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
file = g_file_new_for_path(path);
|
|
||||||
w_fstream = G_OUTPUT_STREAM(g_file_replace(file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, NULL));
|
|
||||||
if (!w_fstream) {
|
|
||||||
ret = -1;
|
|
||||||
goto ret_unref_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate new working buffer string. A size bigger than 200 is unexpected, but possible
|
|
||||||
* 200 is a tradeoff between memory usage and preventing the necessity of realloc'ing the string
|
|
||||||
*/
|
|
||||||
string = g_string_new_len(NULL, 200);
|
|
||||||
if (!string) {
|
|
||||||
ret = -2;
|
|
||||||
goto ret_close_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop over layers and write CSV lines */
|
|
||||||
for (info_iter = settings->layer_infos; info_iter; info_iter = info_iter->next) {
|
|
||||||
linfo = (struct layer_info *)info_iter->data;
|
|
||||||
|
|
||||||
layer_settings_gen_csv_line(string, linfo);
|
|
||||||
g_output_stream_write(w_fstream, string->str, sizeof(gchar), NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete string */
|
|
||||||
g_string_free(string, TRUE);
|
|
||||||
ret_close_file:
|
|
||||||
g_output_stream_flush(w_fstream, NULL, NULL);
|
|
||||||
g_output_stream_close(w_fstream, NULL, NULL);
|
|
||||||
g_object_unref(w_fstream);
|
|
||||||
ret_unref_file:
|
|
||||||
g_object_unref(file);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Load a line from \p stream and parse try to parse it as layer information
|
|
||||||
* @param stream Input data stream
|
|
||||||
* @param linfo Layer info struct to fill
|
|
||||||
* @return 1 if malformatted line, 0 if parsing was successful and parameters are valid, -1 if file end
|
|
||||||
*/
|
|
||||||
static int layer_settings_load_csv_line_from_stream(GDataInputStream *stream, struct layer_info *linfo)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
gsize len;
|
|
||||||
gchar *line;
|
|
||||||
GRegex *regex;
|
|
||||||
GMatchInfo *mi;
|
|
||||||
char *match;
|
|
||||||
|
|
||||||
if (!linfo) {
|
|
||||||
ret = 1;
|
|
||||||
goto ret_direct;
|
|
||||||
}
|
|
||||||
|
|
||||||
regex = g_regex_new("^(?<layer>[0-9]+),(?<r>[0-9\\.]+),(?<g>[0-9\\.]+),(?<b>[0-9\\.]+),(?<a>[0-9\\.]+),(?<export>[01]),(?<name>.*)$", 0, 0, NULL);
|
|
||||||
|
|
||||||
line = g_data_input_stream_read_line(stream, &len, NULL, NULL);
|
|
||||||
if (!line) {
|
|
||||||
ret = -1;
|
|
||||||
goto destroy_regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Match line in CSV */
|
|
||||||
g_regex_match(regex, line, 0, &mi);
|
|
||||||
if (g_match_info_matches(mi)) {
|
|
||||||
/* Line is valid */
|
|
||||||
match = g_match_info_fetch_named(mi, "layer");
|
|
||||||
linfo->layer = (int)g_ascii_strtoll(match, NULL, 10);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "r");
|
|
||||||
linfo->color.red = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "g");
|
|
||||||
linfo->color.green = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "b");
|
|
||||||
linfo->color.blue = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "a");
|
|
||||||
linfo->color.alpha = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "export");
|
|
||||||
linfo->render = ((!strcmp(match, "1")) ? 1 : 0);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "name");
|
|
||||||
linfo->name = match;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
/* Line is malformatted */
|
|
||||||
printf("Could not recognize line in CSV as valid entry: %s\n", line);
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_match_info_free(mi);
|
|
||||||
g_free(line);
|
|
||||||
destroy_regex:
|
|
||||||
g_regex_unref(regex);
|
|
||||||
ret_direct:
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
|
|
||||||
{
|
|
||||||
GFile *file;
|
|
||||||
int ret = 0;
|
|
||||||
GInputStream *in_stream;
|
|
||||||
GDataInputStream *data_stream;
|
|
||||||
int parser_ret;
|
|
||||||
struct layer_info linfo;
|
|
||||||
|
|
||||||
file = g_file_new_for_path(path);
|
|
||||||
in_stream = G_INPUT_STREAM(g_file_read(file, NULL, NULL));
|
|
||||||
if (!in_stream) {
|
|
||||||
ret = -1;
|
|
||||||
goto ret_destroy_file;
|
|
||||||
}
|
|
||||||
/* Delete old settings */
|
|
||||||
layer_settings_clear(settings);
|
|
||||||
|
|
||||||
data_stream = g_data_input_stream_new(in_stream);
|
|
||||||
|
|
||||||
while ((parser_ret = layer_settings_load_csv_line_from_stream(data_stream, &linfo)) >= 0) {
|
|
||||||
/* Line broken */
|
|
||||||
if (parser_ret == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
layer_settings_append_layer_info(settings, &linfo);
|
|
||||||
/* Clear name to prevent memory leak */
|
|
||||||
if (linfo.name)
|
|
||||||
g_free(linfo.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_object_unref(data_stream);
|
|
||||||
g_object_unref(in_stream);
|
|
||||||
ret_destroy_file:
|
|
||||||
g_object_unref(file);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
68
main.c
68
main.c
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include <gds-render/gds-render-gui.h>
|
#include <gds-render/gds-render-gui.h>
|
||||||
#include <gds-render/command-line.h>
|
#include <gds-render/command-line.h>
|
||||||
#include <gds-render/output-renderers/external-renderer.h>
|
#include <gds-render/external-renderer.h>
|
||||||
#include <gds-render/version.h>
|
#include <gds-render/version.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,13 +90,13 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
|
|||||||
(void)action;
|
(void)action;
|
||||||
(void)parameter;
|
(void)parameter;
|
||||||
|
|
||||||
builder = gtk_builder_new_from_resource("/gui/about.glade");
|
builder = gtk_builder_new_from_resource("/about.glade");
|
||||||
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
|
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
|
||||||
gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL);
|
gtk_window_set_transient_for(GTK_WINDOW(dialog), NULL);
|
||||||
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string);
|
gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(dialog), _app_version_string);
|
||||||
|
|
||||||
/* Load icon from resource */
|
/* Load icon from resource */
|
||||||
logo_buf = gdk_pixbuf_new_from_resource_at_scale("/images/logo.svg", 100, 100, TRUE, &error);
|
logo_buf = gdk_pixbuf_new_from_resource_at_scale("/logo.svg", 100, 100, TRUE, &error);
|
||||||
if (logo_buf) {
|
if (logo_buf) {
|
||||||
/* Set logo */
|
/* Set logo */
|
||||||
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo_buf);
|
gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(dialog), logo_buf);
|
||||||
@ -240,25 +240,30 @@ int main(int argc, char **argv)
|
|||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GOptionContext *context;
|
GOptionContext *context;
|
||||||
gchar *gds_name;
|
gchar *gds_name;
|
||||||
gchar **output_paths = NULL;
|
gchar *basename;
|
||||||
gchar *mappingname = NULL;
|
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
|
||||||
gchar *cellname = NULL;
|
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE, svg = FALSE;
|
||||||
gchar **renderer_args = NULL;
|
gboolean version = FALSE;
|
||||||
gboolean version = FALSE, pdf_standalone = FALSE, pdf_layers = FALSE;
|
|
||||||
gchar *custom_library_path = NULL;
|
gchar *custom_library_path = NULL;
|
||||||
|
gchar *custom_library_file_name = NULL;
|
||||||
int scale = 1000;
|
int scale = 1000;
|
||||||
int app_status = 0;
|
int app_status = 0;
|
||||||
|
|
||||||
GOptionEntry entries[] = {
|
GOptionEntry entries[] = {
|
||||||
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL},
|
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL},
|
||||||
{"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args, "Renderer to use. Can be used multiple times.", "pdf|svg|tikz|ext"},
|
{"tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", 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 },
|
||||||
{"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>" },
|
||||||
{"output-file", 'o', 0, G_OPTION_ARG_FILENAME_ARRAY, &output_paths, "Output file path. Can be used multiple times.", "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" },
|
||||||
|
//{"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"},
|
{"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}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -282,6 +287,9 @@ int main(int argc, char **argv)
|
|||||||
scale = 1;
|
scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No format selected */
|
||||||
|
if (!(tikz || pdf || svg))
|
||||||
|
tikz = TRUE;
|
||||||
|
|
||||||
/* Get gds name */
|
/* Get gds name */
|
||||||
gds_name = argv[1];
|
gds_name = argv[1];
|
||||||
@ -291,26 +299,36 @@ int main(int argc, char **argv)
|
|||||||
printf("Ignored argument: %s", argv[i]);
|
printf("Ignored argument: %s", argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
app_status =
|
/* Check if PDF/TeX names are supplied. if not generate */
|
||||||
command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
|
basename = g_path_get_basename(gds_name);
|
||||||
custom_library_path, pdf_standalone, pdf_layers, scale);
|
|
||||||
|
|
||||||
|
if (!texname)
|
||||||
|
texname = g_strdup_printf("./%s.tex", basename);
|
||||||
|
|
||||||
|
if (!pdfname)
|
||||||
|
pdfname = g_strdup_printf("./%s.pdf", basename);
|
||||||
|
|
||||||
|
if (!svgname)
|
||||||
|
svgname = g_strdup_printf("./%s.svg", basename);
|
||||||
|
|
||||||
|
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
|
||||||
|
mappingname, cellname, (double)scale,
|
||||||
|
pdf_layers, pdf_standalone, svg, svgname,
|
||||||
|
custom_library_path, custom_library_file_name);
|
||||||
|
/* Clean up */
|
||||||
|
g_free(pdfname);
|
||||||
|
g_free(texname);
|
||||||
|
g_free(svgname);
|
||||||
|
g_free(basename);
|
||||||
|
if (mappingname)
|
||||||
|
g_free(mappingname);
|
||||||
|
if (cellname)
|
||||||
|
g_free(cellname);
|
||||||
|
app_status = 0;
|
||||||
} else {
|
} else {
|
||||||
app_status = start_gui(argc, argv);
|
app_status = start_gui(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_status:
|
ret_status:
|
||||||
/* If necessary, free command line parameters */
|
|
||||||
if (output_paths)
|
|
||||||
g_strfreev(output_paths);
|
|
||||||
if (renderer_args)
|
|
||||||
g_strfreev(renderer_args);
|
|
||||||
if (mappingname)
|
|
||||||
g_free(mappingname);
|
|
||||||
if (cellname)
|
|
||||||
free(cellname);
|
|
||||||
if (custom_library_path)
|
|
||||||
free(custom_library_path);
|
|
||||||
|
|
||||||
return app_status;
|
return app_status;
|
||||||
}
|
}
|
||||||
|
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 ExternalRenderer
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <gds-render/output-renderers/external-renderer.h>
|
|
||||||
|
|
||||||
struct _ExternalRenderer {
|
|
||||||
GdsOutputRenderer parent;
|
|
||||||
char *shared_object_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_SO_PATH = 1, /**< @brief Shared object path property */
|
|
||||||
N_PROPERTIES /**< @brief Used to get property count */
|
|
||||||
};
|
|
||||||
|
|
||||||
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 scale the scaling value to scale the output cell down by.
|
|
||||||
* @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 *, const char *, double) = NULL;
|
|
||||||
void *so_handle = NULL;
|
|
||||||
char *error_msg;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!so_path) {
|
|
||||||
fprintf(stderr, "Path to shared object not set!\n");
|
|
||||||
return -3000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check parameter sanity */
|
|
||||||
if (!output_file || !toplevel_cell || !layer_info_list)
|
|
||||||
return -3000;
|
|
||||||
|
|
||||||
/* Load shared object */
|
|
||||||
so_handle = dlopen(so_path, RTLD_LAZY);
|
|
||||||
if (!so_handle) {
|
|
||||||
fprintf(stderr, "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 *, const char *, double))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
|
|
||||||
error_msg = dlerror();
|
|
||||||
if (error_msg != NULL) {
|
|
||||||
fprintf(stderr, "Rendering function not found in library:\n%s\n", error_msg);
|
|
||||||
goto ret_close_so_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute */
|
|
||||||
if (so_render_func) {
|
|
||||||
g_message("Calling external renderer.");
|
|
||||||
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
|
|
||||||
g_message("External renderer finished.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_close_so_handle:
|
|
||||||
dlclose(so_handle);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int external_renderer_render_output(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
ExternalRenderer *ext_renderer = GDS_RENDER_EXTERNAL_RENDERER(renderer);
|
|
||||||
LayerSettings *settings;
|
|
||||||
GList *layer_infos = NULL;
|
|
||||||
const char *output_file;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
output_file = gds_output_renderer_get_output_file(renderer);
|
|
||||||
settings = gds_output_renderer_get_and_ref_layer_settings(renderer);
|
|
||||||
|
|
||||||
/* Set layer info list. In case of failure it remains NULL */
|
|
||||||
if (settings)
|
|
||||||
layer_infos = layer_settings_get_layer_info_list(settings);
|
|
||||||
|
|
||||||
ret = external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path);
|
|
||||||
if (settings)
|
|
||||||
g_object_unref(settings);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void external_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
ExternalRenderer *self;
|
|
||||||
|
|
||||||
self = GDS_RENDER_EXTERNAL_RENDERER(obj);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_SO_PATH:
|
|
||||||
g_value_set_string(value, self->shared_object_path);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void external_renderer_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
ExternalRenderer *self;
|
|
||||||
|
|
||||||
self = GDS_RENDER_EXTERNAL_RENDERER(obj);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_SO_PATH:
|
|
||||||
if (self->shared_object_path)
|
|
||||||
g_free(self->shared_object_path);
|
|
||||||
self->shared_object_path = g_value_dup_string(value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void external_renderer_dispose(GObject *self_obj)
|
|
||||||
{
|
|
||||||
ExternalRenderer *self = GDS_RENDER_EXTERNAL_RENDERER(self_obj);
|
|
||||||
|
|
||||||
if (self->shared_object_path) {
|
|
||||||
g_free(self->shared_object_path);
|
|
||||||
self->shared_object_path = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
G_OBJECT_CLASS(external_renderer_parent_class)->dispose(self_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec *external_renderer_properties[N_PROPERTIES] = {NULL};
|
|
||||||
|
|
||||||
static void external_renderer_class_init(ExternalRendererClass *klass)
|
|
||||||
{
|
|
||||||
GdsOutputRendererClass *inherited_parent_class;
|
|
||||||
GObjectClass *oclass;
|
|
||||||
|
|
||||||
inherited_parent_class = GDS_RENDER_OUTPUT_RENDERER_CLASS(klass);
|
|
||||||
oclass = G_OBJECT_CLASS(klass);
|
|
||||||
|
|
||||||
/* Override virtual function */
|
|
||||||
inherited_parent_class->render_output = external_renderer_render_output;
|
|
||||||
|
|
||||||
/* Setup Gobject callbacks */
|
|
||||||
oclass->set_property = external_renderer_set_property;
|
|
||||||
oclass->get_property = external_renderer_get_property;
|
|
||||||
oclass->dispose = external_renderer_dispose;
|
|
||||||
|
|
||||||
/* Setup properties */
|
|
||||||
external_renderer_properties[PROP_SO_PATH] =
|
|
||||||
g_param_spec_string("shared-object-path",
|
|
||||||
"Shared object file path",
|
|
||||||
"Path to the shared object to search rendering function in.",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READWRITE);
|
|
||||||
g_object_class_install_properties(oclass, N_PROPERTIES, external_renderer_properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void external_renderer_init(ExternalRenderer *self)
|
|
||||||
{
|
|
||||||
self->shared_object_path = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalRenderer *external_renderer_new()
|
|
||||||
{
|
|
||||||
return g_object_new(GDS_RENDER_TYPE_EXTERNAL_RENDERER, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalRenderer *external_renderer_new_with_so(const char *so_path)
|
|
||||||
{
|
|
||||||
return g_object_new(GDS_RENDER_TYPE_EXTERNAL_RENDERER, "shared-object-path", so_path, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,449 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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 gds-output-renderer.c
|
|
||||||
* @brief Base GObject class for output renderers
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @addtogroup GdsOutputRenderer
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/output-renderers/gds-output-renderer.h>
|
|
||||||
|
|
||||||
struct renderer_params {
|
|
||||||
struct gds_cell *cell;
|
|
||||||
double scale;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct idle_function_params {
|
|
||||||
GMutex message_lock;
|
|
||||||
char *status_message;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
gchar *output_file;
|
|
||||||
LayerSettings *layer_settings;
|
|
||||||
GMutex settings_lock;
|
|
||||||
gboolean mutex_init_status;
|
|
||||||
GTask *task;
|
|
||||||
GMainContext *main_context;
|
|
||||||
struct renderer_params async_params;
|
|
||||||
struct idle_function_params idle_function_parameters;
|
|
||||||
gpointer padding[11];
|
|
||||||
} GdsOutputRendererPrivate;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
PROP_OUTPUT_FILE = 1,
|
|
||||||
PROP_LAYER_SETTINGS,
|
|
||||||
N_PROPERTIES
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE(GdsOutputRenderer, gds_output_renderer, G_TYPE_OBJECT)
|
|
||||||
|
|
||||||
enum gds_output_renderer_signal_ids {ASYNC_FINISHED = 0, ASYNC_PROGRESS_CHANGED, GDS_OUTPUT_RENDERER_SIGNAL_COUNT};
|
|
||||||
static guint gds_output_renderer_signals[GDS_OUTPUT_RENDERER_SIGNAL_COUNT];
|
|
||||||
|
|
||||||
static int gds_output_renderer_render_dummy(GdsOutputRenderer *renderer,
|
|
||||||
struct gds_cell *cell,
|
|
||||||
double scale)
|
|
||||||
{
|
|
||||||
(void)renderer;
|
|
||||||
(void)cell;
|
|
||||||
(void)scale;
|
|
||||||
|
|
||||||
g_warning("Output renderer does not define a render_output function!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gds_output_renderer_dispose(GObject *self_obj)
|
|
||||||
{
|
|
||||||
GdsOutputRenderer *renderer = GDS_RENDER_OUTPUT_RENDERER(self_obj);
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
|
|
||||||
if (priv->mutex_init_status) {
|
|
||||||
/* Try locking the mutex, to test if it's free */
|
|
||||||
g_mutex_lock(&priv->settings_lock);
|
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
|
||||||
g_mutex_clear(&priv->settings_lock);
|
|
||||||
|
|
||||||
g_mutex_lock(&priv->idle_function_parameters.message_lock);
|
|
||||||
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
|
|
||||||
g_mutex_clear(&priv->idle_function_parameters.message_lock);
|
|
||||||
|
|
||||||
priv->mutex_init_status = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_object(&priv->task);
|
|
||||||
|
|
||||||
if (priv->output_file)
|
|
||||||
g_free(priv->output_file);
|
|
||||||
|
|
||||||
g_clear_object(&priv->layer_settings);
|
|
||||||
|
|
||||||
/* Chain up to parent class */
|
|
||||||
G_OBJECT_CLASS(gds_output_renderer_parent_class)->dispose(self_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gds_output_renderer_get_property(GObject *obj, guint property_id, GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
GdsOutputRenderer *self = GDS_RENDER_OUTPUT_RENDERER(obj);
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(self);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_OUTPUT_FILE:
|
|
||||||
g_value_set_string(value, priv->output_file);
|
|
||||||
break;
|
|
||||||
case PROP_LAYER_SETTINGS:
|
|
||||||
g_value_set_object(value, priv->layer_settings);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gds_output_renderer_set_property(GObject *obj, guint property_id, const GValue *value, GParamSpec *pspec)
|
|
||||||
{
|
|
||||||
GdsOutputRenderer *self = GDS_RENDER_OUTPUT_RENDERER(obj);
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(self);
|
|
||||||
|
|
||||||
switch (property_id) {
|
|
||||||
case PROP_OUTPUT_FILE:
|
|
||||||
g_mutex_lock(&priv->settings_lock);
|
|
||||||
if (priv->output_file)
|
|
||||||
g_free(priv->output_file);
|
|
||||||
priv->output_file = g_strdup(g_value_get_string(value));
|
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
|
||||||
break;
|
|
||||||
case PROP_LAYER_SETTINGS:
|
|
||||||
g_mutex_lock(&priv->settings_lock);
|
|
||||||
g_clear_object(&priv->layer_settings);
|
|
||||||
priv->layer_settings = g_value_get_object(value);
|
|
||||||
g_object_ref(priv->layer_settings);
|
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GParamSpec *gds_output_renderer_properties[N_PROPERTIES] = {NULL};
|
|
||||||
|
|
||||||
static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *oclass = G_OBJECT_CLASS(klass);
|
|
||||||
GType progress_changed_param_types[1] = {G_TYPE_POINTER};
|
|
||||||
|
|
||||||
klass->render_output = gds_output_renderer_render_dummy;
|
|
||||||
|
|
||||||
oclass->dispose = gds_output_renderer_dispose;
|
|
||||||
oclass->set_property = gds_output_renderer_set_property;
|
|
||||||
oclass->get_property = gds_output_renderer_get_property;
|
|
||||||
|
|
||||||
/* Setup properties */
|
|
||||||
gds_output_renderer_properties[PROP_OUTPUT_FILE] =
|
|
||||||
g_param_spec_string("output-file", "output file", "Output file for renderer",
|
|
||||||
NULL, G_PARAM_READWRITE);
|
|
||||||
gds_output_renderer_properties[PROP_LAYER_SETTINGS] =
|
|
||||||
g_param_spec_object("layer-settings", "Layer Settings object",
|
|
||||||
"Object containing the layer rendering information",
|
|
||||||
GDS_RENDER_TYPE_LAYER_SETTINGS, G_PARAM_READWRITE);
|
|
||||||
g_object_class_install_properties(oclass, N_PROPERTIES, gds_output_renderer_properties);
|
|
||||||
|
|
||||||
/* Setup output signals */
|
|
||||||
gds_output_renderer_signals[ASYNC_FINISHED] =
|
|
||||||
g_signal_newv("async-finished", GDS_RENDER_TYPE_OUTPUT_RENDERER,
|
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
gds_output_renderer_signals[ASYNC_PROGRESS_CHANGED] =
|
|
||||||
g_signal_newv("progress-changed", GDS_RENDER_TYPE_OUTPUT_RENDERER,
|
|
||||||
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
1,
|
|
||||||
progress_changed_param_types);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gds_output_renderer_init(GdsOutputRenderer *self)
|
|
||||||
{
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(self);
|
|
||||||
|
|
||||||
priv->layer_settings = NULL;
|
|
||||||
priv->output_file = NULL;
|
|
||||||
priv->task = NULL;
|
|
||||||
priv->mutex_init_status = TRUE;
|
|
||||||
priv->main_context = NULL;
|
|
||||||
priv->idle_function_parameters.status_message = NULL;
|
|
||||||
g_mutex_init(&priv->settings_lock);
|
|
||||||
g_mutex_init(&priv->idle_function_parameters.message_lock);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GdsOutputRenderer *gds_output_renderer_new()
|
|
||||||
{
|
|
||||||
return GDS_RENDER_OUTPUT_RENDERER(g_object_new(GDS_RENDER_TYPE_OUTPUT_RENDERER, NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
GdsOutputRenderer *gds_output_renderer_new_with_props(const char *output_file, LayerSettings *layer_settings)
|
|
||||||
{
|
|
||||||
return GDS_RENDER_OUTPUT_RENDERER(g_object_new(GDS_RENDER_TYPE_OUTPUT_RENDERER,
|
|
||||||
"layer-settings", layer_settings,
|
|
||||||
"output-file", output_file,
|
|
||||||
NULL));
|
|
||||||
}
|
|
||||||
|
|
||||||
void gds_output_renderer_set_output_file(GdsOutputRenderer *renderer, const gchar *file_name)
|
|
||||||
{
|
|
||||||
g_return_if_fail(GDS_RENDER_IS_OUTPUT_RENDERER(renderer));
|
|
||||||
|
|
||||||
/* Check if the filename is actually filled */
|
|
||||||
if (!file_name || !file_name[0])
|
|
||||||
return;
|
|
||||||
g_object_set(renderer, "output-file", file_name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *gds_output_renderer_get_output_file(GdsOutputRenderer *renderer)
|
|
||||||
{
|
|
||||||
const char *file = NULL;
|
|
||||||
|
|
||||||
g_object_get(renderer, "output-file", &file, NULL);
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer *renderer)
|
|
||||||
{
|
|
||||||
LayerSettings *ret = NULL;
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
|
|
||||||
/* Acquire settings lock */
|
|
||||||
g_mutex_lock(&priv->settings_lock);
|
|
||||||
|
|
||||||
/* This function seems to already reference the LayerSettings object */
|
|
||||||
g_object_get(renderer, "layer-settings", &ret, NULL);
|
|
||||||
/* Reference it, so it is not cleared by another thread overwriting the property */
|
|
||||||
//g_object_ref(ret);
|
|
||||||
|
|
||||||
/* It is now safe to clear the lock */
|
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSettings *settings)
|
|
||||||
{
|
|
||||||
g_return_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings));
|
|
||||||
|
|
||||||
g_object_set(renderer, "layer-settings", settings, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
GdsOutputRendererClass *klass;
|
|
||||||
GdsOutputRendererPrivate *priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
|
|
||||||
if (GDS_RENDER_IS_OUTPUT_RENDERER(renderer) == FALSE) {
|
|
||||||
g_error("Output Renderer not valid.");
|
|
||||||
return GDS_OUTPUT_RENDERER_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!priv->output_file || !priv->output_file[0]) {
|
|
||||||
g_error("No/invalid output file set.");
|
|
||||||
return GDS_OUTPUT_RENDERER_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!priv->layer_settings) {
|
|
||||||
g_error("No layer specification supplied.");
|
|
||||||
return GDS_OUTPUT_RENDERER_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cell) {
|
|
||||||
g_error("Output renderer called without cell to render.");
|
|
||||||
return GDS_OUTPUT_RENDERER_PARAM_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
klass = GDS_RENDER_OUTPUT_RENDERER_GET_CLASS(renderer);
|
|
||||||
if (klass->render_output == NULL) {
|
|
||||||
g_critical("Output Renderer: Rendering function broken. This is a bug.");
|
|
||||||
return GDS_OUTPUT_RENDERER_GEN_ERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = klass->render_output(renderer, cell, scale);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gds_output_renderer_async_wrapper(GTask *task,
|
|
||||||
gpointer source_object,
|
|
||||||
gpointer task_data,
|
|
||||||
GCancellable *cancellable)
|
|
||||||
{
|
|
||||||
GdsOutputRenderer *renderer;
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
renderer = GDS_RENDER_OUTPUT_RENDERER(source_object);
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
if (!priv) {
|
|
||||||
ret = -1000;
|
|
||||||
goto ret_from_task;
|
|
||||||
}
|
|
||||||
if(!priv->mutex_init_status) {
|
|
||||||
ret = -1001;
|
|
||||||
goto ret_from_task;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gds_output_renderer_render_output(renderer, priv->async_params.cell, priv->async_params.scale);
|
|
||||||
|
|
||||||
ret_from_task:
|
|
||||||
g_task_return_int(task, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gds_output_renderer_async_finished(GObject *src_obj, GAsyncResult *res, gpointer user_data)
|
|
||||||
{
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
(void)user_data;
|
|
||||||
(void)res; /* Will hopefully be destroyed later */
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(GDS_RENDER_OUTPUT_RENDERER(src_obj));
|
|
||||||
|
|
||||||
priv->main_context = NULL;
|
|
||||||
|
|
||||||
g_signal_emit(src_obj, gds_output_renderer_signals[ASYNC_FINISHED], 0);
|
|
||||||
g_clear_object(&priv->task);
|
|
||||||
|
|
||||||
/* Clear reference set in gds_output_renderer_render_output_async() */
|
|
||||||
g_object_unref(src_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
|
|
||||||
{
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
if (priv->task) {
|
|
||||||
g_warning("renderer already started asynchronously");
|
|
||||||
return -2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->task = g_task_new(renderer, NULL, gds_output_renderer_async_finished, NULL);
|
|
||||||
g_task_set_name(priv->task, "Rendering Thread");
|
|
||||||
|
|
||||||
g_mutex_lock(&priv->settings_lock);
|
|
||||||
priv->async_params.cell = cell;
|
|
||||||
priv->async_params.scale = scale;
|
|
||||||
priv->main_context = g_main_context_default();
|
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
|
||||||
|
|
||||||
/* Self reference. This could end up being nasty... */
|
|
||||||
g_object_ref(renderer);
|
|
||||||
|
|
||||||
/* Do the magic */
|
|
||||||
g_task_run_in_thread(priv->task, gds_output_renderer_async_wrapper);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean idle_event_processor_callback(gpointer user_data)
|
|
||||||
{
|
|
||||||
GdsOutputRenderer *renderer;
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
char *status_message;
|
|
||||||
|
|
||||||
/* If the rendering is finished before the mainloop gets to this point
|
|
||||||
* the renderer is already disposed. Catch this!
|
|
||||||
*/
|
|
||||||
if (!GDS_RENDER_IS_OUTPUT_RENDERER(user_data))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
renderer = GDS_RENDER_OUTPUT_RENDERER(user_data);
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
|
|
||||||
if (g_mutex_trylock(&priv->idle_function_parameters.message_lock)) {
|
|
||||||
status_message = priv->idle_function_parameters.status_message;
|
|
||||||
g_signal_emit(renderer, gds_output_renderer_signals[ASYNC_PROGRESS_CHANGED], 0, status_message);
|
|
||||||
g_free(priv->idle_function_parameters.status_message);
|
|
||||||
priv->idle_function_parameters.status_message = NULL;
|
|
||||||
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
|
|
||||||
} else {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status)
|
|
||||||
{
|
|
||||||
GSource *idle_event_processor;
|
|
||||||
GdsOutputRendererPrivate *priv;
|
|
||||||
gboolean skip_source = FALSE;
|
|
||||||
|
|
||||||
g_return_if_fail(GDS_RENDER_IS_OUTPUT_RENDERER(renderer));
|
|
||||||
if (!status)
|
|
||||||
return;
|
|
||||||
|
|
||||||
priv = gds_output_renderer_get_instance_private(renderer);
|
|
||||||
|
|
||||||
/* If rendering is not async */
|
|
||||||
if (!priv->main_context)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_mutex_lock(&priv->idle_function_parameters.message_lock);
|
|
||||||
if (priv->idle_function_parameters.status_message) {
|
|
||||||
g_free(priv->idle_function_parameters.status_message);
|
|
||||||
|
|
||||||
/* Skip adding new idle source because there's already an active one */
|
|
||||||
skip_source = TRUE;
|
|
||||||
}
|
|
||||||
priv->idle_function_parameters.status_message = g_strdup(status);
|
|
||||||
g_mutex_unlock(&priv->idle_function_parameters.message_lock);
|
|
||||||
|
|
||||||
if (!skip_source) {
|
|
||||||
idle_event_processor = g_idle_source_new();
|
|
||||||
g_source_set_callback(idle_event_processor, idle_event_processor_callback, (gpointer)renderer, NULL);
|
|
||||||
g_source_attach(idle_event_processor, priv->main_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,255 +0,0 @@
|
|||||||
800000
|
|
||||||
008000
|
|
||||||
808000
|
|
||||||
000080
|
|
||||||
800080
|
|
||||||
008080
|
|
||||||
c0c0c0
|
|
||||||
808080
|
|
||||||
ff0000
|
|
||||||
00ff00
|
|
||||||
ffff00
|
|
||||||
0000ff
|
|
||||||
ff00ff
|
|
||||||
00ffff
|
|
||||||
f105f5
|
|
||||||
000000
|
|
||||||
00005f
|
|
||||||
000087
|
|
||||||
0000af
|
|
||||||
0000d7
|
|
||||||
0000ff
|
|
||||||
005f00
|
|
||||||
005f5f
|
|
||||||
005f87
|
|
||||||
005faf
|
|
||||||
005fd7
|
|
||||||
005fff
|
|
||||||
008700
|
|
||||||
00875f
|
|
||||||
008787
|
|
||||||
0087af
|
|
||||||
0087d7
|
|
||||||
0087ff
|
|
||||||
00af00
|
|
||||||
00af5f
|
|
||||||
00af87
|
|
||||||
00afaf
|
|
||||||
00afd7
|
|
||||||
00afff
|
|
||||||
00d700
|
|
||||||
00d75f
|
|
||||||
00d787
|
|
||||||
00d7af
|
|
||||||
00d7d7
|
|
||||||
00d7ff
|
|
||||||
00ff00
|
|
||||||
00ff5f
|
|
||||||
00ff87
|
|
||||||
00ffaf
|
|
||||||
00ffd7
|
|
||||||
00ffff
|
|
||||||
5f0000
|
|
||||||
5f005f
|
|
||||||
5f0087
|
|
||||||
5f00af
|
|
||||||
5f00d7
|
|
||||||
5f00ff
|
|
||||||
5f5f00
|
|
||||||
5f5f5f
|
|
||||||
5f5f87
|
|
||||||
5f5faf
|
|
||||||
5f5fd7
|
|
||||||
5f5fff
|
|
||||||
5f8700
|
|
||||||
5f875f
|
|
||||||
5f8787
|
|
||||||
5f87af
|
|
||||||
5f87d7
|
|
||||||
5f87ff
|
|
||||||
5faf00
|
|
||||||
5faf5f
|
|
||||||
5faf87
|
|
||||||
5fafaf
|
|
||||||
5fafd7
|
|
||||||
5fafff
|
|
||||||
5fd700
|
|
||||||
5fd75f
|
|
||||||
5fd787
|
|
||||||
5fd7af
|
|
||||||
5fd7d7
|
|
||||||
5fd7ff
|
|
||||||
5fff00
|
|
||||||
5fff5f
|
|
||||||
5fff87
|
|
||||||
5fffaf
|
|
||||||
5fffd7
|
|
||||||
5fffff
|
|
||||||
870000
|
|
||||||
87005f
|
|
||||||
870087
|
|
||||||
8700af
|
|
||||||
8700d7
|
|
||||||
8700ff
|
|
||||||
875f00
|
|
||||||
875f5f
|
|
||||||
875f87
|
|
||||||
875faf
|
|
||||||
875fd7
|
|
||||||
875fff
|
|
||||||
878700
|
|
||||||
87875f
|
|
||||||
878787
|
|
||||||
8787af
|
|
||||||
8787d7
|
|
||||||
8787ff
|
|
||||||
87af00
|
|
||||||
87af5f
|
|
||||||
87af87
|
|
||||||
87afaf
|
|
||||||
87afd7
|
|
||||||
87afff
|
|
||||||
87d700
|
|
||||||
87d75f
|
|
||||||
87d787
|
|
||||||
87d7af
|
|
||||||
87d7d7
|
|
||||||
87d7ff
|
|
||||||
87ff00
|
|
||||||
87ff5f
|
|
||||||
87ff87
|
|
||||||
87ffaf
|
|
||||||
87ffd7
|
|
||||||
87ffff
|
|
||||||
af0000
|
|
||||||
af005f
|
|
||||||
af0087
|
|
||||||
af00af
|
|
||||||
af00d7
|
|
||||||
af00ff
|
|
||||||
af5f00
|
|
||||||
af5f5f
|
|
||||||
af5f87
|
|
||||||
af5faf
|
|
||||||
af5fd7
|
|
||||||
af5fff
|
|
||||||
af8700
|
|
||||||
af875f
|
|
||||||
af8787
|
|
||||||
af87af
|
|
||||||
af87d7
|
|
||||||
af87ff
|
|
||||||
afaf00
|
|
||||||
afaf5f
|
|
||||||
afaf87
|
|
||||||
afafaf
|
|
||||||
afafd7
|
|
||||||
afafff
|
|
||||||
afd700
|
|
||||||
afd75f
|
|
||||||
afd787
|
|
||||||
afd7af
|
|
||||||
afd7d7
|
|
||||||
afd7ff
|
|
||||||
afff00
|
|
||||||
afff5f
|
|
||||||
afff87
|
|
||||||
afffaf
|
|
||||||
afffd7
|
|
||||||
afffff
|
|
||||||
d70000
|
|
||||||
d7005f
|
|
||||||
d70087
|
|
||||||
d700af
|
|
||||||
d700d7
|
|
||||||
d700ff
|
|
||||||
d75f00
|
|
||||||
d75f5f
|
|
||||||
d75f87
|
|
||||||
d75faf
|
|
||||||
d75fd7
|
|
||||||
d75fff
|
|
||||||
d78700
|
|
||||||
d7875f
|
|
||||||
d78787
|
|
||||||
d787af
|
|
||||||
d787d7
|
|
||||||
d787ff
|
|
||||||
d7af00
|
|
||||||
d7af5f
|
|
||||||
d7af87
|
|
||||||
d7afaf
|
|
||||||
d7afd7
|
|
||||||
d7afff
|
|
||||||
d7d700
|
|
||||||
d7d75f
|
|
||||||
d7d787
|
|
||||||
d7d7af
|
|
||||||
d7d7d7
|
|
||||||
d7d7ff
|
|
||||||
d7ff00
|
|
||||||
d7ff5f
|
|
||||||
d7ff87
|
|
||||||
d7ffaf
|
|
||||||
d7ffd7
|
|
||||||
d7ffff
|
|
||||||
ff0000
|
|
||||||
ff005f
|
|
||||||
ff0087
|
|
||||||
ff00af
|
|
||||||
ff00d7
|
|
||||||
ff00ff
|
|
||||||
ff5f00
|
|
||||||
ff5f5f
|
|
||||||
ff5f87
|
|
||||||
ff5faf
|
|
||||||
ff5fd7
|
|
||||||
ff5fff
|
|
||||||
ff8700
|
|
||||||
ff875f
|
|
||||||
ff8787
|
|
||||||
ff87af
|
|
||||||
ff87d7
|
|
||||||
ff87ff
|
|
||||||
ffaf00
|
|
||||||
ffaf5f
|
|
||||||
ffaf87
|
|
||||||
ffafaf
|
|
||||||
ffafd7
|
|
||||||
ffafff
|
|
||||||
ffd700
|
|
||||||
ffd75f
|
|
||||||
ffd787
|
|
||||||
ffd7af
|
|
||||||
ffd7d7
|
|
||||||
ffd7ff
|
|
||||||
ffff00
|
|
||||||
ffff5f
|
|
||||||
ffff87
|
|
||||||
ffffaf
|
|
||||||
ffffd7
|
|
||||||
ffffff
|
|
||||||
080808
|
|
||||||
121212
|
|
||||||
1c1c1c
|
|
||||||
262626
|
|
||||||
303030
|
|
||||||
3a3a3a
|
|
||||||
444444
|
|
||||||
4e4e4e
|
|
||||||
585858
|
|
||||||
626262
|
|
||||||
6c6c6c
|
|
||||||
767676
|
|
||||||
808080
|
|
||||||
8a8a8a
|
|
||||||
949494
|
|
||||||
9e9e9e
|
|
||||||
a8a8a8
|
|
||||||
b2b2b2
|
|
||||||
bcbcbc
|
|
||||||
c6c6c6
|
|
||||||
d0d0d0
|
|
||||||
dadada
|
|
||||||
e4e4e4
|
|
||||||
eeeeee
|
|
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<gresources>
|
|
||||||
<gresource prefix="/gui">
|
|
||||||
<file compressed="true">main.glade</file>
|
|
||||||
<file compressed="true">about.glade</file>
|
|
||||||
<file>layer-widget.glade</file>
|
|
||||||
<file>dialog.glade</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/data">
|
|
||||||
<file compressed="true">color-palette.txt</file>
|
|
||||||
</gresource>
|
|
||||||
<gresource prefix="/images">
|
|
||||||
<file compressed="true" alias="logo.svg">../icon/gds-render.svg</file>
|
|
||||||
</gresource>
|
|
||||||
</gresources>
|
|
||||||
|
|
||||||
|
|
@ -28,16 +28,16 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
#include <gds-render/tree-renderer/lib-cell-renderer.h>
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
|
|
||||||
G_DEFINE_TYPE(LibCellRenderer, lib_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT)
|
G_DEFINE_TYPE(LibCellRenderer, lib_cell_renderer, GTK_TYPE_CELL_RENDERER_TEXT)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_LIB = 1, /**< @brief Library to display the name of */
|
PROP_LIB = 1,
|
||||||
PROP_CELL, /**< @brief Cell to display the name of */
|
PROP_CELL,
|
||||||
PROP_ERROR_LEVEL, /**< @brief Error level of cell/library for coloring */
|
PROP_ERROR_LEVEL,
|
||||||
PROP_COUNT /**< @brief Sentinel */
|
PROP_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
void lib_cell_renderer_init(LibCellRenderer *self)
|
void lib_cell_renderer_init(LibCellRenderer *self)
|
@ -28,8 +28,8 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gds-render/cell-selector/tree-store.h>
|
#include <gds-render/tree-renderer/tree-store.h>
|
||||||
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
#include <gds-render/tree-renderer/lib-cell-renderer.h>
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
#include <gds-render/gds-utils/gds-types.h>
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* GDSII-Converter
|
|
||||||
* Copyright (C) 2019 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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The drag and drop implementation is adapted from
|
|
||||||
* https://gitlab.gnome.org/GNOME/gtk/blob/gtk-3-22/tests/testlist3.c
|
|
||||||
*
|
|
||||||
* Thanks to the GTK3 people for creating these examples.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file activity-bar.c
|
|
||||||
* @brief Status bar indicating activity of the program
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup ActivityBar
|
|
||||||
* @ingroup Widgets
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/widgets/activity-bar.h>
|
|
||||||
|
|
||||||
/** @brief Opaque ActivityBar object. Not viewable outside this source file. */
|
|
||||||
struct _ActivityBar {
|
|
||||||
GtkBox super;
|
|
||||||
/* Private stuff */
|
|
||||||
GtkWidget *spinner;
|
|
||||||
GtkWidget *label;
|
|
||||||
};
|
|
||||||
|
|
||||||
G_DEFINE_TYPE(ActivityBar, activity_bar, GTK_TYPE_BOX)
|
|
||||||
|
|
||||||
static void activity_bar_dispose(GObject *obj)
|
|
||||||
{
|
|
||||||
ActivityBar *bar;
|
|
||||||
|
|
||||||
bar = ACTIVITY_BAR(obj);
|
|
||||||
|
|
||||||
/* Clear references on owned objects */
|
|
||||||
g_clear_object(&bar->label);
|
|
||||||
g_clear_object(&bar->spinner);
|
|
||||||
|
|
||||||
/* Chain up */
|
|
||||||
G_OBJECT_CLASS(activity_bar_parent_class)->dispose(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void activity_bar_class_init(ActivityBarClass *klass)
|
|
||||||
{
|
|
||||||
GObjectClass *oclass = G_OBJECT_CLASS(klass);
|
|
||||||
|
|
||||||
oclass->dispose = activity_bar_dispose;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void activity_bar_init(ActivityBar *self)
|
|
||||||
{
|
|
||||||
GtkContainer *box = GTK_CONTAINER(self);
|
|
||||||
|
|
||||||
/* Create Widgets */
|
|
||||||
self->label = gtk_label_new("");
|
|
||||||
self->spinner = gtk_spinner_new();
|
|
||||||
|
|
||||||
/* Add to this widget and show */
|
|
||||||
gtk_container_add(box, self->spinner);
|
|
||||||
gtk_container_add(box, self->label);
|
|
||||||
gtk_widget_show(self->label);
|
|
||||||
gtk_widget_show(self->spinner);
|
|
||||||
|
|
||||||
g_object_ref(self->spinner);
|
|
||||||
g_object_ref(self->label);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActivityBar *activity_bar_new()
|
|
||||||
{
|
|
||||||
ActivityBar *bar;
|
|
||||||
|
|
||||||
bar = ACTIVITY_BAR(g_object_new(TYPE_ACTIVITY_BAR, "orientation", GTK_ORIENTATION_HORIZONTAL, NULL));
|
|
||||||
if (bar)
|
|
||||||
activity_bar_set_ready(bar);
|
|
||||||
|
|
||||||
return bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Complete this once the task list is fully implemented */
|
|
||||||
void activity_bar_set_ready(ActivityBar *bar)
|
|
||||||
{
|
|
||||||
gtk_label_set_text(GTK_LABEL(bar->label), "Ready");
|
|
||||||
gtk_spinner_stop(GTK_SPINNER(bar->spinner));
|
|
||||||
}
|
|
||||||
|
|
||||||
void activity_bar_set_busy(ActivityBar *bar, const char *text)
|
|
||||||
{
|
|
||||||
gtk_label_set_text(GTK_LABEL(bar->label), (text ? text : "Working..."));
|
|
||||||
gtk_spinner_start(GTK_SPINNER(bar->spinner));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -270,7 +270,7 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self)
|
|||||||
|
|
||||||
dialog = &self->parent;
|
dialog = &self->parent;
|
||||||
|
|
||||||
builder = gtk_builder_new_from_resource("/gui/dialog.glade");
|
builder = gtk_builder_new_from_resource("/dialog.glade");
|
||||||
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
|
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
|
||||||
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio"));
|
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio"));
|
||||||
self->radio_cairo_pdf = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-pdf-radio"));
|
self->radio_cairo_pdf = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-pdf-radio"));
|
||||||
|
@ -62,7 +62,7 @@ static void layer_element_init(LayerElement *self)
|
|||||||
{
|
{
|
||||||
GtkBuilder *builder;
|
GtkBuilder *builder;
|
||||||
GtkWidget *glade_box;
|
GtkWidget *glade_box;
|
||||||
builder = gtk_builder_new_from_resource("/gui/layer-widget.glade");
|
builder = gtk_builder_new_from_resource("/layer-widget.glade");
|
||||||
glade_box = GTK_WIDGET(gtk_builder_get_object(builder, "box"));
|
glade_box = GTK_WIDGET(gtk_builder_get_object(builder, "box"));
|
||||||
gtk_container_add(GTK_CONTAINER(self), glade_box);
|
gtk_container_add(GTK_CONTAINER(self), glade_box);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user