Merge branch 'dev' into Issue-28-new-gui-features
This commit is contained in:
commit
f9e16fa4d7
@ -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>
|
||||||
|
@ -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__ */
|
|
@ -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 */
|
||||||
@ -577,6 +576,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 +597,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,31 +623,40 @@ 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);
|
rows = g_list_remove(rows, le);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
le = LAYER_ELEMENT(temp->data);
|
le = LAYER_ELEMENT(temp->data);
|
||||||
@ -702,29 +710,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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user