From 084c6999c7f59e7b9f5e903e6b5be42247216ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 22 May 2018 18:45:23 +0200 Subject: [PATCH] Add option to specify layer order, wrote tex output for layer order --- glade/layer-widget.glade | 17 ++++++++- latex-output/latex-output.c | 68 ++++++++++++++++++++++++++++++++++++ latex-output/latex-output.h | 3 ++ layer-selector.c | 31 ++++++++++++---- layer-selector.h | 2 ++ layer-widget/layer-element.c | 22 +++++++++++- layer-widget/layer-element.h | 5 +++ main.c | 48 ++++++++++++++++++++++--- 8 files changed, 182 insertions(+), 14 deletions(-) diff --git a/glade/layer-widget.glade b/glade/layer-widget.glade index 3773863..bc68892 100644 --- a/glade/layer-widget.glade +++ b/glade/layer-widget.glade @@ -53,6 +53,21 @@ 2 + + + True + True + 5 + 5 + 4 + number + + + False + True + 3 + + True @@ -61,7 +76,7 @@ True True - 3 + 4 diff --git a/latex-output/latex-output.c b/latex-output/latex-output.c index 6768ff3..84fca4d 100644 --- a/latex-output/latex-output.c +++ b/latex-output/latex-output.c @@ -19,7 +19,75 @@ #include "latex-output.h" +#define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file) + +static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString *buffer) +{ + GList *list; + struct layer_info *lifo; + char *end_str; + + for (list = layer_infos; list != NULL; list = list->next) { + lifo = (struct layer_info *)list->data; + g_string_printf(buffer, "\\pgfdeclarelayer{l%d}\n", lifo->layer); + WRITEOUT_BUFFER(buffer); + } + + g_string_printf(buffer, "\\pgfsetlayers{"); + WRITEOUT_BUFFER(buffer); + + for (list = layer_infos; list != NULL; list = list->next) { + lifo = (struct layer_info *)list->data; + + if (list->next == NULL) + end_str = ",main}"; + else + end_str = ","; + g_string_printf(buffer, "l%d%s", lifo->layer, end_str); + WRITEOUT_BUFFER(buffer); + } + fwrite("\n", sizeof(char), 1, tex_file); +} + +static int sorting_func_stack(struct layer_info *info1, struct layer_info *info2) +{ + return info1->stacked_position - info2->stacked_position; +} + +static void sort_layers_for_rendering(GList **layer_infos) +{ + GList *list = *layer_infos; + list = g_list_sort(list, (GCompareFunc)sorting_func_stack); + *layer_infos = list; +} + void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file) { + GString *working_line; + if (!tex_file || !layer_infos || !cell) + return; + + /* 10 kB Line working buffer should be enough */ + working_line = g_string_new_len(NULL, LATEX_LINE_BUFFER_KB*1024); + + /* Sort layer according to target layer */ + sort_layers_for_rendering(&layer_infos); + + /* Write layer definitions */ + write_layer_definitions(tex_file, layer_infos, working_line); + + /* Open tikz Pictute */ + g_string_printf(working_line, "\\begin{tikzpicture}\n"); + WRITEOUT_BUFFER(working_line); + + /* Generate graphics output */ + + + + g_string_printf(working_line, "\\end{tikzpicture}\n"); + WRITEOUT_BUFFER(working_line); + + fflush(tex_file); + g_string_free(working_line, TRUE); } diff --git a/latex-output/latex-output.h b/latex-output/latex-output.h index ee21171..5d79ed9 100644 --- a/latex-output/latex-output.h +++ b/latex-output/latex-output.h @@ -23,6 +23,9 @@ #include "../gds-parser/gds-types.h" #include #include +#include "../layer-selector.h" + +#define LATEX_LINE_BUFFER_KB (10) void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file); diff --git a/layer-selector.c b/layer-selector.c index 9b57dfa..2b09451 100644 --- a/layer-selector.c +++ b/layer-selector.c @@ -34,6 +34,13 @@ static void delete_layer_widget(GtkWidget *widget) gtk_widget_destroy(widget); } + +void delete_layer_info_struct(struct layer_info *info) +{ + if (info) + free(info); +} + /** * @brief export_rendered_layer_info * @return new list with all info elements needed to render cells @@ -55,6 +62,7 @@ GList *export_rendered_layer_info() linfo = (struct layer_info *)malloc(sizeof(struct layer_info)); layer_element_get_color(le, &linfo->color); linfo->layer = layer_element_get_layer(le); + linfo->stacked_position = layer_element_get_stack(le); /* Append to list */ info_list = g_list_append(info_list, (gpointer)linfo); @@ -109,6 +117,7 @@ static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell) if (check_if_layer_widget_exists(layer) == FALSE) { le = layer_element_new(); layer_element_set_layer(LAYER_ELEMENT(le), layer); + layer_element_set_stack(LAYER_ELEMENT(le), layer); gtk_list_box_insert(listbox, le, -1); gtk_widget_show(le); layer_widgets = g_list_append(layer_widgets, le); @@ -140,8 +149,8 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs) { GList *cell_list = NULL; struct gds_library *lib; - clear_list_box_widgets(listbox); + clear_list_box_widgets(listbox); gtk_list_box_set_sort_func(listbox, sort_func, NULL, NULL); for (; libs != NULL; libs = libs->next) { @@ -169,7 +178,7 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs) * @param opacity * @return 0 if succesfull, 1 if line was malformatted or parameters are broken, -1 if file end */ -static int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color) +static int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, int *target_layer, GdkRGBA *color) { int ret; gsize len; @@ -183,7 +192,7 @@ static int load_csv_line(GDataInputStream *stream, gboolean *export, char **name goto ret_direct; } - regex = g_regex_new("^(?[0-9]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[01]),(?.*)$", 0, 0, NULL); + regex = g_regex_new("^(?[0-9]+),(?[0-9]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[0-9\\.]+),(?[01]),(?.*)$", 0, 0, NULL); line = g_data_input_stream_read_line(stream, &len, NULL, NULL); if (!line) { @@ -196,7 +205,10 @@ static int load_csv_line(GDataInputStream *stream, gboolean *export, char **name if (g_match_info_matches(mi)) { /* Line is valid */ match = g_match_info_fetch_named(mi, "layer"); - *layer = g_ascii_strtoll(match, NULL, 10); + *layer = (int)g_ascii_strtoll(match, NULL, 10); + g_free(match); + match = g_match_info_fetch_named(mi, "target"); + *target_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); @@ -258,6 +270,7 @@ static void load_layer_mapping_from_file(gchar *file_name) char *name; gboolean export; int layer; + int target_layer; GdkRGBA color; int result; @@ -269,7 +282,7 @@ static void load_layer_mapping_from_file(gchar *file_name) dstream = g_data_input_stream_new(G_INPUT_STREAM(stream)); - while((result = load_csv_line(dstream, &export, &name, &layer, &color)) >= 0) { + while((result = load_csv_line(dstream, &export, &name, &layer, &target_layer, &color)) >= 0) { /* skip broken line */ if (result == 1) continue; @@ -279,6 +292,7 @@ static void load_layer_mapping_from_file(gchar *file_name) layer_element_set_name(le, name); layer_element_set_color(le, &color); layer_element_set_export(le, export); + layer_element_set_stack(le, target_layer); } g_free(name); } @@ -313,6 +327,7 @@ static void create_csv_line(LayerElement *layer_element, char *line_buffer, size gboolean export; const gchar *name; int layer; + int target_layer; GdkRGBA color; string = g_string_new_len(NULL, max_len-1); @@ -321,10 +336,12 @@ static void create_csv_line(LayerElement *layer_element, char *line_buffer, size export = layer_element_get_export(layer_element); name = (const gchar*)layer_element_get_name(layer_element); layer = layer_element_get_layer(layer_element); + target_layer = layer_element_get_stack(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, + g_string_printf(string, "%d,%d,%lf,%lf,%lf,%lf,%d,%s\n", + layer, target_layer, color.red, color.green, color.blue, color.alpha, (export == TRUE ? 1 : 0), name); if (string->len > (max_len-1)) { @@ -350,7 +367,7 @@ static void save_layer_mapping_data(const gchar *file_name) /* Overwrite existing file */ file = fopen((const char *)file_name, "w"); - /* File format is CSV: ,,,,,, */ + /* File format is CSV: ,,,,,,, */ for (le_list = layer_widgets; le_list != NULL; le_list = le_list->next) { /* To be sure it is a valid string */ workbuff[0] = 0; diff --git a/layer-selector.h b/layer-selector.h index 78fd8c7..69a5a66 100644 --- a/layer-selector.h +++ b/layer-selector.h @@ -26,6 +26,7 @@ struct layer_info { int layer; + int stacked_position; ///< Lower is bottom, higher is top GdkRGBA color; }; @@ -33,5 +34,6 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs); void setup_load_mapping_callback(GtkWidget *button, GtkWindow *main_window); void setup_save_mapping_callback(GtkWidget *button, GtkWindow *main_window); GList *export_rendered_layer_info(); +void delete_layer_info_struct(struct layer_info *info); #endif /* __LAYER_SELECTOR_H__ */ diff --git a/layer-widget/layer-element.c b/layer-widget/layer-element.c index a36a1bf..72d16f8 100644 --- a/layer-widget/layer-element.c +++ b/layer-widget/layer-element.c @@ -52,6 +52,7 @@ static void layer_element_init(LayerElement *self) self->priv.export = GTK_CHECK_BUTTON(gtk_builder_get_object(builder, "export")); self->priv.layer = GTK_LABEL(gtk_builder_get_object(builder, "layer")); self->priv.name = GTK_ENTRY(gtk_builder_get_object(builder, "entry")); + self->priv.stack = GTK_ENTRY(gtk_builder_get_object(builder, "entry-stack")); /* Connect signals */ /* None */ @@ -79,7 +80,7 @@ void layer_element_set_layer(LayerElement *elem, int layer) GString *string; string = g_string_new_len(NULL, 100); - g_string_printf(string, "Layer: %3d", layer); + g_string_printf(string, "Layer: %d", layer); gtk_label_set_text(elem->priv.layer, (const gchar *)string->str); elem->priv.layer_num = layer; g_string_free(string, TRUE); @@ -90,6 +91,25 @@ int layer_element_get_layer(LayerElement *elem) return elem->priv.layer_num; } + +void layer_element_set_stack(LayerElement *elem, int layer) +{ + GString *string; + + string = g_string_new_len(NULL, 20); + g_string_printf(string, "%d", layer); + gtk_entry_set_text(elem->priv.stack, (const gchar *)string->str); + g_string_free(string, TRUE); +} + +int layer_element_get_stack(LayerElement *elem) +{ + const char *txt; + + txt = gtk_entry_get_text(elem->priv.stack); + return (int)g_ascii_strtoll(txt, NULL, 10); +} + void layer_element_set_export(LayerElement *elem, gboolean export) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(elem->priv.export), export); diff --git a/layer-widget/layer-element.h b/layer-widget/layer-element.h index de5a37c..42709b4 100644 --- a/layer-widget/layer-element.h +++ b/layer-widget/layer-element.h @@ -35,6 +35,7 @@ typedef struct _LayerElementPriv { int layer_num; GtkColorButton *color; GtkCheckButton *export; + GtkEntry *stack; } LayerElementPriv; typedef struct _LayerElement { @@ -50,6 +51,10 @@ const char *layer_element_get_name(LayerElement *elem); void layer_element_set_name(LayerElement *elem, const char* name); void layer_element_set_layer(LayerElement *elem, int layer); int layer_element_get_layer(LayerElement *elem); + +void layer_element_set_stack(LayerElement *elem, int layer); +int layer_element_get_stack(LayerElement *elem); + void layer_element_set_export(LayerElement *elem, gboolean export); gboolean layer_element_get_export(LayerElement *elem); void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba); diff --git a/main.c b/main.c index 48f33ff..4918cfa 100644 --- a/main.c +++ b/main.c @@ -33,8 +33,8 @@ struct open_button_data { }; struct convert_button_data { - GList *layer_info; GtkTreeView *tree_view; + GtkWindow *main_window; }; gboolean on_window_close(gpointer window, gpointer user) @@ -162,7 +162,43 @@ end_destroy: static void on_convert_clicked(gpointer button, gpointer user) { struct convert_button_data *data = (struct convert_button_data *)user; - printf("convert\n"); + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkTreeModel *model; + GList *layer_list; + struct gds_cell *cell_to_render; + FILE *tex_file; + GtkWidget *dialog; + gint res; + char *file_name; + + /* Get selected cell */ + selection = gtk_tree_view_get_selection(data->tree_view); + if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE) + return; + + gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell_to_render, -1); + + if (!cell_to_render) + return; + + /* Get layers that are rendered */ + layer_list = export_rendered_layer_info(); + + /* save file dialog */ + dialog = gtk_file_chooser_dialog_new("Save TeX File", GTK_WINDOW(data->main_window), GTK_FILE_CHOOSER_ACTION_SAVE, + "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL); + res = gtk_dialog_run(GTK_DIALOG(dialog)); + if (res == GTK_RESPONSE_ACCEPT) { + file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + tex_file = fopen(file_name, "w"); + g_free(file_name); + } + + gtk_widget_destroy(dialog); + render_cell_to_code(cell_to_render, layer_list, tex_file); + fclose(tex_file); + g_list_free_full(layer_list, (GDestroyNotify)delete_layer_info_struct); } /* This function activates/deactivates the convert button depending on whether @@ -187,11 +223,10 @@ int main(int argc, char **argv) GtkTreeView *cell_tree; GtkTreeStore *cell_store; GtkWidget *conv_button; - - GtkWidget *layer; GtkWidget *listbox; struct open_button_data open_data; + struct convert_button_data conv_data; gtk_init(&argc, &argv); @@ -212,8 +247,11 @@ int main(int argc, char **argv) /* Connect Convert button */ + conv_data.tree_view = cell_tree; + conv_data.main_window = open_data.main_window; + conv_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "convert-button")); - g_signal_connect(conv_button, "clicked", G_CALLBACK(on_convert_clicked), layer); + g_signal_connect(conv_button, "clicked", G_CALLBACK(on_convert_clicked), &conv_data); listbox = GTK_WIDGET(gtk_builder_get_object(main_builder, "layer-list")); open_data.layer_box = GTK_LIST_BOX(listbox);