28 Commits

Author SHA1 Message Date
f6c65d9c7a Merge branch 'dev' 2022-04-10 15:35:14 +02:00
d43bec2cea Merge pull request 'issue/44-remove-duplicate-vertices' (#45) from issue/44-remove-duplicate-vertices into dev
Reviewed-on: #45
2022-04-10 15:33:41 +02:00
05a1ef9014 Disable debug output of parser. 2022-04-10 15:31:55 +02:00
a36b78b237 Add vertex simplification to parser
* Duplicate / Redundant vertices of polygons are now removed during parsing.
* Implications: Reduced output size of tex document, faster rendering.
2022-04-10 15:28:23 +02:00
ac87cafa37 Merge pull request 'Merge new features and minor fixes for v1.2.1 release' (#43) from dev into master
Reviewed-on: #43
2022-04-09 20:39:09 +02:00
091729841a Merge branch 'master' into dev 2022-04-09 20:39:07 +02:00
28368e8a32 Cairo Renderer: Only print notification that layer is rendered, if it is actually rendered 2022-04-09 20:36:49 +02:00
2b3cc8222a Merge pull request 'Change icons to new Adwaita icons' (#42) from update-icons into dev
Reviewed-on: #42
2022-04-09 20:15:26 +02:00
c23150b819 Merge branch 'dev' into update-icons 2022-04-09 20:15:01 +02:00
049e6c2a4c Merge pull request 'Improve some features' (#41) from improve-features into dev
Reviewed-on: #41
2022-04-09 20:13:47 +02:00
600e10e4d5 Increase layer count of Cairo renderer as this turned out to be too low for some semiconductor technologies 2022-04-09 20:10:11 +02:00
238f2cea82 Improve Autonaming in GUI
Autonaming now only asks for overwrite confirmation, if there
are layers with non empty names. Otherwise, the dialog is not shown.
2022-04-09 20:08:24 +02:00
91706ccf2e Change icons to new Adwaita icons 2022-04-09 19:40:39 +02:00
17e7239e54 Merge branch 'dev' 2022-02-11 21:57:10 +01:00
554b73c406 Fix hard crash in case of a unwritable Latex Output file. Print warnign instead of hard stop 2022-02-11 21:56:54 +01:00
4eebff04a4 Update README.MD
Add github status badge for CI
2021-10-01 23:46:32 +02:00
04525611fa Update cmake.yml
Add gettext to dependencies
2021-10-01 23:43:37 +02:00
cb92d64ec3 Update cmake.yml 2021-10-01 23:41:40 +02:00
37ff2080f9 Create cmake.yml 2021-10-01 23:35:16 +02:00
e1b85d1a99 Merge branch 'issue/39-fix-search' of mhu/gds-render into dev 2020-11-26 23:08:55 +01:00
b0c9afdae5 Fix #39: Checking of pure library entry in cell selector was broken 2020-11-26 23:07:48 +01:00
f6abfada2c ColorPalette: Fix Dispose function
* Set freed pointer to NULL in dispose function because dispose cna be run multiple times. This fixes the case of freeing an already freed pointer.
2020-07-09 23:54:40 +02:00
f135b42d8a make clear we're not getting a return value from vector_2d_copy 2020-06-29 20:03:38 +02:00
058564326b Update library and compiler versions in doxygen 2020-04-24 01:17:20 +02:00
fd1eac7fda Merge branch 'master' into dev 2020-04-24 01:07:50 +02:00
2c91956b32 Doxygen: Update calculate_cell_bounding_box()
* Fix typo
* Extend description
2020-04-24 01:05:37 +02:00
232d025211 Doxygen: Update calculate_cell_bounding_box()
* Add note about problematic behaviour
* Fix typos
2020-04-24 01:02:10 +02:00
e461b0be1d Merge branch 'dev' 2020-04-19 00:52:42 +02:00
18 changed files with 384 additions and 203 deletions

37
.github/workflows/cmake.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: CMake
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get -y install libgtk-3-dev gettext
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

View File

@@ -1,5 +1,7 @@
# GDS-Render Readme # GDS-Render Readme
[![CMake](https://github.com/0mhu/gds-render/actions/workflows/cmake.yml/badge.svg?branch=master)](https://github.com/0mhu/gds-render/actions/workflows/cmake.yml)
This software is a rendering programm for GDS2 layout files. This software is a rendering programm for GDS2 layout files.
The GDS2 format is mainly used in integrated circuit development. The GDS2 format is mainly used in integrated circuit development.
This program allows the conversion of a GDS file to a vector graphics file. This program allows the conversion of a GDS file to a vector graphics file.

View File

@@ -155,6 +155,10 @@ int command_line_convert_gds(const char *gds_name,
LayerSettings *layer_sett; LayerSettings *layer_sett;
GdsOutputRenderer *current_renderer; GdsOutputRenderer *current_renderer;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
/* Check if parameters are valid */ /* Check if parameters are valid */
if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) { if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) {
printf(_("Probably missing argument. Check --help option\n")); printf(_("Probably missing argument. Check --help option\n"));
@@ -173,7 +177,7 @@ int command_line_convert_gds(const char *gds_name,
/* Load GDS */ /* Load GDS */
clear_lib_list(&libs); clear_lib_list(&libs);
res = parse_gds_from_file(gds_name, &libs); res = parse_gds_from_file(gds_name, &libs, &gds_parsing_options);
if (res) if (res)
goto ret_destroy_library_list; goto ret_destroy_library_list;

View File

@@ -30,7 +30,7 @@ Development is done with the following library versions:
| Cairographics | GLib2 | GTK3 | | Cairographics | GLib2 | GTK3 |
| ------------- | ---------- | --------- | | ------------- | ---------- | --------- |
| 1.17.3 | 2.60.6-1 | 3.24.10-1 | | 1.17.2 | 2.64.2 | 3.24.18 |
@section comp-instr Compilation Instructions @section comp-instr Compilation Instructions
@subsection linux-build General Linux Build Instruction @subsection linux-build General Linux Build Instruction
@@ -47,7 +47,7 @@ Once cmake has finished, type
make make
@endcode @endcode
to build the program and to build the program and
@code @code
make documentation make documentation
@endcode @endcode
@@ -59,7 +59,7 @@ The subfolder 'AUR' contains a PKGBUILD file to build an Archlinux/Pacman packag
@subsection comp-warnings Compiler Warnings @subsection comp-warnings Compiler Warnings
The compiler will throw the following warnings. Compiled with GCC 8.2.1. The compiler will throw the following warnings. Compiled with GCC 9.3.0.
| Warning | Assessment | | Warning | Assessment |
| ------- | ---------- | | ------- | ---------- |

View File

@@ -187,7 +187,8 @@ static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1); gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
if (lib) { /* Show always, if this is a pure lib entry */
if (lib && !cell) {
result = TRUE; result = TRUE;
goto exit_filter; goto exit_filter;
} }
@@ -277,6 +278,10 @@ static void on_load_gds(gpointer button, gpointer user)
char *filename; char *filename;
unsigned int cell_error_level; unsigned int cell_error_level;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
self = RENDERER_GUI(user); self = RENDERER_GUI(user);
if (!self) if (!self)
return; return;
@@ -306,7 +311,7 @@ static void on_load_gds(gpointer button, gpointer user)
clear_lib_list(&self->gds_libraries); clear_lib_list(&self->gds_libraries);
/* Parse new GDSII file */ /* Parse new GDSII file */
gds_result = parse_gds_from_file(filename, &self->gds_libraries); gds_result = parse_gds_from_file(filename, &self->gds_libraries, &gds_parsing_options);
/* Delete file name afterwards */ /* Delete file name afterwards */
g_free(filename); g_free(filename);
@@ -690,19 +695,13 @@ static void on_select_all_layers_clicked(GtkWidget *button, gpointer user_data)
layer_selector_select_all_layers(gui->layer_selector, TRUE); layer_selector_select_all_layers(gui->layer_selector, TRUE);
} }
static void auto_naming_clicked(GtkWidget *button, gpointer user_data) static gboolean auto_naming_ask_for_override(GdsRenderGui *gui)
{ {
GdsRenderGui *gui;
GtkDialog *dialog; GtkDialog *dialog;
gboolean overwrite; gint dialog_result;
int dialog_result; gboolean overwrite = FALSE;
(void)button;
gui = RENDERER_GUI(user_data); g_return_val_if_fail(RENDERER_IS_GUI(gui), FALSE);
/* Don't do anything if the selector is empty. */
if (!layer_selector_contains_elements(gui->layer_selector))
return;
/* Ask for overwrite */ /* Ask for overwrite */
dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION, dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION,
@@ -719,6 +718,25 @@ static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
} }
gtk_widget_destroy(GTK_WIDGET(dialog)); gtk_widget_destroy(GTK_WIDGET(dialog));
return overwrite;
}
static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
{
GdsRenderGui *gui;
gboolean overwrite = FALSE;
(void)button;
gui = RENDERER_GUI(user_data);
/* Don't do anything if the selector is empty. */
if (!layer_selector_contains_elements(gui->layer_selector))
return;
/* Ask, if names shall be overwritten, if they are not empty */
if (layer_selector_num_of_named_elements(gui->layer_selector) > 0)
overwrite = auto_naming_ask_for_override(gui);
layer_selector_auto_name_layers(gui->layer_selector, overwrite); layer_selector_auto_name_layers(gui->layer_selector, overwrite);
} }

View File

@@ -266,7 +266,8 @@ static uint16_t gds_convert_unsigned_int16(const char *data)
* @param library_ptr Return of newly created library. * @param library_ptr Return of newly created library.
* @return Newly created list pointer * @return Newly created list pointer
*/ */
static GList *append_library(GList *curr_list, struct gds_library **library_ptr) static GList *append_library(GList *curr_list, const struct gds_library_parsing_opts *opts,
struct gds_library **library_ptr)
{ {
struct gds_library *lib; struct gds_library *lib;
@@ -276,6 +277,8 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
lib->name[0] = 0; lib->name[0] = 0;
lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten
lib->cell_names = NULL; lib->cell_names = NULL;
/* Copy the settings into the library */
memcpy(&lib->parsing_opts, opts, sizeof(struct gds_library_parsing_opts));
} else } else
return NULL; return NULL;
if (library_ptr) if (library_ptr)
@@ -488,20 +491,102 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
} }
/** /**
* @brief Scans cell references inside cell * @brief Simplify graphics objects
This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance * @param graphics gfx struct
* @param user_data GDS library
*/
static void simplify_graphics(gpointer graphics, gpointer user_data)
{
struct gds_graphics *gfx;
const struct gds_point *first_vertex = NULL;
const struct gds_point *prev_vertex = NULL;
const struct gds_point *current_vertex;
GList *vertex_iter;
GList *next_iter;
(void)user_data;
size_t processed_count = 0U;
size_t removed_count = 0U;
gfx = (struct gds_graphics *)graphics;
if (gfx->gfx_type == GRAPHIC_POLYGON) {
GDS_INF("\t\t\tPolygon found\n");
/* Loop over all vertices */
for (vertex_iter = gfx->vertices; vertex_iter;) {
current_vertex = (const struct gds_point *)vertex_iter->data;
next_iter = g_list_next(vertex_iter);
processed_count++;
if (vertex_iter == gfx->vertices) {
/* This is the first vertex */
first_vertex = current_vertex;
prev_vertex = NULL;
}
if (prev_vertex) {
if (current_vertex->x == prev_vertex->x && current_vertex->y == prev_vertex->y) {
/* Vertex is the same as the previous one */
GDS_INF("\t\t\t\tDuplicate vertex (%d,%d). Removing...\n",
current_vertex->x, current_vertex->y);
/* Delete the current one from the list */
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
/* Free the data */
if (vertex_iter->data)
free(vertex_iter->data);
vertex_iter->data = NULL;
g_list_free_1(vertex_iter);
removed_count++;
} else if (!g_list_next(vertex_iter)) {
/* This is the last element in the list */
if (current_vertex->x == first_vertex->x &&
current_vertex->y == first_vertex->y) {
GDS_INF("\t\t\t\tLast vertex is identical to first vertex (%d,%d). Removing\n",
current_vertex->x, current_vertex->y);
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
if (vertex_iter->data)
free(vertex_iter->data);
g_list_free_1(vertex_iter);
removed_count++;
} else {
GDS_WARN("First vertex is not coincident with first vertex, although the GDS file format specifies this. However, this is not a problem.");
}
}
}
vertex_iter = next_iter;
prev_vertex = current_vertex;
}
GDS_INF("\t\t\tProcessed %zu vertices. %zu removed.\n", processed_count, removed_count);
}
}
/**
* @brief Scans cell and resolves references and simplifies polygons
* This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance
*
* @param gcell pointer cast of #gds_cell * * @param gcell pointer cast of #gds_cell *
* @param library Library where the cell references are searched in * @param library Library where the cell references are searched in
*/ */
static void scan_cell_reference_dependencies(gpointer gcell, gpointer library) static void scan_cell_references_and_polygons(gpointer gcell, gpointer library)
{ {
struct gds_cell *cell = (struct gds_cell *)gcell; struct gds_cell *cell = (struct gds_cell *)gcell;
struct gds_library *my_lib = (struct gds_library *)library;
int simplify_polygons;
simplify_polygons = my_lib->parsing_opts.simplified_polygons;
GDS_INF("\tScanning cell: %s\n", cell->name); GDS_INF("\tScanning cell: %s\n", cell->name);
GDS_INF("\t\tCell references\n");
/* Scan all library references */ /* Scan all library references */
g_list_foreach(cell->child_cells, parse_reference_list, library); g_list_foreach(cell->child_cells, parse_reference_list, library);
GDS_INF("\t\tSimplifying Polygons%s\n", simplify_polygons ? "" : ": skipped");
if (simplify_polygons) {
g_list_foreach(cell->graphic_objs, simplify_graphics, library);
}
} }
/** /**
@@ -517,7 +602,7 @@ static void scan_library_references(gpointer library_list_item, gpointer user)
(void)user; (void)user;
GDS_INF("Scanning Library: %s\n", lib->name); GDS_INF("Scanning Library: %s\n", lib->name);
g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib); g_list_foreach(lib->cells, scan_cell_references_and_polygons, lib);
} }
/** /**
@@ -617,7 +702,8 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
GDS_INF("Converted AREF to SREFs\n"); GDS_INF("Converted AREF to SREFs\n");
} }
int parse_gds_from_file(const char *filename, GList **library_list) int parse_gds_from_file(const char *filename, GList **library_list,
const struct gds_library_parsing_opts *parsing_options)
{ {
char *workbuff; char *workbuff;
int read; int read;
@@ -697,7 +783,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
/* if begin: Allocate structures */ /* if begin: Allocate structures */
switch (rec_type) { switch (rec_type) {
case BGNLIB: case BGNLIB:
lib_list = append_library(lib_list, &current_lib); lib_list = append_library(lib_list, parsing_options, &current_lib);
if (lib_list == NULL) { if (lib_list == NULL) {
GDS_ERROR("Allocating memory failed"); GDS_ERROR("Allocating memory failed");
run = -3; run = -3;
@@ -771,7 +857,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -4; run = -4;
break; break;
} }
GDS_INF("\tEntering boundary/Box\n"); GDS_INF("\tEntering boundary of type %s\n", rec_type==BOUNDARY ? "polygon" : "box");
break; break;
case SREF: case SREF:
if (current_cell == NULL) { if (current_cell == NULL) {
@@ -806,7 +892,9 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
case ENDEL: case ENDEL:
if (current_graphics != NULL) { if (current_graphics != NULL) {
GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path")); GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary"
: (current_graphics->gfx_type == GRAPHIC_PATH ? "path"
: "box")));
current_graphics = NULL; current_graphics = NULL;
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
@@ -825,11 +913,11 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} else if (current_s_reference) { } else if (current_s_reference) {
if (rec_data_length != 8) { if (rec_data_length != 8) {
GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!"); GDS_WARN("Instance has weird coordinates. Rendered output might be wrong!");
} }
} else if (current_a_reference) { } else if (current_a_reference) {
if (rec_data_length != (3*(4+4))) if (rec_data_length != (3*(4+4)))
GDS_WARN("Array instance has weird coordinates. Rendered output might be screwed!"); GDS_WARN("Array instance has weird coordinates. Rendered output might be wrong!");
} }
break; break;
case AREF: case AREF:

View File

@@ -65,7 +65,7 @@ void vector_2d_rotate(struct vector_2d *vec, double angle)
sin_val = sin(angle); sin_val = sin(angle);
cos_val = cos(angle); cos_val = cos(angle);
vector_2d_copy(&temp, vec); (void)vector_2d_copy(&temp, vec);
/* Apply rotation matrix */ /* Apply rotation matrix */
vec->x = (cos_val * temp.x) - (sin_val * temp.y); vec->x = (cos_val * temp.x) - (sin_val * temp.y);

View File

@@ -48,9 +48,11 @@
* *
* @param[in] filename Path to the GDS file * @param[in] filename Path to the GDS file
* @param[in,out] library_array GList Pointer. * @param[in,out] library_array GList Pointer.
* @param[in] parsing_options Parsing options.
* @return 0 if successful * @return 0 if successful
*/ */
int parse_gds_from_file(const char *filename, GList **library_array); int parse_gds_from_file(const char *filename, GList **library_array,
const struct gds_library_parsing_opts *parsing_options);
/** /**
* @brief Deletes all libraries including cells, references etc. * @brief Deletes all libraries including cells, references etc.

View File

@@ -129,6 +129,13 @@ struct gds_cell {
struct gds_cell_checks checks; /**< @brief Checking results */ struct gds_cell_checks checks; /**< @brief Checking results */
}; };
/**
* @brief Options, hwo this liobrary was parsed.
*/
struct gds_library_parsing_opts {
int simplified_polygons; /**< @brief Polygons have been simplified. Coincident end point removed. */
};
/** /**
* @brief GDS Toplevel library * @brief GDS Toplevel library
*/ */
@@ -136,6 +143,7 @@ struct gds_library {
char name[CELL_NAME_MAX]; char name[CELL_NAME_MAX];
struct gds_time_field mod_time; struct gds_time_field mod_time;
struct gds_time_field access_time; struct gds_time_field access_time;
struct gds_library_parsing_opts parsing_opts;
double unit_in_meters; /**< Length of a database unit in meters */ 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 *cells; /**< List of #gds_cell that contains all cells in this library*/
GList *cell_names /**< List of strings that contains all cell names */; GList *cell_names /**< List of strings that contains all cell names */;

View File

@@ -35,10 +35,17 @@
#include <gds-render/gds-utils/gds-types.h> #include <gds-render/gds-utils/gds-types.h>
/** /**
* @brief calculate_cell_bounding_box Calculate bounding box of gds cell * @brief Calculate bounding box of a gds cell.
* @param box Resulting boundig box. Will be uüdated and not overwritten *
* This function updates a given bounding box with the dimensions of a
* gds_cell. Please note that the handling of path miter points is not complete yet.
* If a path object is the outmost object of your cell at any edge,
* the resulting bounding box might be the wrong size. The devistion from the real size
* is guaranteed to be within the width of the path object.
*
* @param box Resulting boundig box. Will be updated and not overwritten
* @param cell Toplevel cell * @param cell Toplevel cell
* @warning Path handling not yet implemented correctly. * @warning Handling of Path graphic objects not yet implemented correctly.
*/ */
void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell); void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell);

View File

@@ -130,6 +130,13 @@ void layer_selector_auto_name_layers(LayerSelector *layer_selector, gboolean ove
*/ */
gboolean layer_selector_contains_elements(LayerSelector *layer_selector); gboolean layer_selector_contains_elements(LayerSelector *layer_selector);
/**
* @brief Get number of layer elements that are named
* @param[in] layer_selector Layer selector
* @return Number of layers with a name != NULL or != ""
*/
size_t layer_selector_num_of_named_elements(LayerSelector *layer_selector);
G_END_DECLS G_END_DECLS
#endif /* __LAYER_SELECTOR_H__ */ #endif /* __LAYER_SELECTOR_H__ */

View File

@@ -38,7 +38,7 @@ G_DECLARE_FINAL_TYPE(CairoRenderer, cairo_renderer, GDS_RENDER, CAIRO_RENDERER,
#define GDS_RENDER_TYPE_CAIRO_RENDERER (cairo_renderer_get_type()) #define GDS_RENDER_TYPE_CAIRO_RENDERER (cairo_renderer_get_type())
#define MAX_LAYERS (300) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/ #define MAX_LAYERS (5000) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/
/** /**
* @brief Create new CairoRenderer for SVG output * @brief Create new CairoRenderer for SVG output

View File

@@ -238,6 +238,7 @@ static void color_palette_dispose(GObject *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);
palette->color_array = NULL;
} }
/* Chain up to parent class */ /* Chain up to parent class */

View File

@@ -822,12 +822,10 @@ void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalett
unsigned int color_count; unsigned int color_count;
GdkRGBA color; GdkRGBA color;
if (GDS_RENDER_IS_COLOR_PALETTE(palette) == FALSE || LAYER_IS_SELECTOR(layer_selector) == FALSE) g_return_if_fail(GDS_RENDER_IS_COLOR_PALETTE(palette));
return; g_return_if_fail(LAYER_IS_SELECTOR(layer_selector));
if (global_alpha <= 0) g_return_if_fail(global_alpha > 0);
return; g_return_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box));
if (GTK_IS_LIST_BOX(layer_selector->list_box) == FALSE)
return;
le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box)); le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
@@ -898,4 +896,31 @@ gboolean layer_selector_contains_elements(LayerSelector *layer_selector)
return (layer_element_list ? TRUE : FALSE); return (layer_element_list ? TRUE : FALSE);
} }
size_t layer_selector_num_of_named_elements(LayerSelector *layer_selector)
{
GList *le_list;
GList *le_list_ptr;
LayerElement *le;
const char *layer_name;
size_t count = 0U;
g_return_val_if_fail(LAYER_IS_SELECTOR(layer_selector), 0U);
le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = g_list_next(le_list_ptr)) {
le = LAYER_ELEMENT(le_list_ptr->data);
if (!le)
continue;
layer_name = layer_element_get_name(le);
if (layer_name && *layer_name) {
/* Layer name is not empty. Count it */
count++;
}
}
return count;
}
/** @} */ /** @} */

View File

@@ -371,8 +371,6 @@ static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer
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;
@@ -381,6 +379,8 @@ static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer
if (!linfo->render) if (!linfo->render)
continue; continue;
dprintf(comm_pipe[1], _("Exporting layer %d to file\n"), linfo->layer);
if (pdf_file && pdf_cr) { if (pdf_file && pdf_cr) {
cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin); cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
cairo_paint_with_alpha(pdf_cr, linfo->color.alpha); cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);

View File

@@ -370,7 +370,7 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
l_renderer->pdf_layers, l_renderer->tex_standalone, renderer); l_renderer->pdf_layers, l_renderer->tex_standalone, renderer);
fclose(tex_file); fclose(tex_file);
} else { } else {
g_error(_("Could not open LaTeX output file")); g_warning(_("Could not open LaTeX output file"));
} }
if (settings) if (settings)

View File

@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 --> <!-- Generated with glade 3.38.2 -->
<interface> <interface>
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkAdjustment" id="adjustment1"> <object class="GtkAdjustment" id="adjustment1">
<property name="upper">1</property> <property name="upper">1</property>
<property name="value">1</property> <property name="value">1</property>
<property name="step_increment">0.01</property> <property name="step-increment">0.01</property>
<property name="page_increment">0.10000000000000001</property> <property name="page-increment">0.10</property>
</object> </object>
<object class="GtkBox" id="box"> <object class="GtkBox" id="box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="spacing">3</property> <property name="spacing">3</property>
<child> <child>
<object class="GtkEventBox" id="event-box"> <object class="GtkEventBox" id="event-box">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="stock">gtk-justify-fill</property> <property name="icon-name">open-menu-symbolic</property>
</object> </object>
</child> </child>
</object> </object>
@@ -33,7 +33,7 @@
<child> <child>
<object class="GtkLabel" id="layer"> <object class="GtkLabel" id="layer">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">label</property> <property name="label" translatable="yes">label</property>
</object> </object>
<packing> <packing>
@@ -45,9 +45,9 @@
<child> <child>
<object class="GtkColorButton" id="color"> <object class="GtkColorButton" id="color">
<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="use_alpha">True</property> <property name="use-alpha">True</property>
<property name="title" translatable="yes">Select Layer Color and Opacity</property> <property name="title" translatable="yes">Select Layer Color and Opacity</property>
<property name="rgba">rgb(0,0,0)</property> <property name="rgba">rgb(0,0,0)</property>
</object> </object>
@@ -61,9 +61,9 @@
<object class="GtkCheckButton" id="export"> <object class="GtkCheckButton" id="export">
<property name="label" translatable="yes">Export Layer</property> <property name="label" translatable="yes">Export Layer</property>
<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">False</property> <property name="receives-default">False</property>
<property name="draw_indicator">True</property> <property name="draw-indicator">True</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -74,7 +74,7 @@
<child> <child>
<object class="GtkEntry" id="entry"> <object class="GtkEntry" id="entry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can-focus">True</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>

View File

@@ -1,145 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 --> <!-- Generated with glade 3.38.2 -->
<interface> <interface>
<requires lib="gtk+" version="3.20"/> <requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="auto-name-img"> <object class="GtkImage" id="auto-name-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="stock">gtk-edit</property> <property name="icon-name">format-text-rich-symbolic</property>
</object> </object>
<object class="GtkImage" id="color-img"> <object class="GtkImage" id="color-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="stock">gtk-select-color</property> <property name="icon-name">color-select-symbolic</property>
</object>
<object class="GtkImage" id="load-mapping-img">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-open</property>
</object>
<object class="GtkImage" id="save-mapping-img">
<property name="visible">True</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>
</object> </object>
<object class="GtkImage" id="select-all-img"> <object class="GtkImage" id="select-all-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="stock">gtk-apply</property> <property name="icon-name">emblem-ok-symbolic</property>
</object> </object>
<object class="GtkImage" id="sort-down-img"> <object class="GtkImage" id="sort-down-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="stock">gtk-sort-ascending</property> <property name="icon-name">view-sort-descending-symbolic</property>
</object> </object>
<object class="GtkImage" id="sort-up-img"> <object class="GtkImage" id="sort-up-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="stock">gtk-sort-descending</property> <property name="icon-name">view-sort-ascending-symbolic</property>
</object> </object>
<object class="GtkWindow" id="main-window"> <object class="GtkWindow" id="main-window">
<property name="height_request">250</property> <property name="height-request">250</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="icon_name">gds-render</property> <property name="icon-name">gds-render</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="header-bar">
<property name="name">header</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">GDS-Render</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton" id="button-load-gds">
<property name="label">gtk-open</property>
<property name="visible">True</property>
<property name="can_focus">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="always_show_image">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="button-load-mapping">
<property name="label" translatable="yes">Load Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">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="always_show_image">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-save-mapping">
<property name="label" translatable="yes">Save Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="image">save-mapping-img</property>
<property name="always_show_image">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="convert-button">
<property name="label">gtk-convert</property>
<property name="name">button-convert</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">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="always_show_image">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkSearchEntry" id="cell-search"> <object class="GtkSearchEntry" id="cell-search">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can-focus">True</property>
<property name="primary_icon_name">edit-find-symbolic</property> <property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property> <property name="primary-icon-activatable">False</property>
<property name="primary_icon_sensitive">False</property> <property name="primary-icon-sensitive">False</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -150,15 +62,15 @@
<child> <child>
<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="hscrollbar_policy">never</property> <property name="hscrollbar-policy">never</property>
<property name="shadow_type">in</property> <property name="shadow-type">in</property>
<child> <child>
<object class="GtkTreeView" id="cell-tree"> <object class="GtkTreeView" id="cell-tree">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can-focus">True</property>
<property name="enable_search">False</property> <property name="enable-search">False</property>
<property name="enable_grid_lines">both</property> <property name="enable-grid-lines">both</property>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection"/> <object class="GtkTreeSelection"/>
</child> </child>
@@ -181,20 +93,20 @@
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkButton" id="button-up-sort"> <object class="GtkButton" id="button-up-sort">
<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="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>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -205,11 +117,11 @@
<child> <child>
<object class="GtkButton" id="button-down-sort"> <object class="GtkButton" id="button-down-sort">
<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="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>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -220,11 +132,11 @@
<child> <child>
<object class="GtkButton" id="auto-color-button"> <object class="GtkButton" id="auto-color-button">
<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="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>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -235,11 +147,11 @@
<child> <child>
<object class="GtkButton" id="button-select-all"> <object class="GtkButton" id="button-select-all">
<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="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>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -250,11 +162,11 @@
<child> <child>
<object class="GtkButton" id="button-auto-name"> <object class="GtkButton" id="button-auto-name">
<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="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>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@@ -272,19 +184,19 @@
<child> <child>
<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="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>
<object class="GtkViewport"> <object class="GtkViewport">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<child> <child>
<object class="GtkListBox" id="layer-list"> <object class="GtkListBox" id="layer-list">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="selection_mode">none</property> <property name="selection-mode">none</property>
</object> </object>
</child> </child>
</object> </object>
@@ -313,7 +225,7 @@
<child> <child>
<object class="GtkBox" id="activity-bar"> <object class="GtkBox" id="activity-bar">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<placeholder/> <placeholder/>
@@ -327,5 +239,75 @@
</child> </child>
</object> </object>
</child> </child>
<child type="titlebar">
<object class="GtkHeaderBar" id="header-bar">
<property name="name">header</property>
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">GDS-Render</property>
<property name="show-close-button">True</property>
<child>
<object class="GtkButton" id="button-load-gds">
<property name="label">Open GDS</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Open GDS2 Database</property>
<style>
<class name="suggested-action"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="button-load-mapping">
<property name="label" translatable="yes">Load Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Load the current layer configuration from CSV</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-save-mapping">
<property name="label" translatable="yes">Save Mapping</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="convert-button">
<property name="label">Convert Cell</property>
<property name="name">button-convert</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Convert selected cell</property>
<property name="always-show-image">True</property>
<style>
<class name="suggested-action"/>
</style>
</object>
<packing>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
</object> </object>
</interface> </interface>