Merge branch 'dev'
This commit is contained in:
commit
74eb17b2dc
@ -6,6 +6,8 @@ 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_compile_options(-Wall -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
|
||||||
|
|
||||||
add_subdirectory(resources)
|
add_subdirectory(resources)
|
||||||
add_subdirectory(doxygen)
|
add_subdirectory(doxygen)
|
||||||
add_subdirectory(version)
|
add_subdirectory(version)
|
||||||
@ -32,8 +34,6 @@ set(SOURCE
|
|||||||
${LAYER_SELECTOR_SOURCES}
|
${LAYER_SELECTOR_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_compile_options(-Wall -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c)
|
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c)
|
||||||
add_dependencies(${PROJECT_NAME} glib-resources)
|
add_dependencies(${PROJECT_NAME} glib-resources)
|
||||||
add_dependencies(${PROJECT_NAME} version)
|
add_dependencies(${PROJECT_NAME} version)
|
||||||
|
@ -1,176 +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 tree-store.h
|
|
||||||
* @brief Tree store implementation
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup GUI
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/cell-selector/tree-store.h>
|
|
||||||
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
|
||||||
#include <gds-render/gds-utils/gds-types.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief this function olny allows cells to be selected
|
|
||||||
* @param selection
|
|
||||||
* @param model
|
|
||||||
* @param path
|
|
||||||
* @param path_currently_selected
|
|
||||||
* @param data
|
|
||||||
* @return TRUE if element is selectable, FALSE if not
|
|
||||||
*/
|
|
||||||
static gboolean tree_sel_func(GtkTreeSelection *selection,
|
|
||||||
GtkTreeModel *model,
|
|
||||||
GtkTreePath *path,
|
|
||||||
gboolean path_currently_selected,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkTreeIter iter;
|
|
||||||
struct gds_cell *cell;
|
|
||||||
unsigned int error_level;
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
(void)selection;
|
|
||||||
(void)path_currently_selected;
|
|
||||||
(void)data;
|
|
||||||
|
|
||||||
gtk_tree_model_get_iter(model, &iter, path);
|
|
||||||
gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
|
|
||||||
|
|
||||||
/* Allow only rows with _valid_ cell to be selected */
|
|
||||||
if (cell) {
|
|
||||||
/* Cell available. Check if it passed the critical checks */
|
|
||||||
if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
|
|
||||||
ret = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
|
|
||||||
* @param model Tree model
|
|
||||||
* @param iter Current element / iter in Model to check
|
|
||||||
* @param data Data. Set to static stores variable
|
|
||||||
* @return TRUE if visible, else FALSE
|
|
||||||
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
|
|
||||||
*/
|
|
||||||
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
|
|
||||||
{
|
|
||||||
struct tree_stores *stores = (struct tree_stores *)data;
|
|
||||||
struct gds_cell *cell;
|
|
||||||
struct gds_library *lib;
|
|
||||||
gboolean result = FALSE;
|
|
||||||
const char *search_string;
|
|
||||||
|
|
||||||
if (!model || !iter || !stores)
|
|
||||||
goto exit_filter;
|
|
||||||
|
|
||||||
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
|
|
||||||
|
|
||||||
if (lib) {
|
|
||||||
result = TRUE;
|
|
||||||
goto exit_filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cell)
|
|
||||||
goto exit_filter;
|
|
||||||
|
|
||||||
search_string = gtk_entry_get_text(stores->search_entry);
|
|
||||||
|
|
||||||
/* Show all, if field is empty */
|
|
||||||
if (!strlen(search_string))
|
|
||||||
result = TRUE;
|
|
||||||
|
|
||||||
if (strstr(cell->name, search_string))
|
|
||||||
result = TRUE;
|
|
||||||
|
|
||||||
gtk_tree_view_expand_all(stores->base_tree_view);
|
|
||||||
|
|
||||||
exit_filter:
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void change_filter(GtkWidget *entry, gpointer data)
|
|
||||||
{
|
|
||||||
struct tree_stores *stores = (struct tree_stores *)data;
|
|
||||||
(void)entry;
|
|
||||||
|
|
||||||
gtk_tree_model_filter_refilter(stores->filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Setup a GtkTreeView with the necessary columns
|
|
||||||
* @param view Tree view to set up
|
|
||||||
* @param search_entry Entry field for search
|
|
||||||
* @return Tree stores for storing data inside the GtkTreeView
|
|
||||||
*/
|
|
||||||
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry)
|
|
||||||
{
|
|
||||||
static struct tree_stores stores;
|
|
||||||
GtkCellRenderer *render_dates;
|
|
||||||
GtkCellRenderer *render_cell;
|
|
||||||
GtkCellRenderer *render_lib;
|
|
||||||
GtkTreeViewColumn *column;
|
|
||||||
|
|
||||||
stores.base_tree_view = view;
|
|
||||||
stores.search_entry = search_entry;
|
|
||||||
|
|
||||||
stores.base_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
|
|
||||||
|
|
||||||
/* Searching */
|
|
||||||
if (search_entry) {
|
|
||||||
stores.filter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(GTK_TREE_MODEL(stores.base_store), NULL));
|
|
||||||
gtk_tree_model_filter_set_visible_func (stores.filter,
|
|
||||||
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
|
|
||||||
&stores, NULL);
|
|
||||||
g_signal_connect(GTK_SEARCH_ENTRY(search_entry), "search-changed", G_CALLBACK(change_filter), &stores);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_tree_view_set_model(view, GTK_TREE_MODEL(stores.filter));
|
|
||||||
|
|
||||||
render_dates = gtk_cell_renderer_text_new();
|
|
||||||
render_cell = lib_cell_renderer_new();
|
|
||||||
render_lib = lib_cell_renderer_new();
|
|
||||||
|
|
||||||
column = gtk_tree_view_column_new_with_attributes("Library", render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
|
|
||||||
gtk_tree_view_append_column(view, column);
|
|
||||||
|
|
||||||
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL,
|
|
||||||
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
|
|
||||||
gtk_tree_view_append_column(view, column);
|
|
||||||
|
|
||||||
column = gtk_tree_view_column_new_with_attributes("Mod. Date", render_dates, "text", CELL_SEL_MODDATE, NULL);
|
|
||||||
gtk_tree_view_append_column(view, column);
|
|
||||||
|
|
||||||
column = gtk_tree_view_column_new_with_attributes("Acc. Date", render_dates, "text", CELL_SEL_ACCESSDATE, NULL);
|
|
||||||
gtk_tree_view_append_column(view, column);
|
|
||||||
|
|
||||||
/* Callback for selection
|
|
||||||
* This prevents selecting a library */
|
|
||||||
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL);
|
|
||||||
|
|
||||||
return &stores;
|
|
||||||
}
|
|
||||||
/** @} */
|
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#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/layer-settings.h>
|
#include <gds-render/layer/layer-settings.h>
|
||||||
#include <gds-render/output-renderers/cairo-renderer.h>
|
#include <gds-render/output-renderers/cairo-renderer.h>
|
||||||
#include <gds-render/output-renderers/latex-renderer.h>
|
#include <gds-render/output-renderers/latex-renderer.h>
|
||||||
@ -225,9 +224,8 @@ int command_line_convert_gds(const char *gds_name,
|
|||||||
ret_destroy_library_list:
|
ret_destroy_library_list:
|
||||||
clear_lib_list(&libs);
|
clear_lib_list(&libs);
|
||||||
ret_clear_renderers:
|
ret_clear_renderers:
|
||||||
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) {
|
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next)
|
||||||
g_object_unref(list_iter->data);
|
g_object_unref(list_iter->data);
|
||||||
}
|
|
||||||
ret_destroy_layer_mapping:
|
ret_destroy_layer_mapping:
|
||||||
g_object_unref(layer_sett);
|
g_object_unref(layer_sett);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* @warning Although the GdsOutputRenderer class provides compatibility for asynchronous rendering,
|
* @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.
|
* 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.
|
* A allowed function to be called from the async rendering thread is #gds_output_renderer_update_async_progress 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.
|
* @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.
|
||||||
*
|
*
|
||||||
|
176
gds-render-gui.c
176
gds-render-gui.c
@ -35,7 +35,6 @@
|
|||||||
#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/widgets/activity-bar.h>
|
||||||
#include <gds-render/cell-selector/tree-store.h>
|
|
||||||
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
#include <gds-render/cell-selector/lib-cell-renderer.h>
|
||||||
#include <gds-render/output-renderers/latex-renderer.h>
|
#include <gds-render/output-renderers/latex-renderer.h>
|
||||||
#include <gds-render/output-renderers/cairo-renderer.h>
|
#include <gds-render/output-renderers/cairo-renderer.h>
|
||||||
@ -43,6 +42,16 @@
|
|||||||
#include <gds-render/geometric/cell-geometrics.h>
|
#include <gds-render/geometric/cell-geometrics.h>
|
||||||
#include <gds-render/version.h>
|
#include <gds-render/version.h>
|
||||||
|
|
||||||
|
/** @brief Columns of selection tree view */
|
||||||
|
enum cell_store_columns {
|
||||||
|
CELL_SEL_LIBRARY = 0,
|
||||||
|
CELL_SEL_CELL,
|
||||||
|
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
|
||||||
|
CELL_SEL_MODDATE,
|
||||||
|
CELL_SEL_ACCESSDATE,
|
||||||
|
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
|
||||||
|
};
|
||||||
|
|
||||||
enum gds_render_gui_signal_sig_ids {SIGNAL_WINDOW_CLOSED = 0, SIGNAL_COUNT};
|
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];
|
||||||
@ -64,6 +73,7 @@ struct _GdsRenderGui {
|
|||||||
GtkWidget *save_layer_button;
|
GtkWidget *save_layer_button;
|
||||||
GtkWidget *select_all_button;
|
GtkWidget *select_all_button;
|
||||||
GtkTreeStore *cell_tree_store;
|
GtkTreeStore *cell_tree_store;
|
||||||
|
GtkTreeModelFilter *cell_filter;
|
||||||
GtkWidget *cell_search_entry;
|
GtkWidget *cell_search_entry;
|
||||||
LayerSelector *layer_selector;
|
LayerSelector *layer_selector;
|
||||||
GtkTreeView *cell_tree_view;
|
GtkTreeView *cell_tree_view;
|
||||||
@ -124,6 +134,155 @@ static GString *generate_string_from_date(struct gds_time_field *date)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function only allows valid cells to be selected
|
||||||
|
* @param selection
|
||||||
|
* @param model
|
||||||
|
* @param path
|
||||||
|
* @param path_currently_selected
|
||||||
|
* @param data
|
||||||
|
* @return TRUE if element is selectable, FALSE if not
|
||||||
|
*/
|
||||||
|
static gboolean tree_sel_func(GtkTreeSelection *selection,
|
||||||
|
GtkTreeModel *model,
|
||||||
|
GtkTreePath *path,
|
||||||
|
gboolean path_currently_selected,
|
||||||
|
gpointer data)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
struct gds_cell *cell;
|
||||||
|
unsigned int error_level;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
(void)selection;
|
||||||
|
(void)path_currently_selected;
|
||||||
|
(void)data;
|
||||||
|
|
||||||
|
gtk_tree_model_get_iter(model, &iter, path);
|
||||||
|
gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
|
||||||
|
|
||||||
|
/* Allow only rows with _valid_ cell to be selected */
|
||||||
|
if (cell) {
|
||||||
|
/* Cell available. Check if it passed the critical checks */
|
||||||
|
if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
|
||||||
|
ret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Trigger refiltering of cell filter
|
||||||
|
* @param entry Unused widget, that emitted the signal
|
||||||
|
* @param data GdsrenderGui self instance
|
||||||
|
*/
|
||||||
|
static void cell_tree_view_change_filter(GtkWidget *entry, gpointer data)
|
||||||
|
{
|
||||||
|
GdsRenderGui *self = RENDERER_GUI(data);
|
||||||
|
(void)entry;
|
||||||
|
|
||||||
|
gtk_tree_model_filter_refilter(self->cell_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
|
||||||
|
* @param model Tree model
|
||||||
|
* @param iter Current element / iter in Model to check
|
||||||
|
* @param data Data. Set to static stores variable
|
||||||
|
* @return TRUE if visible, else FALSE
|
||||||
|
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
|
||||||
|
*/
|
||||||
|
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
GdsRenderGui *self;
|
||||||
|
struct gds_cell *cell;
|
||||||
|
struct gds_library *lib;
|
||||||
|
gboolean result = FALSE;
|
||||||
|
const char *search_string;
|
||||||
|
|
||||||
|
self = RENDERER_GUI(data);
|
||||||
|
g_return_val_if_fail(RENDERER_IS_GUI(self), FALSE);
|
||||||
|
|
||||||
|
if (!model || !iter)
|
||||||
|
goto exit_filter;
|
||||||
|
|
||||||
|
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
|
||||||
|
|
||||||
|
if (lib) {
|
||||||
|
result = TRUE;
|
||||||
|
goto exit_filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cell)
|
||||||
|
goto exit_filter;
|
||||||
|
|
||||||
|
search_string = gtk_entry_get_text(GTK_ENTRY(self->cell_search_entry));
|
||||||
|
|
||||||
|
/* Show all, if field is empty */
|
||||||
|
if (!strlen(search_string))
|
||||||
|
result = TRUE;
|
||||||
|
|
||||||
|
if (strstr(cell->name, search_string))
|
||||||
|
result = TRUE;
|
||||||
|
|
||||||
|
gtk_tree_view_expand_all(self->cell_tree_view);
|
||||||
|
|
||||||
|
exit_filter:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Setup a GtkTreeView with the necessary columns
|
||||||
|
* @param self Current GUI object
|
||||||
|
*/
|
||||||
|
int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
|
||||||
|
{
|
||||||
|
GtkCellRenderer *render_dates;
|
||||||
|
GtkCellRenderer *render_cell;
|
||||||
|
GtkCellRenderer *render_lib;
|
||||||
|
GtkTreeViewColumn *column;
|
||||||
|
|
||||||
|
self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER,
|
||||||
|
G_TYPE_POINTER, G_TYPE_UINT,
|
||||||
|
G_TYPE_STRING, G_TYPE_STRING);
|
||||||
|
|
||||||
|
/* Searching */
|
||||||
|
self->cell_filter = GTK_TREE_MODEL_FILTER(
|
||||||
|
gtk_tree_model_filter_new(GTK_TREE_MODEL(self->cell_tree_store), NULL));
|
||||||
|
|
||||||
|
gtk_tree_model_filter_set_visible_func(self->cell_filter,
|
||||||
|
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
|
||||||
|
self, NULL);
|
||||||
|
g_signal_connect(GTK_SEARCH_ENTRY(self->cell_search_entry), "search-changed",
|
||||||
|
G_CALLBACK(cell_tree_view_change_filter), self);
|
||||||
|
|
||||||
|
gtk_tree_view_set_model(self->cell_tree_view, GTK_TREE_MODEL(self->cell_filter));
|
||||||
|
|
||||||
|
render_dates = gtk_cell_renderer_text_new();
|
||||||
|
render_cell = lib_cell_renderer_new();
|
||||||
|
render_lib = lib_cell_renderer_new();
|
||||||
|
|
||||||
|
column = gtk_tree_view_column_new_with_attributes("Library", render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
|
||||||
|
gtk_tree_view_append_column(self->cell_tree_view, column);
|
||||||
|
|
||||||
|
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL,
|
||||||
|
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
|
||||||
|
gtk_tree_view_append_column(self->cell_tree_view, column);
|
||||||
|
|
||||||
|
column = gtk_tree_view_column_new_with_attributes("Mod. Date", render_dates, "text", CELL_SEL_MODDATE, NULL);
|
||||||
|
gtk_tree_view_append_column(self->cell_tree_view, column);
|
||||||
|
|
||||||
|
column = gtk_tree_view_column_new_with_attributes("Acc. Date", render_dates, "text", CELL_SEL_ACCESSDATE, NULL);
|
||||||
|
gtk_tree_view_append_column(self->cell_tree_view, column);
|
||||||
|
|
||||||
|
/* Callback for selection
|
||||||
|
* This prevents selecting a library
|
||||||
|
*/
|
||||||
|
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(self->cell_tree_view),
|
||||||
|
tree_sel_func, NULL, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback function of Load GDS button
|
* @brief Callback function of Load GDS button
|
||||||
* @param button
|
* @param button
|
||||||
@ -295,7 +454,9 @@ static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpoin
|
|||||||
g_object_unref(renderer);
|
g_object_unref(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer, const char *status_message, gpointer data)
|
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer,
|
||||||
|
const char *status_message,
|
||||||
|
gpointer data)
|
||||||
{
|
{
|
||||||
GdsRenderGui *gui;
|
GdsRenderGui *gui;
|
||||||
(void)renderer;
|
(void)renderer;
|
||||||
@ -536,6 +697,7 @@ static void gds_render_gui_dispose(GObject *gobject)
|
|||||||
g_clear_object(&self->convert_button);
|
g_clear_object(&self->convert_button);
|
||||||
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_filter);
|
||||||
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->activity_status_bar);
|
||||||
g_clear_object(&self->palette);
|
g_clear_object(&self->palette);
|
||||||
@ -624,7 +786,6 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
GtkBuilder *main_builder;
|
GtkBuilder *main_builder;
|
||||||
GtkWidget *listbox;
|
GtkWidget *listbox;
|
||||||
GtkHeaderBar *header_bar;
|
GtkHeaderBar *header_bar;
|
||||||
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 *activity_bar_box;
|
||||||
@ -636,9 +797,7 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
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"));
|
||||||
|
|
||||||
cell_selector_stores = setup_cell_selector(self->cell_tree_view, GTK_ENTRY(self->cell_search_entry));
|
gds_render_gui_setup_cell_selector(self);
|
||||||
|
|
||||||
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"));
|
self->open_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds"));
|
||||||
@ -716,10 +875,9 @@ static void gds_render_gui_init(GdsRenderGui *self)
|
|||||||
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); <= This is already referenced by the _new() function */
|
||||||
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->palette); */
|
||||||
g_object_ref(self->open_button);
|
g_object_ref(self->open_button);
|
||||||
g_object_ref(self->load_layer_button);
|
g_object_ref(self->load_layer_button);
|
||||||
g_object_ref(self->save_layer_button);
|
g_object_ref(self->save_layer_button);
|
||||||
|
@ -151,7 +151,7 @@ void bounding_box_calculate_path_box(GList *vertices, double thickness,
|
|||||||
GList *vertex_iterator;
|
GList *vertex_iterator;
|
||||||
struct vector_2d pt;
|
struct vector_2d pt;
|
||||||
|
|
||||||
printf("Warning! Function %s not yet implemented correctly!\n", __func__);
|
/* printf("Warning! Function %s not yet implemented correctly!\n", __func__); */
|
||||||
|
|
||||||
if (!vertices || !box)
|
if (!vertices || !box)
|
||||||
return;
|
return;
|
||||||
|
@ -1,57 +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 tree-store.h
|
|
||||||
* @brief Header file for Tree store implementation
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup GUI
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __TREE_STORE_H__
|
|
||||||
#define __TREE_STORE_H__
|
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
/** @brief Columns of selection tree view */
|
|
||||||
enum cell_store_columns {
|
|
||||||
CELL_SEL_LIBRARY = 0,
|
|
||||||
CELL_SEL_CELL,
|
|
||||||
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
|
|
||||||
CELL_SEL_MODDATE,
|
|
||||||
CELL_SEL_ACCESSDATE,
|
|
||||||
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tree_stores {
|
|
||||||
GtkTreeView *base_tree_view;
|
|
||||||
GtkTreeStore *base_store;
|
|
||||||
GtkTreeModelFilter *filter;
|
|
||||||
GtkEntry *search_entry;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry);
|
|
||||||
|
|
||||||
#endif /* __TREE_STORE_H__ */
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -1,60 +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 mapping-parser.h
|
|
||||||
* @brief Function to read a mapping file line and parse it.
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __MAPPING_PARSER_H__
|
|
||||||
#define __MAPPING_PARSER_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup Mapping-Parser
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <glib.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
|
|
||||||
* @param stream Input data stream
|
|
||||||
* @param export Layer shall be exported
|
|
||||||
* @param name Layer name. Free returned pointer after using.
|
|
||||||
* @param layer Layer number
|
|
||||||
* @param color RGBA color.
|
|
||||||
* @return 1 if malformatted line, 0 if parsing was successful and parameters are valid, -1 if file end
|
|
||||||
*/
|
|
||||||
int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Create Line for LayerMapping file with supplied information
|
|
||||||
* @param layer_element information
|
|
||||||
* @param line_buffer buffer to write to
|
|
||||||
* @param max_len Maximum length that cna be used in \p line_buffer
|
|
||||||
*/
|
|
||||||
void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* __MAPPING_PARSER_H__ */
|
|
@ -152,7 +152,7 @@ int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct
|
|||||||
* @param renderer GdsOutputrenderer object
|
* @param renderer GdsOutputrenderer object
|
||||||
* @param status Status to supply to signal emission
|
* @param status Status to supply to signal emission
|
||||||
*/
|
*/
|
||||||
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status);
|
void gds_output_renderer_update_async_progress(GdsOutputRenderer *renderer, const char *status);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -141,13 +141,16 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
|
|||||||
g_regex_match(regex, line, 0, &mi);
|
g_regex_match(regex, line, 0, &mi);
|
||||||
if (g_match_info_matches(mi) && color_idx < lines) {
|
if (g_match_info_matches(mi) && color_idx < lines) {
|
||||||
match = g_match_info_fetch_named(mi, "red");
|
match = g_match_info_fetch_named(mi, "red");
|
||||||
palette->color_array[color_idx].red = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
palette->color_array[color_idx].red =
|
||||||
|
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
||||||
g_free(match);
|
g_free(match);
|
||||||
match = g_match_info_fetch_named(mi, "green");
|
match = g_match_info_fetch_named(mi, "green");
|
||||||
palette->color_array[color_idx].green = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
palette->color_array[color_idx].green =
|
||||||
|
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
||||||
g_free(match);
|
g_free(match);
|
||||||
match = g_match_info_fetch_named(mi, "blue");
|
match = g_match_info_fetch_named(mi, "blue");
|
||||||
palette->color_array[color_idx].blue = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
palette->color_array[color_idx].blue =
|
||||||
|
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
|
||||||
g_free(match);
|
g_free(match);
|
||||||
|
|
||||||
/* Only RGB supported so far. Fix alpha channel to 1.0 */
|
/* Only RGB supported so far. Fix alpha channel to 1.0 */
|
||||||
@ -233,8 +236,7 @@ static void color_palette_dispose(GObject *gobj)
|
|||||||
ColorPalette *palette;
|
ColorPalette *palette;
|
||||||
|
|
||||||
palette = GDS_RENDER_COLOR_PALETTE(gobj);
|
palette = GDS_RENDER_COLOR_PALETTE(gobj);
|
||||||
if (palette->color_array)
|
if (palette->color_array) {
|
||||||
{
|
|
||||||
palette->color_array_length = 0;
|
palette->color_array_length = 0;
|
||||||
free(palette->color_array);
|
free(palette->color_array);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include <gds-render/layer/layer-selector.h>
|
#include <gds-render/layer/layer-selector.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>
|
|
||||||
|
|
||||||
struct _LayerSelector {
|
struct _LayerSelector {
|
||||||
/* Parent */
|
/* Parent */
|
||||||
@ -55,7 +54,8 @@ struct _LayerSelector {
|
|||||||
|
|
||||||
G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT)
|
G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT)
|
||||||
|
|
||||||
/* Drag and drop code
|
/*
|
||||||
|
* Drag and drop code
|
||||||
* Original code from https://blog.gtk.org/2017/06/01/drag-and-drop-in-lists-revisited/
|
* Original code from https://blog.gtk.org/2017/06/01/drag-and-drop-in-lists-revisited/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -120,10 +120,10 @@ static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
GtkListBoxRow *row;
|
GtkListBoxRow *row;
|
||||||
|
GtkListBoxRow *tmp;
|
||||||
|
|
||||||
row = NULL;
|
row = NULL;
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
GtkListBoxRow *tmp;
|
|
||||||
tmp = gtk_list_box_get_row_at_index(list, i);
|
tmp = gtk_list_box_get_row_at_index(list, i);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
break;
|
break;
|
||||||
@ -349,7 +349,8 @@ static void layer_selector_class_init(LayerSelectorClass *klass)
|
|||||||
|
|
||||||
static void layer_selector_setup_dnd(LayerSelector *self)
|
static void layer_selector_setup_dnd(LayerSelector *self)
|
||||||
{
|
{
|
||||||
gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &self->dnd_target, 1, GDK_ACTION_MOVE);
|
gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
|
||||||
|
&self->dnd_target, 1, GDK_ACTION_MOVE);
|
||||||
g_signal_connect(self->list_box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL);
|
g_signal_connect(self->list_box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL);
|
||||||
g_signal_connect(self->list_box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL);
|
g_signal_connect(self->list_box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL);
|
||||||
g_signal_connect(self->list_box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL);
|
g_signal_connect(self->list_box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL);
|
||||||
@ -425,9 +426,9 @@ static void layer_selector_clear_widgets(LayerSelector *self)
|
|||||||
GList *temp;
|
GList *temp;
|
||||||
|
|
||||||
list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
|
list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
|
||||||
for (temp = list; temp != NULL; temp = temp->next) {
|
for (temp = list; temp != NULL; temp = temp->next)
|
||||||
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(temp->data));
|
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(temp->data));
|
||||||
}
|
|
||||||
/* Widgets are already destroyed when removed from box because they are only referenced inside the container */
|
/* Widgets are already destroyed when removed from box because they are only referenced inside the container */
|
||||||
|
|
||||||
g_list_free(list);
|
g_list_free(list);
|
||||||
@ -445,7 +446,8 @@ static void layer_selector_clear_widgets(LayerSelector *self)
|
|||||||
* @param layer Layer number to check for
|
* @param layer Layer number to check for
|
||||||
* @return TRUE if layer is present, else FALSE
|
* @return TRUE if layer is present, else FALSE
|
||||||
*/
|
*/
|
||||||
static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer) {
|
static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer)
|
||||||
|
{
|
||||||
GList *list;
|
GList *list;
|
||||||
GList *temp;
|
GList *temp;
|
||||||
LayerElement *widget;
|
LayerElement *widget;
|
||||||
@ -553,9 +555,8 @@ void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
|
|||||||
|
|
||||||
for (; libs != NULL; libs = libs->next) {
|
for (; libs != NULL; libs = libs->next) {
|
||||||
lib = (struct gds_library *)libs->data;
|
lib = (struct gds_library *)libs->data;
|
||||||
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next) {
|
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next)
|
||||||
layer_selector_analyze_cell_layers(selector, (struct gds_cell *)cell_list->data);
|
layer_selector_analyze_cell_layers(selector, (struct gds_cell *)cell_list->data);
|
||||||
} /* For Cell List */
|
|
||||||
} /* For libs */
|
} /* For libs */
|
||||||
|
|
||||||
/* Sort the layers */
|
/* Sort the layers */
|
||||||
@ -577,6 +578,7 @@ void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
|
|||||||
static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, int layer)
|
static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, int layer)
|
||||||
{
|
{
|
||||||
LayerElement *ret = NULL;
|
LayerElement *ret = NULL;
|
||||||
|
|
||||||
for (; el_list != NULL; el_list = el_list->next) {
|
for (; el_list != NULL; el_list = el_list->next) {
|
||||||
if (layer_element_get_layer(LAYER_ELEMENT(el_list->data)) == layer) {
|
if (layer_element_get_layer(LAYER_ELEMENT(el_list->data)) == layer) {
|
||||||
ret = LAYER_ELEMENT(el_list->data);
|
ret = LAYER_ELEMENT(el_list->data);
|
||||||
@ -597,19 +599,18 @@ static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, i
|
|||||||
* @param self LayerSelector instance
|
* @param self LayerSelector instance
|
||||||
* @param file_name File name to load from
|
* @param file_name File name to load from
|
||||||
*/
|
*/
|
||||||
static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gchar *file_name)
|
static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, const gchar *file_name)
|
||||||
{
|
{
|
||||||
GFile *file;
|
GFile *file;
|
||||||
GFileInputStream *stream;
|
GFileInputStream *stream;
|
||||||
GDataInputStream *dstream;
|
GDataInputStream *dstream;
|
||||||
LayerElement *le;
|
LayerElement *le;
|
||||||
char *name;
|
|
||||||
gboolean export;
|
|
||||||
int layer;
|
|
||||||
GdkRGBA color;
|
|
||||||
int result;
|
|
||||||
GList *rows;
|
GList *rows;
|
||||||
GList *temp;
|
GList *temp;
|
||||||
|
GList *layer_infos;
|
||||||
|
int status;
|
||||||
|
LayerSettings *layer_settings;
|
||||||
|
struct layer_info *linfo;
|
||||||
|
|
||||||
file = g_file_new_for_path(file_name);
|
file = g_file_new_for_path(file_name);
|
||||||
stream = g_file_read(file, NULL, NULL);
|
stream = g_file_read(file, NULL, NULL);
|
||||||
@ -624,30 +625,39 @@ static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gch
|
|||||||
/* Reference and remove all rows from box */
|
/* Reference and remove all rows from box */
|
||||||
for (temp = rows; temp != NULL; temp = temp->next) {
|
for (temp = rows; temp != NULL; temp = temp->next) {
|
||||||
le = LAYER_ELEMENT(temp->data);
|
le = LAYER_ELEMENT(temp->data);
|
||||||
/* Referencing protets the widget from being deleted when removed */
|
/* Referencing protects the widget from being deleted when removed */
|
||||||
g_object_ref(G_OBJECT(le));
|
g_object_ref(G_OBJECT(le));
|
||||||
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
|
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
|
||||||
}
|
}
|
||||||
|
|
||||||
while((result = mapping_parser_load_line(dstream, &export, &name, &layer, &color)) >= 0) {
|
/* Load Layer settings. No need to check pointer, will be checked by load csv func. */
|
||||||
/* skip broken line */
|
layer_settings = layer_settings_new();
|
||||||
if (result == 1)
|
|
||||||
|
status = layer_settings_load_from_csv(layer_settings, file_name);
|
||||||
|
if (status)
|
||||||
|
goto abort_layer_settings;
|
||||||
|
|
||||||
|
layer_infos = layer_settings_get_layer_info_list(layer_settings);
|
||||||
|
if (!layer_infos)
|
||||||
|
goto abort_layer_settings;
|
||||||
|
|
||||||
|
/* Loop over all layer infos read from the CSV file */
|
||||||
|
for (; layer_infos; layer_infos = g_list_next(layer_infos)) {
|
||||||
|
linfo = (struct layer_info *)layer_infos->data;
|
||||||
|
le = layer_selector_find_layer_element_in_list(rows, linfo->layer);
|
||||||
|
if (!le)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Add rows in the same order as in file */
|
layer_element_set_name(le, linfo->name);
|
||||||
if ((le = layer_selector_find_layer_element_in_list(rows, layer))) {
|
layer_element_set_export(le, (linfo->render ? TRUE : FALSE));
|
||||||
gtk_list_box_insert(self->list_box, GTK_WIDGET(le), -1);
|
layer_element_set_color(le, &linfo->color);
|
||||||
|
gtk_container_add(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
|
||||||
layer_element_set_color(le, &color);
|
|
||||||
layer_element_set_export(le, export);
|
|
||||||
layer_element_set_name(le, name);
|
|
||||||
g_free(name);
|
|
||||||
|
|
||||||
/* Dereference and remove from list */
|
|
||||||
g_object_unref(G_OBJECT(le));
|
|
||||||
rows = g_list_remove(rows, le);
|
rows = g_list_remove(rows, le);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
abort_layer_settings:
|
||||||
|
/* Destroy layer settings. Not needed for adding remaining elements */
|
||||||
|
g_object_unref(layer_settings);
|
||||||
|
|
||||||
/* Add remaining elements */
|
/* Add remaining elements */
|
||||||
for (temp = rows; temp != NULL; temp = temp->next) {
|
for (temp = rows; temp != NULL; temp = temp->next) {
|
||||||
@ -682,7 +692,8 @@ static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user
|
|||||||
|
|
||||||
sel = LAYER_SELECTOR(user_data);
|
sel = LAYER_SELECTOR(user_data);
|
||||||
|
|
||||||
dialog = gtk_file_chooser_dialog_new("Load Mapping File", GTK_WINDOW(sel->load_parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
|
dialog = gtk_file_chooser_dialog_new("Load Mapping File", GTK_WINDOW(sel->load_parent_window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
"Cancel", GTK_RESPONSE_CANCEL, "Load Mapping", GTK_RESPONSE_ACCEPT, NULL);
|
"Cancel", GTK_RESPONSE_CANCEL, "Load Mapping", GTK_RESPONSE_ACCEPT, NULL);
|
||||||
res = gtk_dialog_run(GTK_DIALOG(dialog));
|
res = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
if (res == GTK_RESPONSE_ACCEPT) {
|
if (res == GTK_RESPONSE_ACCEPT) {
|
||||||
@ -702,29 +713,14 @@ static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user
|
|||||||
*/
|
*/
|
||||||
static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gchar *file_name)
|
static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gchar *file_name)
|
||||||
{
|
{
|
||||||
FILE *file;
|
LayerSettings *layer_settings;
|
||||||
char workbuff[512];
|
|
||||||
GList *le_list;
|
|
||||||
GList *temp;
|
|
||||||
|
|
||||||
/* Overwrite existing file */
|
g_return_if_fail(LAYER_IS_SELECTOR(self));
|
||||||
file = fopen((const char *)file_name, "w");
|
g_return_if_fail(file_name);
|
||||||
|
|
||||||
le_list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
|
/* Get layer settings. No need to check return value. to_csv func is safe */
|
||||||
|
layer_settings = layer_selector_export_rendered_layer_info(self);
|
||||||
/* File format is CSV: <Layer>,<target_pos>,<R>,<G>,<B>,<Alpha>,<Export?>,<Name> */
|
(void)layer_settings_to_csv(layer_settings, file_name);
|
||||||
for (temp = le_list; temp != NULL; temp = temp->next) {
|
|
||||||
/* To be sure it is a valid string */
|
|
||||||
workbuff[0] = 0;
|
|
||||||
mapping_parser_gen_csv_line(LAYER_ELEMENT(temp->data), workbuff, sizeof(workbuff));
|
|
||||||
fwrite(workbuff, sizeof(char), strlen(workbuff), file);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free(le_list);
|
|
||||||
|
|
||||||
/* Save File */
|
|
||||||
fflush(file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -742,7 +738,8 @@ static void layer_selector_save_mapping_clicked(GtkWidget *button, gpointer user
|
|||||||
|
|
||||||
sel = LAYER_SELECTOR(user_data);
|
sel = LAYER_SELECTOR(user_data);
|
||||||
|
|
||||||
dialog = gtk_file_chooser_dialog_new("Save Mapping File", GTK_WINDOW(sel->save_parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
|
dialog = gtk_file_chooser_dialog_new("Save Mapping File", GTK_WINDOW(sel->save_parent_window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||||
"Cancel", GTK_RESPONSE_CANCEL, "Save Mapping", GTK_RESPONSE_ACCEPT, NULL);
|
"Cancel", GTK_RESPONSE_CANCEL, "Save Mapping", GTK_RESPONSE_ACCEPT, NULL);
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||||
|
|
||||||
@ -809,10 +806,9 @@ void layer_selector_select_all_layers(LayerSelector *layer_selector, gboolean se
|
|||||||
|
|
||||||
for (iter = le_list; iter != NULL; iter = g_list_next(iter)) {
|
for (iter = le_list; iter != NULL; iter = g_list_next(iter)) {
|
||||||
le = LAYER_ELEMENT(iter->data);
|
le = LAYER_ELEMENT(iter->data);
|
||||||
if (LAYER_IS_ELEMENT(le)) {
|
if (LAYER_IS_ELEMENT(le))
|
||||||
layer_element_set_export(le, select);
|
layer_element_set_export(le, select);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
g_list_free(le_list);
|
g_list_free(le_list);
|
||||||
}
|
}
|
||||||
|
@ -223,7 +223,7 @@ int layer_settings_to_csv(LayerSettings *settings, const char *path)
|
|||||||
linfo = (struct layer_info *)info_iter->data;
|
linfo = (struct layer_info *)info_iter->data;
|
||||||
|
|
||||||
layer_settings_gen_csv_line(string, linfo);
|
layer_settings_gen_csv_line(string, linfo);
|
||||||
g_output_stream_write(w_fstream, string->str, sizeof(gchar), NULL, NULL);
|
g_output_stream_write(w_fstream, string->str, string->len * sizeof(gchar), NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete string */
|
/* Delete string */
|
||||||
@ -314,10 +314,14 @@ int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
|
|||||||
GInputStream *in_stream;
|
GInputStream *in_stream;
|
||||||
GDataInputStream *data_stream;
|
GDataInputStream *data_stream;
|
||||||
int parser_ret;
|
int parser_ret;
|
||||||
|
int stacked_pos;
|
||||||
struct layer_info linfo;
|
struct layer_info linfo;
|
||||||
|
|
||||||
file = g_file_new_for_path(path);
|
file = g_file_new_for_path(path);
|
||||||
in_stream = G_INPUT_STREAM(g_file_read(file, NULL, NULL));
|
in_stream = G_INPUT_STREAM(g_file_read(file, NULL, NULL));
|
||||||
|
|
||||||
|
g_return_val_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings), -2);
|
||||||
|
|
||||||
if (!in_stream) {
|
if (!in_stream) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
goto ret_destroy_file;
|
goto ret_destroy_file;
|
||||||
@ -327,11 +331,14 @@ int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
|
|||||||
|
|
||||||
data_stream = g_data_input_stream_new(in_stream);
|
data_stream = g_data_input_stream_new(in_stream);
|
||||||
|
|
||||||
|
stacked_pos = 0;
|
||||||
while ((parser_ret = layer_settings_load_csv_line_from_stream(data_stream, &linfo)) >= 0) {
|
while ((parser_ret = layer_settings_load_csv_line_from_stream(data_stream, &linfo)) >= 0) {
|
||||||
/* Line broken */
|
/* Line broken */
|
||||||
if (parser_ret == 1)
|
if (parser_ret == 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
linfo.stacked_position = stacked_pos++;
|
||||||
|
|
||||||
layer_settings_append_layer_info(settings, &linfo);
|
layer_settings_append_layer_info(settings, &linfo);
|
||||||
/* Clear name to prevent memory leak */
|
/* Clear name to prevent memory leak */
|
||||||
if (linfo.name)
|
if (linfo.name)
|
||||||
|
@ -1,144 +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 mapping-parser.c
|
|
||||||
* @brief Function to read a mapping file line and parse it.
|
|
||||||
* @author Mario Hüttel <mario.huettel@gmx.net>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @addtogroup Mapping-Parser
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gds-render/layer/mapping-parser.h>
|
|
||||||
|
|
||||||
int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
gsize len;
|
|
||||||
gchar *line;
|
|
||||||
GRegex *regex;
|
|
||||||
GMatchInfo *mi;
|
|
||||||
char *match;
|
|
||||||
|
|
||||||
if ((!export) || (!name) || (!layer) || (!color)) {
|
|
||||||
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");
|
|
||||||
*layer = (int)g_ascii_strtoll(match, NULL, 10);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "r");
|
|
||||||
color->red = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "g");
|
|
||||||
color->green = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "b");
|
|
||||||
color->blue = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "a");
|
|
||||||
color->alpha = g_ascii_strtod(match, NULL);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "export");
|
|
||||||
*export = ((!strcmp(match, "1")) ? TRUE : FALSE);
|
|
||||||
g_free(match);
|
|
||||||
match = g_match_info_fetch_named(mi, "name");
|
|
||||||
*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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
GString *string;
|
|
||||||
gboolean export;
|
|
||||||
const gchar *name;
|
|
||||||
int layer;
|
|
||||||
GdkRGBA color;
|
|
||||||
|
|
||||||
string = g_string_new_len(NULL, max_len-1);
|
|
||||||
|
|
||||||
/* Extract values */
|
|
||||||
export = layer_element_get_export(layer_element);
|
|
||||||
name = (const gchar*)layer_element_get_name(layer_element);
|
|
||||||
layer = layer_element_get_layer(layer_element);
|
|
||||||
layer_element_get_color(layer_element, &color);
|
|
||||||
|
|
||||||
/* print values to line */
|
|
||||||
g_string_printf(string, "%d:%lf:%lf:%lf:%lf:%d:%s\n",
|
|
||||||
layer, color.red, color.green,
|
|
||||||
color.blue, color.alpha, (export == TRUE ? 1 : 0), 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] = ',';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string->len > (max_len-1)) {
|
|
||||||
printf("Layer Definition too long. Please shorten Layer Name!!\n");
|
|
||||||
line_buffer[0] = 0x0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy max_len bytes of string */
|
|
||||||
strncpy(line_buffer, (char *)string->str, max_len-1);
|
|
||||||
line_buffer[max_len-1] = 0;
|
|
||||||
|
|
||||||
/* Completely remove string */
|
|
||||||
g_string_free(string, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
32
main.c
32
main.c
@ -126,14 +126,14 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
|
|||||||
*/
|
*/
|
||||||
static const GActionEntry app_actions[] = {
|
static const GActionEntry app_actions[] = {
|
||||||
{ "quit", app_quit, NULL, NULL, NULL, {0} },
|
{ "quit", app_quit, NULL, NULL, NULL, {0} },
|
||||||
{"about", app_about, NULL, NULL, NULL, {0}}
|
{ "about", app_about, NULL, NULL, NULL, {0} },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called when a GUI main window is closed
|
* @brief Called when a GUI main window is closed
|
||||||
*
|
*
|
||||||
* The GdsRenderGui object associated with the closed main window
|
* The GdsRenderGui object associated with the closed main window
|
||||||
* is removed from the list of open GUIs (\p user_data) and unreferenced.
|
* is removed from the list of open GUIs (\p user_data) and dereferenced.
|
||||||
*
|
*
|
||||||
* @param gui The GUI instance the closed main window belongs to
|
* @param gui The GUI instance the closed main window belongs to
|
||||||
* @param user_data List of GUIs
|
* @param user_data List of GUIs
|
||||||
@ -183,8 +183,8 @@ static void gapp_activate(GApplication *app, gpointer user_data)
|
|||||||
*/
|
*/
|
||||||
static int start_gui(int argc, char **argv)
|
static int start_gui(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
GtkApplication *gapp;
|
GtkApplication *gapp;
|
||||||
|
GString *application_domain;
|
||||||
int app_status;
|
int app_status;
|
||||||
static struct application_data appdata = {
|
static struct application_data appdata = {
|
||||||
.gui_list = NULL
|
.gui_list = NULL
|
||||||
@ -193,13 +193,22 @@ static int start_gui(int argc, char **argv)
|
|||||||
GMenu *m_quit;
|
GMenu *m_quit;
|
||||||
GMenu *m_about;
|
GMenu *m_about;
|
||||||
|
|
||||||
gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE);
|
/*
|
||||||
|
* Generate version dependent application id
|
||||||
|
* This allows running the application in different versions at the same time.
|
||||||
|
*/
|
||||||
|
application_domain = g_string_new(NULL);
|
||||||
|
g_string_printf(application_domain, "de.shimatta.gds_render_%s", _app_git_commit);
|
||||||
|
|
||||||
|
gapp = gtk_application_new(application_domain->str, G_APPLICATION_FLAGS_NONE);
|
||||||
|
g_string_free(application_domain, TRUE);
|
||||||
|
|
||||||
g_application_register(G_APPLICATION(gapp), NULL, NULL);
|
g_application_register(G_APPLICATION(gapp), NULL, NULL);
|
||||||
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
|
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
|
||||||
|
|
||||||
if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
|
if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
|
||||||
g_application_activate(G_APPLICATION(gapp));
|
g_application_activate(G_APPLICATION(gapp));
|
||||||
printf("There is already an open instance. Will open second window in said instance.\n");
|
printf("There is already an open instance. Will open second window in that instance.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,14 +267,17 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
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"},
|
{"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args,
|
||||||
|
"Renderer to use. Can be used multiple times.", "pdf|svg|tikz|ext"},
|
||||||
{"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" },
|
{"output-file", 'o', 0, G_OPTION_ARG_FILENAME_ARRAY, &output_paths,
|
||||||
|
"Output file path. Can be used multiple times.", "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"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -289,14 +301,12 @@ int main(int argc, char **argv)
|
|||||||
scale = 1;
|
scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get gds name */
|
/* Get gds name */
|
||||||
gds_name = argv[1];
|
gds_name = argv[1];
|
||||||
|
|
||||||
/* Print out additional arguments as ignored */
|
/* Print out additional arguments as ignored */
|
||||||
for (i = 2; i < argc; i++) {
|
for (i = 2; i < argc; i++)
|
||||||
printf("Ignored argument: %s", argv[i]);
|
printf("Ignored argument: %s", argv[i]);
|
||||||
}
|
|
||||||
|
|
||||||
app_status =
|
app_status =
|
||||||
command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
|
command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
|
||||||
|
@ -121,7 +121,8 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
/* Render child cells */
|
/* Render child cells */
|
||||||
for (instance_list = cell->child_cells; instance_list != NULL; instance_list = instance_list->next) {
|
for (instance_list = cell->child_cells; instance_list != NULL; instance_list = instance_list->next) {
|
||||||
cell_instance = (struct gds_cell_instance *)instance_list->data;
|
cell_instance = (struct gds_cell_instance *)instance_list->data;
|
||||||
if ((temp_cell = cell_instance->cell_ref) != NULL) {
|
temp_cell = cell_instance->cell_ref;
|
||||||
|
if (temp_cell != NULL) {
|
||||||
apply_inherited_transform_to_all_layers(layers,
|
apply_inherited_transform_to_all_layers(layers,
|
||||||
&cell_instance->origin,
|
&cell_instance->origin,
|
||||||
cell_instance->magnification,
|
cell_instance->magnification,
|
||||||
@ -177,6 +178,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
break;
|
break;
|
||||||
case GRAPHIC_BOX:
|
case GRAPHIC_BOX:
|
||||||
|
/* Expected fallthrough */
|
||||||
case GRAPHIC_POLYGON:
|
case GRAPHIC_POLYGON:
|
||||||
cairo_set_line_width(cr, 0.1/scale);
|
cairo_set_line_width(cr, 0.1/scale);
|
||||||
cairo_close_path(cr);
|
cairo_close_path(cr);
|
||||||
@ -187,8 +189,39 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
} /* for gfx list */
|
} /* for gfx list */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a line from a file descriptor
|
||||||
|
*
|
||||||
|
* In case of a broken pipe / closed writing end, it will terminate
|
||||||
|
*
|
||||||
|
* @param fd File descriptor to read from
|
||||||
|
* @param buff Buffer to write data in
|
||||||
|
* @param buff_size Buffer size
|
||||||
|
* @return length of read data
|
||||||
|
*/
|
||||||
|
static int read_line_from_fd(int fd, char *buff, size_t buff_size)
|
||||||
|
{
|
||||||
|
ssize_t cnt;
|
||||||
|
char c;
|
||||||
|
unsigned int buff_cnt = 0;
|
||||||
|
|
||||||
|
while ((cnt = read(fd, &c, 1)) == 1) {
|
||||||
|
if (buff_cnt < (buff_size-1)) {
|
||||||
|
buff[buff_cnt++] = c;
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buff[buff_cnt] = 0;
|
||||||
|
return (int)buff_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Render \p cell to a PDF file specified by \p pdf_file
|
* @brief Render \p cell to a PDF file specified by \p pdf_file
|
||||||
|
* @param renderer The current renderer this function is running from
|
||||||
* @param cell Toplevel cell to @ref Cairo-Renderer
|
* @param cell Toplevel cell to @ref Cairo-Renderer
|
||||||
* @param layer_infos List of layer information. Specifies color and layer stacking
|
* @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 pdf_file PDF output file. Set to NULL if no PDF file has to be generated
|
||||||
@ -196,8 +229,12 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
|
|||||||
* @param scale Scale the output image down by \p scale
|
* @param scale Scale the output image down by \p scale
|
||||||
* @return Error
|
* @return Error
|
||||||
*/
|
*/
|
||||||
static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, const char *pdf_file,
|
static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer,
|
||||||
const char *svg_file, double scale)
|
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 = NULL, *svg_surface = NULL;
|
||||||
cairo_t *pdf_cr = NULL, *svg_cr = NULL;
|
cairo_t *pdf_cr = NULL, *svg_cr = NULL;
|
||||||
@ -209,28 +246,40 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
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;
|
pid_t process_id;
|
||||||
|
int comm_pipe[2];
|
||||||
|
char receive_message[200];
|
||||||
|
|
||||||
if (pdf_file == NULL && svg_file == NULL) {
|
if (pdf_file == NULL && svg_file == NULL) {
|
||||||
/* No output specified */
|
/* No output specified */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate communication pipe for status updates */
|
||||||
|
if (pipe(comm_pipe) == -1)
|
||||||
|
return -2;
|
||||||
|
|
||||||
/* Fork to a new child process. This ensures the memory leaks (see issue #16) in Cairo don't
|
/* Fork to a new child process. This ensures the memory leaks (see issue #16) in Cairo don't
|
||||||
* brick everything.
|
* brick everything.
|
||||||
*
|
*
|
||||||
* And by the way: This now bricks all Windows compatibility. Deal with it.
|
* 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 = fork();
|
||||||
//process_id = -1;
|
//process_id = -1;
|
||||||
if (process_id < 0) {
|
if (process_id < 0) {
|
||||||
/* Well... shit... We have to run it in our process. */
|
/* This should not happen */
|
||||||
|
fprintf(stderr, "Fatal error: Cairo Renderer: Could not spawn child process!");
|
||||||
|
exit(-2);
|
||||||
} else if (process_id > 0) {
|
} else if (process_id > 0) {
|
||||||
/* Woohoo... Successfully dumped the shitty code to an unknowing victim */
|
/* Woohoo... Successfully dumped the shitty code to an unknowing victim */
|
||||||
goto ret_parent;
|
goto ret_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Close stdin and (stdout and stderr may live on) */
|
||||||
|
close(0);
|
||||||
|
//close(1);
|
||||||
|
close(comm_pipe[0]);
|
||||||
|
|
||||||
|
|
||||||
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
|
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
|
||||||
|
|
||||||
/* Clear layers */
|
/* Clear layers */
|
||||||
@ -260,7 +309,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dprintf(comm_pipe[1], "Rendering layers\n");
|
||||||
render_cell(cell, layers, scale);
|
render_cell(cell, layers, scale);
|
||||||
|
|
||||||
/* get size of image and top left coordinate */
|
/* get size of image and top left coordinate */
|
||||||
@ -278,7 +327,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
/* 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);
|
||||||
printf("Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n",
|
dprintf(comm_pipe[1], "Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n",
|
||||||
linfo->layer,
|
linfo->layer,
|
||||||
(linfo->name && linfo->name[0] ? " (" : ""),
|
(linfo->name && linfo->name[0] ? " (" : ""),
|
||||||
(linfo->name && linfo->name[0] ? linfo->name : ""),
|
(linfo->name && linfo->name[0] ? linfo->name : ""),
|
||||||
@ -297,7 +346,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Cell bounding box: (%lf | %lf) -- (%lf | %lf)\n", xmin, ymin, xmax, ymax);
|
/* printf("Cell bounding box: (%lf | %lf) -- (%lf | %lf)\n", xmin, ymin, xmax, ymax); */
|
||||||
|
|
||||||
if (pdf_file) {
|
if (pdf_file) {
|
||||||
pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
|
pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
|
||||||
@ -313,6 +362,8 @@ 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;
|
||||||
|
|
||||||
|
dprintf(comm_pipe[1], "Exporting layer %d to file\n", linfo->layer);
|
||||||
|
|
||||||
if (linfo->layer >= MAX_LAYERS) {
|
if (linfo->layer >= MAX_LAYERS) {
|
||||||
printf("Layer outside of Spec.\n");
|
printf("Layer outside of Spec.\n");
|
||||||
continue;
|
continue;
|
||||||
@ -356,14 +407,26 @@ ret_clear_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 */
|
/* Suspend child process */
|
||||||
if (process_id == 0)
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
/* Fork didn't work. Just return here */
|
|
||||||
return 0;
|
|
||||||
ret_parent:
|
ret_parent:
|
||||||
|
close(comm_pipe[1]);
|
||||||
|
|
||||||
|
while (read_line_from_fd(comm_pipe[0], receive_message, sizeof(receive_message)) > 0) {
|
||||||
|
/* Strip \n from string and replace with ' ' */
|
||||||
|
for (i = 0; receive_message[i] != '\0'; i++) {
|
||||||
|
if (receive_message[i] == '\n')
|
||||||
|
receive_message[i] = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update asyc progress*/
|
||||||
|
gds_output_renderer_update_async_progress(renderer, receive_message);
|
||||||
|
}
|
||||||
|
|
||||||
waitpid(process_id, NULL, 0);
|
waitpid(process_id, NULL, 0);
|
||||||
|
|
||||||
|
close(comm_pipe[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,8 +463,8 @@ static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
|
|||||||
else
|
else
|
||||||
pdf_file = output_file;
|
pdf_file = output_file;
|
||||||
|
|
||||||
gds_output_renderer_update_gui_status_from_async(renderer, "Rendering Cairo Output...");
|
gds_output_renderer_update_async_progress(renderer, "Rendering Cairo Output...");
|
||||||
ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale);
|
ret = cairo_renderer_render_cell_to_vector_file(renderer, cell, layer_infos, pdf_file, svg_file, scale);
|
||||||
|
|
||||||
if (settings)
|
if (settings)
|
||||||
g_object_unref(settings);
|
g_object_unref(settings);
|
||||||
|
@ -79,7 +79,8 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load symbol from library */
|
/* Load symbol from library */
|
||||||
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
|
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))
|
||||||
|
dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
|
||||||
error_msg = dlerror();
|
error_msg = dlerror();
|
||||||
if (error_msg != NULL) {
|
if (error_msg != NULL) {
|
||||||
fprintf(stderr, "Rendering function not found in library:\n%s\n", error_msg);
|
fprintf(stderr, "Rendering function not found in library:\n%s\n", error_msg);
|
||||||
|
@ -213,8 +213,6 @@ void gds_output_renderer_init(GdsOutputRenderer *self)
|
|||||||
priv->idle_function_parameters.status_message = NULL;
|
priv->idle_function_parameters.status_message = NULL;
|
||||||
g_mutex_init(&priv->settings_lock);
|
g_mutex_init(&priv->settings_lock);
|
||||||
g_mutex_init(&priv->idle_function_parameters.message_lock);
|
g_mutex_init(&priv->idle_function_parameters.message_lock);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GdsOutputRenderer *gds_output_renderer_new()
|
GdsOutputRenderer *gds_output_renderer_new()
|
||||||
@ -260,8 +258,6 @@ LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer
|
|||||||
|
|
||||||
/* This function seems to already reference the LayerSettings object */
|
/* This function seems to already reference the LayerSettings object */
|
||||||
g_object_get(renderer, "layer-settings", &ret, NULL);
|
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 */
|
/* It is now safe to clear the lock */
|
||||||
g_mutex_unlock(&priv->settings_lock);
|
g_mutex_unlock(&priv->settings_lock);
|
||||||
@ -415,7 +411,7 @@ static gboolean idle_event_processor_callback(gpointer user_data)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status)
|
void gds_output_renderer_update_async_progress(GdsOutputRenderer *renderer, const char *status)
|
||||||
{
|
{
|
||||||
GSource *idle_event_processor;
|
GSource *idle_event_processor;
|
||||||
GdsOutputRendererPrivate *priv;
|
GdsOutputRendererPrivate *priv;
|
||||||
|
@ -140,7 +140,8 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
|
|||||||
color->red = inf->color.red;
|
color->red = inf->color.red;
|
||||||
color->green = inf->color.green;
|
color->green = inf->color.green;
|
||||||
color->blue = inf->color.blue;
|
color->blue = inf->color.blue;
|
||||||
g_string_printf(buffer, "\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi\n",
|
g_string_printf(buffer,
|
||||||
|
"\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi\n",
|
||||||
layer, layer, inf->name);
|
layer, layer, inf->name);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -167,7 +168,7 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
|||||||
struct gds_graphics *gfx;
|
struct gds_graphics *gfx;
|
||||||
struct gds_point *pt;
|
struct gds_point *pt;
|
||||||
GdkRGBA color;
|
GdkRGBA color;
|
||||||
static const char *line_caps[] = {"butt", "round", "rect"};
|
static const char * const line_caps[] = {"butt", "round", "rect"};
|
||||||
|
|
||||||
for (temp = graphics; temp != NULL; temp = temp->next) {
|
for (temp = graphics; temp != NULL; temp = temp->next) {
|
||||||
gfx = (struct gds_graphics *)temp->data;
|
gfx = (struct gds_graphics *)temp->data;
|
||||||
@ -175,13 +176,18 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
|||||||
|
|
||||||
/* Layer is defined => create graphics */
|
/* Layer is defined => create graphics */
|
||||||
if (gfx->gfx_type == GRAPHIC_POLYGON || gfx->gfx_type == GRAPHIC_BOX) {
|
if (gfx->gfx_type == GRAPHIC_POLYGON || gfx->gfx_type == GRAPHIC_BOX) {
|
||||||
g_string_printf(buffer, "\\draw[line width=0.00001 pt, draw={c%d}, fill={c%d}, fill opacity={%lf}] ",
|
g_string_printf(buffer,
|
||||||
|
"\\draw[line width=0.00001 pt, draw={c%d}, fill={c%d}, fill opacity={%lf}] ",
|
||||||
gfx->layer, gfx->layer, color.alpha);
|
gfx->layer, gfx->layer, color.alpha);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
/* Append vertices */
|
/* Append vertices */
|
||||||
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
|
for (temp_vertex = gfx->vertices;
|
||||||
|
temp_vertex != NULL;
|
||||||
|
temp_vertex = temp_vertex->next) {
|
||||||
pt = (struct gds_point *)temp_vertex->data;
|
pt = (struct gds_point *)temp_vertex->data;
|
||||||
g_string_printf(buffer, "(%lf pt, %lf pt) -- ", ((double)pt->x)/scale, ((double)pt->y)/scale);
|
g_string_printf(buffer, "(%lf pt, %lf pt) -- ",
|
||||||
|
((double)pt->x)/scale,
|
||||||
|
((double)pt->y)/scale);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
}
|
}
|
||||||
g_string_printf(buffer, "cycle;\n");
|
g_string_printf(buffer, "cycle;\n");
|
||||||
@ -204,7 +210,9 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
|||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
/* Append vertices */
|
/* Append vertices */
|
||||||
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
|
for (temp_vertex = gfx->vertices;
|
||||||
|
temp_vertex != NULL;
|
||||||
|
temp_vertex = temp_vertex->next) {
|
||||||
pt = (struct gds_point *)temp_vertex->data;
|
pt = (struct gds_point *)temp_vertex->data;
|
||||||
g_string_printf(buffer, "(%lf pt, %lf pt)%s",
|
g_string_printf(buffer, "(%lf pt, %lf pt)%s",
|
||||||
((double)pt->x)/scale,
|
((double)pt->x)/scale,
|
||||||
@ -241,7 +249,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
|
|
||||||
status = g_string_new(NULL);
|
status = g_string_new(NULL);
|
||||||
g_string_printf(status, "Generating cell %s", cell->name);
|
g_string_printf(status, "Generating cell %s", cell->name);
|
||||||
gds_output_renderer_update_gui_status_from_async(renderer, status->str);
|
gds_output_renderer_update_async_progress(renderer, status->str);
|
||||||
g_string_free(status, TRUE);
|
g_string_free(status, TRUE);
|
||||||
|
|
||||||
/* Draw polygons of current cell */
|
/* Draw polygons of current cell */
|
||||||
@ -263,7 +271,8 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
|||||||
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
|
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
g_string_printf(buffer, "\\begin{scope}[yscale=%lf, xscale=%lf]\n", (inst->flipped ? -1*inst->magnification : inst->magnification),
|
g_string_printf(buffer, "\\begin{scope}[yscale=%lf, xscale=%lf]\n",
|
||||||
|
(inst->flipped ? -1*inst->magnification : inst->magnification),
|
||||||
inst->magnification);
|
inst->magnification);
|
||||||
WRITEOUT_BUFFER(buffer);
|
WRITEOUT_BUFFER(buffer);
|
||||||
|
|
||||||
@ -302,7 +311,8 @@ static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos,
|
|||||||
WRITEOUT_BUFFER(working_line);
|
WRITEOUT_BUFFER(working_line);
|
||||||
g_string_printf(working_line, "\\iftestmode\n");
|
g_string_printf(working_line, "\\iftestmode\n");
|
||||||
WRITEOUT_BUFFER(working_line);
|
WRITEOUT_BUFFER(working_line);
|
||||||
g_string_printf(working_line, "\\documentclass[tikz]{standalone}\n\\usepackage{xcolor}\n\\usetikzlibrary{ocgx}\n\\begin{document}\n");
|
g_string_printf(working_line,
|
||||||
|
"\\documentclass[tikz]{standalone}\n\\usepackage{xcolor}\n\\usetikzlibrary{ocgx}\n\\begin{document}\n");
|
||||||
WRITEOUT_BUFFER(working_line);
|
WRITEOUT_BUFFER(working_line);
|
||||||
g_string_printf(working_line, "\\fi\n");
|
g_string_printf(working_line, "\\fi\n");
|
||||||
WRITEOUT_BUFFER(working_line);
|
WRITEOUT_BUFFER(working_line);
|
||||||
@ -361,9 +371,8 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
|
|||||||
g_error("Could not open LaTeX output file");
|
g_error("Could not open LaTeX output file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings) {
|
if (settings)
|
||||||
g_object_unref(settings);
|
g_object_unref(settings);
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
<object class="GtkImage" id="save-mapping-img">
|
<object class="GtkImage" id="save-mapping-img">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="tooltip_text" translatable="yes">Save the current layer configuration to CSV</property>
|
||||||
<property name="stock">gtk-save-as</property>
|
<property name="stock">gtk-save-as</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="select-all-img">
|
<object class="GtkImage" id="select-all-img">
|
||||||
@ -46,7 +47,7 @@
|
|||||||
<property name="name">header</property>
|
<property name="name">header</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="title" translatable="yes">GDS Renderer</property>
|
<property name="title" translatable="yes">GDS-Render</property>
|
||||||
<property name="show_close_button">True</property>
|
<property name="show_close_button">True</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkButton" id="button-load-gds">
|
<object class="GtkButton" id="button-load-gds">
|
||||||
@ -54,6 +55,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Open GDS2 Database</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
<style>
|
<style>
|
||||||
@ -68,6 +70,7 @@
|
|||||||
<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="tooltip_text" translatable="yes">Load the current layer configuration from CSV</property>
|
||||||
<property name="image">load-mapping-img</property>
|
<property name="image">load-mapping-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
<style>
|
<style>
|
||||||
@ -103,6 +106,7 @@
|
|||||||
<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="tooltip_text" translatable="yes">Convert selected cell</property>
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
<style>
|
<style>
|
||||||
@ -188,6 +192,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Sort layers ascending</property>
|
||||||
<property name="image">sort-up-img</property>
|
<property name="image">sort-up-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
</object>
|
</object>
|
||||||
@ -202,6 +207,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Sort layers descending</property>
|
||||||
<property name="image">sort-down-img</property>
|
<property name="image">sort-down-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
</object>
|
</object>
|
||||||
@ -216,6 +222,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Automatically color layers</property>
|
||||||
<property name="image">color-img</property>
|
<property name="image">color-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
</object>
|
</object>
|
||||||
@ -230,6 +237,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Select all layers for export</property>
|
||||||
<property name="image">select-all-img</property>
|
<property name="image">select-all-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
</object>
|
</object>
|
||||||
@ -244,6 +252,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</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="tooltip_text" translatable="yes">Automatically name layers</property>
|
||||||
<property name="image">auto-name-img</property>
|
<property name="image">auto-name-img</property>
|
||||||
<property name="always_show_image">True</property>
|
<property name="always_show_image">True</property>
|
||||||
</object>
|
</object>
|
||||||
@ -264,6 +273,7 @@
|
|||||||
<object class="GtkScrolledWindow">
|
<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="margin_top">1</property>
|
||||||
<property name="hscrollbar_policy">never</property>
|
<property name="hscrollbar_policy">never</property>
|
||||||
<property name="shadow_type">in</property>
|
<property name="shadow_type">in</property>
|
||||||
<child>
|
<child>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
project(libversion)
|
||||||
add_library(version STATIC "version.c")
|
add_library(version STATIC "version.c")
|
||||||
execute_process(COMMAND bash ./generate-version-string.sh
|
execute_process(COMMAND bash ./generate-version-string.sh
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
@ -170,8 +170,11 @@ static gboolean shape_drawer_drawing_callback(GtkWidget *widget, cairo_t *cr, gp
|
|||||||
|
|
||||||
final_scale_value = (width_scale < height_scale ? width_scale : height_scale);
|
final_scale_value = (width_scale < height_scale ? width_scale : height_scale);
|
||||||
|
|
||||||
cairo_rectangle(cr, -(double)dialog->cell_width*final_scale_value/2.0, -(double)dialog->cell_height*final_scale_value/2.0,
|
cairo_rectangle(cr,
|
||||||
(double)dialog->cell_width*final_scale_value, (double)dialog->cell_height*final_scale_value);
|
-(double)dialog->cell_width * final_scale_value / 2.0,
|
||||||
|
-(double)dialog->cell_height * final_scale_value / 2.0,
|
||||||
|
(double)dialog->cell_width * final_scale_value,
|
||||||
|
(double)dialog->cell_height * final_scale_value);
|
||||||
cairo_stroke(cr);
|
cairo_stroke(cr);
|
||||||
cairo_restore(cr);
|
cairo_restore(cr);
|
||||||
|
|
||||||
@ -183,7 +186,7 @@ static double convert_number_to_engineering(double input, const char **out_prefi
|
|||||||
const char *selected_prefix = NULL;
|
const char *selected_prefix = NULL;
|
||||||
double return_val = 0.0;
|
double return_val = 0.0;
|
||||||
int idx;
|
int idx;
|
||||||
static const char * prefixes[] = {"y", "z", "a", "f", "p", "n", "u", "m", "c", "d", /* < 1 */
|
static const char * const prefixes[] = {"y", "z", "a", "f", "p", "n", "u", "m", "c", "d", /* < 1 */
|
||||||
"", /* 1 */
|
"", /* 1 */
|
||||||
"h", "k", "M", "G", "T", "P", "E", "Z", "Y"}; /* > 1 */
|
"h", "k", "M", "G", "T", "P", "E", "Z", "Y"}; /* > 1 */
|
||||||
static const double scale[] = {1E-24, 1E-21, 1E-18, 1E-15, 1E-12, 1E-9, 1E-6, 1E-3, 1E-2, 1E-1,
|
static const double scale[] = {1E-24, 1E-21, 1E-18, 1E-15, 1E-12, 1E-9, 1E-6, 1E-3, 1E-2, 1E-1,
|
||||||
@ -193,7 +196,7 @@ static double convert_number_to_engineering(double input, const char **out_prefi
|
|||||||
|
|
||||||
/* If pointer is invalid, return NaN */
|
/* If pointer is invalid, return NaN */
|
||||||
if (!out_prefix)
|
if (!out_prefix)
|
||||||
return 0.0 / 0.0;
|
return (0.0 / 0.0);
|
||||||
|
|
||||||
/* Start with the 2nd smallest prefix */
|
/* Start with the 2nd smallest prefix */
|
||||||
for (idx = 1; idx < prefix_count; idx++) {
|
for (idx = 1; idx < prefix_count; idx++) {
|
||||||
@ -308,9 +311,9 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
|
|||||||
RendererSettingsDialog *res;
|
RendererSettingsDialog *res;
|
||||||
|
|
||||||
res = RENDERER_SETTINGS_DIALOG(g_object_new(RENDERER_TYPE_SETTINGS_DIALOG, NULL));
|
res = RENDERER_SETTINGS_DIALOG(g_object_new(RENDERER_TYPE_SETTINGS_DIALOG, NULL));
|
||||||
if (res && parent) {
|
if (res && parent)
|
||||||
gtk_window_set_transient_for(GTK_WINDOW(res), parent);
|
gtk_window_set_transient_for(GTK_WINDOW(res), parent);
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,13 +325,12 @@ void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struc
|
|||||||
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
|
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
|
||||||
|
|
||||||
/* Get active radio button selection */
|
/* Get active radio button selection */
|
||||||
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE) {
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE)
|
||||||
settings->renderer = RENDERER_LATEX_TIKZ;
|
settings->renderer = RENDERER_LATEX_TIKZ;
|
||||||
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE) {
|
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE)
|
||||||
settings->renderer = RENDERER_CAIROGRAPHICS_PDF;
|
settings->renderer = RENDERER_CAIROGRAPHICS_PDF;
|
||||||
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE) {
|
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE)
|
||||||
settings->renderer = RENDERER_CAIROGRAPHICS_SVG;
|
settings->renderer = RENDERER_CAIROGRAPHICS_SVG;
|
||||||
}
|
|
||||||
|
|
||||||
settings->tex_pdf_layers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->layer_check));
|
settings->tex_pdf_layers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->layer_check));
|
||||||
settings->tex_standalone = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->standalone_check));
|
settings->tex_standalone = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->standalone_check));
|
||||||
|
@ -54,6 +54,7 @@ static void layer_element_constructed(GObject *obj)
|
|||||||
static void layer_element_class_init(LayerElementClass *klass)
|
static void layer_element_class_init(LayerElementClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *oclass = G_OBJECT_CLASS(klass);
|
GObjectClass *oclass = G_OBJECT_CLASS(klass);
|
||||||
|
|
||||||
oclass->dispose = layer_element_dispose;
|
oclass->dispose = layer_element_dispose;
|
||||||
oclass->constructed = layer_element_constructed;
|
oclass->constructed = layer_element_constructed;
|
||||||
}
|
}
|
||||||
@ -62,6 +63,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("/gui/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);
|
||||||
@ -140,7 +142,8 @@ void layer_element_set_dnd_callbacks(LayerElement *elem, struct layer_element_dn
|
|||||||
|
|
||||||
/* Setup drag and drop */
|
/* Setup drag and drop */
|
||||||
gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(elem)), "row");
|
gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(elem)), "row");
|
||||||
gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK, data->entries, data->entry_count, GDK_ACTION_MOVE);
|
gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK,
|
||||||
|
data->entries, data->entry_count, GDK_ACTION_MOVE);
|
||||||
g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(data->drag_begin), NULL);
|
g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(data->drag_begin), NULL);
|
||||||
g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(data->drag_data_get), NULL);
|
g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(data->drag_data_get), NULL);
|
||||||
g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(data->drag_end), NULL);
|
g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(data->drag_end), NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user