diff --git a/gds-parser/gds-parser.c b/gds-parser/gds-parser.c index 8553b69..e6ef61b 100644 --- a/gds-parser/gds-parser.c +++ b/gds-parser/gds-parser.c @@ -48,11 +48,17 @@ #include #include +/** + * @brief Default units assumed for library. + * @note This value is usually overwritten with the value defined in the library. + */ +#define GDS_DEFAULT_UNITS (10E-9) + #define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/ #define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */ #if GDS_PRINT_DEBUG_INFOS - #define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But cna be disabled in code */ + #define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But can be disabled in code */ #else #define GDS_INF(fmt, ...) #endif @@ -221,7 +227,7 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr) if (lib) { lib->cells = NULL; lib->name[0] = 0; - lib->unit_to_meters = 1; // Default. Will be overwritten + lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten lib->cell_names = NULL; } else return NULL; @@ -297,6 +303,7 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr) cell->child_cells = NULL; cell->graphic_objs = NULL; cell->name[0] = 0; + cell->parent_library = NULL; } else return NULL; /* return cell */ @@ -383,7 +390,7 @@ static int name_cell(struct gds_cell *cell, unsigned int bytes, return -1; } data[bytes] = 0; // Append '0' - len = strlen(data); + len = (int)strlen(data); if (len > CELL_NAME_MAX-1) { GDS_ERROR("Cell name '%s' too long: %d\n", data, len); return -1; @@ -458,6 +465,7 @@ static void scan_cell_reference_dependencies(gpointer gcell, gpointer library) static void scan_library_references(gpointer library_list_item, gpointer user) { struct gds_library *lib = (struct gds_library *)library_list_item; + (void)user; GDS_INF("Scanning Library: %s\n", lib->name); g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib); @@ -607,12 +615,20 @@ int parse_gds_from_file(const char *filename, GList **library_list) GDS_INF("Leaving Library\n"); break; case BGNSTR: + if (current_lib == NULL) { + GDS_ERROR("Defining Cell outside of library!\n"); + run = -4; + break; + } current_lib->cells = append_cell(current_lib->cells, ¤t_cell); if (current_lib->cells == NULL) { GDS_ERROR("Allocating memory failed"); run = -3; break; } + + current_cell->parent_library = current_lib; + GDS_INF("Entering Cell\n"); break; case ENDSTR: @@ -710,6 +726,8 @@ int parse_gds_from_file(const char *filename, GList **library_list) break; case PATHTYPE: break; + case UNITS: + break; default: //GDS_WARN("Record: %04x, len: %u", (unsigned int)rec_type, (unsigned int)rec_data_length); break; @@ -717,7 +735,7 @@ int parse_gds_from_file(const char *filename, GList **library_list) /* No Data -> No Processing, go back to top */ - if (!rec_data_length) continue; + if (!rec_data_length || run != 1) continue; read = fread(workbuff, sizeof(char), rec_data_length, gds_file); @@ -731,7 +749,6 @@ int parse_gds_from_file(const char *filename, GList **library_list) switch (rec_type) { case HEADER: - case UNITS: case ENDLIB: case ENDSTR: case BOUNDARY: @@ -742,6 +759,20 @@ int parse_gds_from_file(const char *filename, GList **library_list) case INVALID: break; + case UNITS: + if (!current_lib) { + GDS_WARN("Units defined outside of library!\n"); + break; + } + + if (rec_data_length != 16) { + GDS_WARN("Unit define incomplete. Will assume database unit of %E meters\n", current_lib->unit_in_meters); + break; + } + + current_lib->unit_in_meters = gds_convert_double(&workbuff[8]); + GDS_INF("Length of database unit: %E meters\n", current_lib->unit_in_meters); + break; case BGNLIB: /* Parse date record */ gds_parse_date(workbuff, read, ¤t_lib->mod_time, ¤t_lib->access_time); @@ -848,15 +879,11 @@ int parse_gds_from_file(const char *filename, GList **library_list) fclose(gds_file); - if (!run) { /* Iterate and find references to cells */ g_list_foreach(lib_list, scan_library_references, NULL); } - - - *library_list = lib_list; free(workbuff); diff --git a/gds-parser/gds-types.h b/gds-parser/gds-types.h index 88cad12..80e2acc 100644 --- a/gds-parser/gds-types.h +++ b/gds-parser/gds-types.h @@ -104,6 +104,7 @@ struct gds_cell { struct gds_time_field access_time; GList *child_cells; /**< @brief List of #gds_cell_instance elements */ GList *graphic_objs; /**< @brief List of #gds_graphics */ + struct gds_library *parent_library; /**< @brief Pointer to parent library */ }; /** @@ -113,7 +114,7 @@ struct gds_library { char name[CELL_NAME_MAX]; struct gds_time_field mod_time; struct gds_time_field access_time; - double unit_to_meters; /**< @warning not yet implemented */ + double unit_in_meters; /**< Length of a database unit in meters */ GList *cells; /**< List of #gds_cell that contains all cells in this library*/ GList *cell_names /**< List of strings that contains all cell names */; }; diff --git a/glade/dialog.glade b/glade/dialog.glade index 90b1ea5..792d1ca 100644 --- a/glade/dialog.glade +++ b/glade/dialog.glade @@ -4,7 +4,7 @@ 1 - 3000 + 4000 1000 10 1000 @@ -51,7 +51,6 @@ Render SVG using Cairographics (too buggy at the moment) True True - False True False True @@ -69,6 +68,7 @@ True True adjustment1 + 4000 0 0 @@ -106,5 +106,83 @@ 5 + + + 200 + True + False + + + True + True + 6 + + + + + True + False + + + True + False + + + True + True + 0 + + + + + True + False + + + True + True + 1 + + + + + False + True + 7 + + + + + True + False + + + True + False + + + True + True + 0 + + + + + True + False + + + True + True + 1 + + + + + False + True + 8 + + diff --git a/main-window.c b/main-window.c index 89f1aca..600bf0a 100644 --- a/main-window.c +++ b/main-window.c @@ -36,6 +36,7 @@ #include "latex-output/latex-output.h" #include "widgets/conv-settings-dialog.h" #include "cairo-output/cairo-output.h" +#include "trigonometric/cell-trigonometrics.h" /** * @brief User data supplied to callback function of the open button @@ -214,8 +215,8 @@ end_destroy: static void on_convert_clicked(gpointer button, gpointer user) { static struct render_settings sett = { - .scale = 1000.0f, - .renderer = RENDERER_LATEX_TIKZ, + .scale = 1000.0, + .renderer = RENDERER_LATEX_TIKZ, }; struct convert_button_data *data = (struct convert_button_data *)user; GtkTreeSelection *selection; @@ -229,6 +230,8 @@ static void on_convert_clicked(gpointer button, gpointer user) GtkFileFilter *filter; gint res; char *file_name; + union bounding_box cell_box; + double height, width; /* Get selected cell */ selection = gtk_tree_view_get_selection(data->tree_view); @@ -243,8 +246,21 @@ static void on_convert_clicked(gpointer button, gpointer user) /* Get layers that are rendered */ layer_list = export_rendered_layer_info(); + /* Calculate cell size in DB units */ + bounding_box_prepare_empty(&cell_box); + calculate_cell_bounding_box(&cell_box, cell_to_render); + + /* Calculate size in meters database units */ + height = (cell_box.vectors.upper_right.y - cell_box.vectors.lower_left.y); + width = (cell_box.vectors.upper_right.x - cell_box.vectors.lower_left.x); + + /* Show settings dialog */ settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window)); renderer_settings_dialog_set_settings(settings, &sett); + renderer_settings_dialog_set_database_unit_scale(settings, cell_to_render->parent_library->unit_in_meters); + renderer_settings_dialog_set_cell_height(settings, height); + renderer_settings_dialog_set_cell_width(settings, width); + res = gtk_dialog_run(GTK_DIALOG(settings)); if (res == GTK_RESPONSE_OK) { renderer_settings_dialog_get_settings(settings, &sett); @@ -254,8 +270,6 @@ static void on_convert_clicked(gpointer button, gpointer user) goto ret_layer_destroy; } - - /* save file dialog */ dialog = gtk_file_chooser_dialog_new((sett.renderer == RENDERER_LATEX_TIKZ ? "Save LaTeX File" : "Save PDF"), diff --git a/main.c b/main.c index 1cee472..1eea1f7 100644 --- a/main.c +++ b/main.c @@ -56,8 +56,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_ } const static GActionEntry app_actions[] = { - { "quit", app_quit }, - { "about", app_about } + {"quit", app_quit}, + {"about", app_about} }; static void gapp_activate(GApplication *app, gpointer user_data) @@ -100,7 +100,6 @@ static int start_gui(int argc, char **argv) g_object_unref(m_about); g_object_unref(menu); - app_status = g_application_run(G_APPLICATION(gapp), argc, argv); g_object_unref(gapp); @@ -189,6 +188,5 @@ int main(int argc, char **argv) app_status = start_gui(argc, argv); } - return app_status; } diff --git a/trigonometric/bounding-box.c b/trigonometric/bounding-box.c index 8f4f8e6..9d3b26d 100644 --- a/trigonometric/bounding-box.c +++ b/trigonometric/bounding-box.c @@ -133,14 +133,70 @@ static void calculate_path_miter_points(struct vector_2d *a, struct vector_2d *b vector_2d_subtract(m2, m2, &v_vec); } -void bounding_box_calculate_path_box(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box) +void bounding_box_calculate_path_box(GList *vertices, double thickness, + conv_generic_to_vector_2d_t conv_func, union bounding_box *box) { + GList *vertex_iterator; + struct vector_2d pt; + printf("Warning! Function bounding_box_calculate_path_box not yet implemented correctly!\n"); + + if (!vertices || !box) + return; + + for (vertex_iterator = vertices; vertex_iterator != NULL; vertex_iterator = g_list_next(vertex_iterator)) { + + if (conv_func != NULL) + conv_func(vertex_iterator->data, &pt); + else + (void)vector_2d_copy(&pt, (struct vector_2d *)vertex_iterator->data); + + /* These are approximations. + * Used as long as miter point calculation is not fully implemented + */ + box->vectors.lower_left.x = MIN(box->vectors.lower_left.x, pt.x - thickness/2); + box->vectors.lower_left.y = MIN(box->vectors.lower_left.y, pt.y - thickness/2); + box->vectors.upper_right.x = MAX(box->vectors.upper_right.x, pt.x + thickness/2); + box->vectors.upper_right.y = MAX(box->vectors.upper_right.y, pt.y + thickness/2); + } } void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt) { + struct vector_2d point; + if (!destination || !pt) + return; + + if (conv_func) + conv_func(pt, &point); + else + (void)vector_2d_copy(&point, (struct vector_2d *)pt); + + destination->vectors.lower_left.x = MIN(destination->vectors.lower_left.x, point.x); + destination->vectors.lower_left.y = MIN(destination->vectors.lower_left.y, point.y); + destination->vectors.upper_right.x = MAX(destination->vectors.upper_right.x, point.x); + destination->vectors.upper_right.y = MAX(destination->vectors.upper_right.y, point.y); +} + +/** + * @brief bounding_box_apply_transform + * @param scale scaling factor + * @param rotation roation of bounding box around the origin in degrees (counterclockwise) + * @param box bounding box the operations should be applied to + */ +void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box) +{ + int i; + + /* Due to linearity, the order of the operations does not matter. + * flip must be applied before rotation as defined by the GDS format + */ + for (i = 0; i < 2; i++) { + box->vector_array[i].y *= (flip_at_x ? -1 : 1); + vector_2d_rotate(&box->vector_array[i], rotation_deg * M_PI / 180); + vector_2d_scale(&box->vector_array[i], scale); + } } /** @} */ diff --git a/trigonometric/bounding-box.h b/trigonometric/bounding-box.h index aa9e1a1..12f883d 100644 --- a/trigonometric/bounding-box.h +++ b/trigonometric/bounding-box.h @@ -32,6 +32,7 @@ #define _BOUNDING_BOX_H_ #include #include "vector-operations.h" +#include union bounding_box { /** Coordinate System is (y up | x right) */ @@ -48,6 +49,8 @@ void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t void bounding_box_update_box(union bounding_box *destination, union bounding_box *update); void bounding_box_prepare_empty(union bounding_box *box); void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt); +void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box); +void bounding_box_calculate_path_box(GList *vertices, double thickness, conv_generic_to_vector_2d_t conv_func, union bounding_box *box); #endif /* _BOUNDING_BOX_H_ */ diff --git a/trigonometric/cell-trigonometrics.c b/trigonometric/cell-trigonometrics.c new file mode 100644 index 0000000..823a531 --- /dev/null +++ b/trigonometric/cell-trigonometrics.c @@ -0,0 +1,117 @@ +/* + * GDSII-Converter + * Copyright (C) 2018 Mario Hüttel + * + * 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 . + */ + +/** + * @file cell-trigonometrics.c + * @brief Calculation of gds_cell trigonometrics + * @author Mario Hüttel + */ + +#include "cell-trigonometrics.h" +#include + +/** + * @addtogroup trigonometric + * @{ + */ + +static void convert_gds_point_to_2d_vector(struct gds_point *pt, struct vector_2d *vector) +{ + vector->x = pt->x; + vector->y = pt->y; +} + +/** + * @brief update_box_with_gfx + * @param box + * @param gfx_list + */ +static void update_box_with_gfx(union bounding_box *box, struct gds_graphics *gfx) +{ + union bounding_box current_box; + + bounding_box_prepare_empty(¤t_box); + + switch (gfx->gfx_type) { + case GRAPHIC_BOX: + /* Expected fallthrough */ + case GRAPHIC_POLYGON: + bounding_box_calculate_polygon(gfx->vertices, + (conv_generic_to_vector_2d_t)&convert_gds_point_to_2d_vector, + ¤t_box); + break; + case GRAPHIC_PATH: + /* + * This is not implemented correctly. + * Please be aware if paths are the outmost elements of your cell. + * You might end up with a completely wrong calculated cell size. + */ + bounding_box_calculate_path_box(gfx->vertices, gfx->width_absolute, + (conv_generic_to_vector_2d_t)&convert_gds_point_to_2d_vector, + ¤t_box); + break; + default: + /* Unknown graphics object. */ + /* Print error? Nah.. */ + break; + } + + /* Update box with results */ + bounding_box_update_box(box, ¤t_box); +} + +void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell) +{ + GList *gfx_list; + struct gds_graphics *gfx; + GList *sub_cell_list; + struct gds_cell_instance *sub_cell; + union bounding_box temp_box; + + if (!box || !cell) + return; + + /* Update box with graphic elements */ + for (gfx_list = cell->graphic_objs; gfx_list != NULL; gfx_list = gfx_list->next) { + gfx = (struct gds_graphics *)gfx_list->data; + update_box_with_gfx(box, gfx); + } + + /* Update bounding box with boxes of subcells */ + for (sub_cell_list = cell->child_cells; sub_cell_list != NULL; sub_cell_list = sub_cell_list->next) { + sub_cell = (struct gds_cell_instance *)sub_cell_list->data; + bounding_box_prepare_empty(&temp_box); + /* Recursion Woohoo!! This dies if your GDS is faulty and contains a reference loop */ + calculate_cell_bounding_box(&temp_box, sub_cell->cell_ref); + + /* Apply transformations */ + bounding_box_apply_transform(ABS(sub_cell->magnification), sub_cell->angle, sub_cell->flipped, &temp_box); + + /* Move bounding box to origin */ + temp_box.vectors.lower_left.x += sub_cell->origin.x; + temp_box.vectors.upper_right.x += sub_cell->origin.x; + temp_box.vectors.lower_left.y += sub_cell->origin.y; + temp_box.vectors.upper_right.y += sub_cell->origin.y; + + /* update the parent's box */ + bounding_box_update_box(box, &temp_box); + } +} + +/** @} */ diff --git a/trigonometric/cell-trigonometrics.h b/trigonometric/cell-trigonometrics.h new file mode 100644 index 0000000..2a4ba5d --- /dev/null +++ b/trigonometric/cell-trigonometrics.h @@ -0,0 +1,47 @@ +/* + * GDSII-Converter + * Copyright (C) 2018 Mario Hüttel + * + * 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 . + */ + +/** + * @file cell-trigonometrics.h + * @brief Calculation of gds_cell trigonometrics + * @author Mario Hüttel + */ + +/** + * @addtogroup trigonometric + * @{ + */ + +#ifndef _CELL_TRIGONOMETRICS_H_ +#define _CELL_TRIGONOMETRICS_H_ + +#include "bounding-box.h" +#include "../gds-parser/gds-types.h" + +/** + * @brief calculate_cell_bounding_box Calculate bounding box of gds cell + * @param box Resulting boundig box. Will be uüdated and not overwritten + * @param cell toplevel cell + * @warning Path handling not yet implemented correctly + */ +void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell); + +#endif /* _CELL_TRIGONOMETRICS_H_ */ + +/** @} */ diff --git a/trigonometric/vector-operations.c b/trigonometric/vector-operations.c index 4cdbca4..0666056 100644 --- a/trigonometric/vector-operations.c +++ b/trigonometric/vector-operations.c @@ -76,18 +76,17 @@ struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *ve if (!vec) return NULL; - if (opt_res) { - opt_res->x = vec->x; - opt_res->y = vec->y; - return opt_res; - } else { + + if (opt_res) + res = opt_res; + else res = vector_2d_alloc(); - if (res) { - res->x = vec->x; - res->y = vec->y; - } - return res; + + if (res) { + res->x = vec->x; + res->y = vec->y; } + return res; } struct vector_2d *vector_2d_alloc(void) diff --git a/widgets/conv-settings-dialog.c b/widgets/conv-settings-dialog.c index e4280e1..7460dfb 100644 --- a/widgets/conv-settings-dialog.c +++ b/widgets/conv-settings-dialog.c @@ -39,12 +39,20 @@ struct _RendererSettingsDialog { GtkWidget *scale; GtkWidget *layer_check; GtkWidget *standalone_check; + GtkDrawingArea *shape_drawing; + GtkLabel *x_label; + GtkLabel *y_label; + + GtkLabel *x_output_label; + GtkLabel *y_output_label; + + unsigned int cell_height; + unsigned int cell_width; + double unit_in_meters; }; G_DEFINE_TYPE(RendererSettingsDialog, renderer_settings_dialog, GTK_TYPE_DIALOG) - - static void renderer_settings_dialog_class_init(RendererSettingsDialogClass *klass) { /* No special code needed. Child cells are destroyed automatically due to reference counter */ @@ -72,13 +80,89 @@ static void latex_render_callback(GtkToggleButton *radio, RendererSettingsDialog hide_tex_options(dialog); } +static gboolean shape_drawer_drawing_callback(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + int width; + int height; + GtkStyleContext *style_context; + GdkRGBA foreground_color; + RendererSettingsDialog *dialog = (RendererSettingsDialog *)data; + double usable_width; + double usable_height; + double height_scale; + double width_scale; + double final_scale_value; + + style_context = gtk_widget_get_style_context(widget); + width = gtk_widget_get_allocated_width(widget); + height = gtk_widget_get_allocated_height(widget); + + gtk_render_background(style_context, cr, 0, 0, width, height); + + gtk_style_context_get_color(style_context, gtk_style_context_get_state(style_context), + &foreground_color); + + gdk_cairo_set_source_rgba(cr, &foreground_color); + + cairo_save(cr); + + /* Tranform coordiante system */ + cairo_scale(cr, 1, -1); + cairo_translate(cr, (double)width/2.0, -(double)height/2.0); + + /* Define usable drawing area */ + usable_width = (0.95*(double)width) - 15.0; + usable_height = (0.95*(double)height) - 15.0; + + width_scale = usable_width/(double)dialog->cell_width; + height_scale = usable_height/(double)dialog->cell_height; + + 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, + (double)dialog->cell_width*final_scale_value, (double)dialog->cell_height*final_scale_value); + cairo_stroke(cr); + cairo_restore(cr); + + return FALSE; +} + +static void renderer_settings_dialog_update_labels(RendererSettingsDialog *self) +{ + char default_buff[100]; + double scale; + + if (!self) + return; + + snprintf(default_buff, sizeof(default_buff), "Width: %E", self->cell_width * self->unit_in_meters); + gtk_label_set_text(self->x_label, default_buff); + snprintf(default_buff, sizeof(default_buff), "Height: %E", self->cell_height * self->unit_in_meters); + gtk_label_set_text(self->y_label, default_buff); + + scale = gtk_range_get_value(GTK_RANGE(self->scale)); + + snprintf(default_buff, sizeof(default_buff), "Output Width: %u px", (unsigned int)((double)self->cell_width / scale)); + gtk_label_set_text(self->x_output_label, default_buff); + snprintf(default_buff, sizeof(default_buff), "Output Height: %u px", (unsigned int)((double)self->cell_height / scale)); + gtk_label_set_text(self->y_output_label, default_buff); +} + +static void scale_value_changed(GtkRange *range, gpointer user_data) +{ + (void)range; + RendererSettingsDialog *dialog; + + dialog = RENDERER_SETTINGS_DIALOG(user_data); + renderer_settings_dialog_update_labels(dialog); +} + static void renderer_settings_dialog_init(RendererSettingsDialog *self) { GtkBuilder *builder; GtkWidget *box; GtkDialog *dialog; - dialog = &(self->parent); builder = gtk_builder_new_from_resource("/dialog.glade"); @@ -89,12 +173,27 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self) self->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale")); self->standalone_check = GTK_WIDGET(gtk_builder_get_object(builder, "standalone-check")); self->layer_check = GTK_WIDGET(gtk_builder_get_object(builder, "layer-check")); + self->shape_drawing = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "shape-drawer")); + self->x_label = GTK_LABEL(gtk_builder_get_object(builder, "x-label")); + self->y_label = GTK_LABEL(gtk_builder_get_object(builder, "y-label")); + self->x_output_label = GTK_LABEL(gtk_builder_get_object(builder, "x-output-label")); + self->y_output_label = GTK_LABEL(gtk_builder_get_object(builder, "y-output-label")); gtk_dialog_add_buttons(dialog, "Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dialog)), box); gtk_window_set_title(GTK_WINDOW(self), "Renderer Settings"); g_signal_connect(self->radio_latex, "toggled", G_CALLBACK(latex_render_callback), (gpointer)self); + g_signal_connect(G_OBJECT(self->shape_drawing), + "draw", G_CALLBACK(shape_drawer_drawing_callback), (gpointer)self); + + g_signal_connect(self->scale, "value-changed", G_CALLBACK(scale_value_changed), (gpointer)self); + + /* Default values */ + self->cell_width = 1; + self->cell_height = 1; + self->unit_in_meters = 1E-6; + renderer_settings_dialog_update_labels(self); g_object_unref(builder); } @@ -155,9 +254,44 @@ void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struc hide_tex_options(dialog); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg), TRUE); break; - - } } +void renderer_settings_dialog_set_cell_width(RendererSettingsDialog *dialog, unsigned int width) +{ + if (!dialog) + return; + + if (width == 0) + width = 1; + + + dialog->cell_width = width; + renderer_settings_dialog_update_labels(dialog); +} + +void renderer_settings_dialog_set_cell_height(RendererSettingsDialog *dialog, unsigned int height) +{ + if (!dialog) + return; + + if (height == 0) + height = 1; + + dialog->cell_height = height; + renderer_settings_dialog_update_labels(dialog); +} + +void renderer_settings_dialog_set_database_unit_scale(RendererSettingsDialog *dialog, double unit_in_meters) +{ + if (!dialog) + return; + + if (unit_in_meters < 0) + unit_in_meters *= -1; + + dialog->unit_in_meters = unit_in_meters; + renderer_settings_dialog_update_labels(dialog); +} + /** @} */ diff --git a/widgets/conv-settings-dialog.h b/widgets/conv-settings-dialog.h index 909ceaa..562a114 100644 --- a/widgets/conv-settings-dialog.h +++ b/widgets/conv-settings-dialog.h @@ -75,6 +75,27 @@ void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struc */ void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings); +/** + * @brief renderer_settings_dialog_set_cell_width Set width for rendered cell + * @param dialog + * @param width Width in database units + */ +void renderer_settings_dialog_set_cell_width(RendererSettingsDialog *dialog, unsigned int width); + +/** + * @brief renderer_settings_dialog_set_cell_height Set height for rendered cell + * @param dialog + * @param height Height in database units + */ +void renderer_settings_dialog_set_cell_height(RendererSettingsDialog *dialog, unsigned int height); + +/** + * @brief renderer_settings_dialog_set_database_unit_scale Set database scale + * @param dialog dialog element + * @param unit_in_meters Database unit in meters + */ +void renderer_settings_dialog_set_database_unit_scale(RendererSettingsDialog *dialog, double unit_in_meters); + #endif /* __CONV_SETTINGS_DIALOG_H__ */ /** @} */