Compare commits

..

40 Commits

Author SHA1 Message Date
504dc476b1 Fix recursive clone in github actions 2022-12-17 19:00:16 +01:00
8ff872cf36 Fix recursive clone in github actions 2022-12-17 18:57:19 +01:00
9c4dbd51c8 Merge branch 'dev' 2022-12-17 18:52:05 +01:00
2829143bbe Merge pull request 'Fix #49: Initialize variable' (#50) from fix-issue-49 into dev
Reviewed-on: #50
2022-12-17 18:43:56 +01:00
5185097075 Fix #49: Initialize variable 2022-12-17 18:43:10 +01:00
573cd59892 Merge branch 'dev' 2022-04-17 22:21:38 +02:00
8b1f667819 Merge pull request 'issue/47-add-vertex-count-to-gui' (#48) from issue/47-add-vertex-count-to-gui into dev
Reviewed-on: #48
2022-04-17 20:09:47 +02:00
c2ca2ff573 Rework the analysis cmd option to work with new statistics functions 2022-04-17 20:07:57 +02:00
c0ac6cc3c5 Move statistic calculation to parser. Show Vertex and GFX count in GUI. CLI -A param is now broken. Will implement in next commits. 2022-04-17 18:37:32 +02:00
22bc3a18d7 Issue #47: Add renderer for cell statistics and render dummy value 2022-04-17 17:40:18 +02:00
dbc9fcdf34 Issue #47: AddVertex count column to tree view 2022-04-17 16:54:57 +02:00
b39030aeaa Fix PKGBUILD 2022-04-17 00:47:41 +02:00
2f59a762cd Fix PKGBUILD 2022-04-17 00:46:51 +02:00
ab26f8a2af Fix PKGBUILD 2022-04-17 00:45:49 +02:00
9a43cd53f8 Update PKGBUILD 2022-04-17 00:38:50 +02:00
ba6b07c8a2 Implement cell statistics command line interface 2022-04-17 00:37:26 +02:00
1548c82542 Add libfort for pretty console tables 2022-04-16 16:13:22 +02:00
fb6d31c120 Fix stuck at -1 return value when executing command line interface 2022-04-16 16:00:50 +02:00
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
64 changed files with 1037 additions and 864 deletions

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

@ -0,0 +1,40 @@
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:
- name: Checkout Repository
uses: actions/checkout@v2
with:
submodules: recursive
- 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}}

4
.gitmodules vendored
View File

@ -2,3 +2,7 @@
path = c-style-checker path = c-style-checker
url = https://git.shimatta.de/mhu/c-style-checker url = https://git.shimatta.de/mhu/c-style-checker
branch = master branch = master
[submodule "3rdparty/libfort"]
path = 3rdparty/libfort
url = https://git.shimatta.de/3rd-party/libfort
branch = develop

1
3rdparty/libfort vendored Submodule

@ -0,0 +1 @@
Subproject commit 41237162a9bd34a30a88069ee4e230584ae8d674

View File

@ -10,8 +10,8 @@ licence=('GPLv2')
depends=('glib2' 'gtk3' 'cairo') depends=('glib2' 'gtk3' 'cairo')
makedepends=('cmake' 'git') makedepends=('cmake' 'git')
privides=('gds-render') privides=('gds-render')
source=("${pkgname}-git"::"git+https://git.shimatta.de/mhu/gds-render.git") source=("${pkgname}-git"::"git+https://git.shimatta.de/mhu/gds-render.git" "https://git.shimatta.de/3rd-party/libfort.git")
sha1sums=('SKIP') sha1sums=('SKIP' 'SKIP')
pkgver () { pkgver () {
_date=`date +"%Y%m%d"` _date=`date +"%Y%m%d"`
@ -26,6 +26,13 @@ build () {
make make
} }
prepare () {
cd "${pkgname}-git"
git submodule init
git config submodule.libfort.url "$srcdir/libfort"
git submodule update
}
package () { package () {
cd "$srcdir/$pkgname-git/build" cd "$srcdir/$pkgname-git/build"
make DESTDIR="${pkgdir}" install make DESTDIR="${pkgdir}" install

View File

@ -1,4 +1,4 @@
project(gds-render) project(gds-render LANGUAGES C)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE) set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE)
@ -38,7 +38,7 @@ IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"${CMAKE_CURRENT_BINARY_DIR}/translations/output\") add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"${CMAKE_CURRENT_BINARY_DIR}/translations/output\")
message("${BoldMagenta}${CMAKE_CURRENT_BINARY_DIR}/translations/output used as data dir${ColorReset}") message("${BoldMagenta}${CMAKE_CURRENT_BINARY_DIR}/translations/output used as data dir${ColorReset}")
else(CMAKE_BUILD_TYPE STREQUAL "Debug") else(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("${BoldCyan}Global locale directory used. Make sure files in /usr/share/locale are available${ColorReset}") message("Global locale directory used. Make sure files in /usr/share/locale are available")
add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"/usr/share\") add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"/usr/share\")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug") ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
@ -77,6 +77,9 @@ add_subdirectory(resources)
add_subdirectory(doxygen) add_subdirectory(doxygen)
add_subdirectory(translations) add_subdirectory(translations)
add_subdirectory(version) add_subdirectory(version)
set(FORT_ENABLE_TESTING OFF CACHE INTERNAL "")
add_subdirectory(3rdparty/libfort)
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS}) link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER}) add_definitions(${GLIB2_CFLAGS_OTHER})
@ -90,5 +93,5 @@ install (TARGETS ${PROJECT_NAME}
RUNTIME RUNTIME
DESTINATION bin DESTINATION bin
) )
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS}) target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS} fort)

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

@ -0,0 +1,106 @@
/*
* GDSII-Converter
* Copyright (C) 2022 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 cell-statistics-renderer.c
* @brief CellStatisticsRenderer GObject Class
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup CellStatisticsRenderer
* @{
*/
#include <gds-render/cell-selector/cell-statistics-renderer.h>
G_DEFINE_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GTK_TYPE_CELL_RENDERER_TEXT)
enum {
PROP_CELL_STAT = 1,
PROP_COUNT
};
static void cell_statistics_renderer_set_property(GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
GValue val = G_VALUE_INIT;
GString *string;
const struct gds_cell_statistics *cell_stat;
switch (param_id) {
case PROP_CELL_STAT:
cell_stat = (const struct gds_cell_statistics *)g_value_get_pointer(value);
g_value_init(&val, G_TYPE_STRING);
string = g_string_new_len("", 5);
if (cell_stat)
g_string_printf(string, "%zu (%zu) | %zu (%zu)", cell_stat->total_vertex_count,
cell_stat->vertex_count, cell_stat->total_gfx_count, cell_stat->gfx_count);
g_value_set_string(&val, string->str);
g_object_set_property(object, "text", &val);
g_value_unset(&val);
g_string_free(string, TRUE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static void cell_statistics_renderer_get_property(GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
(void)value;
switch (param_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static GParamSpec *properties[PROP_COUNT];
void cell_statistics_renderer_class_init(CellStatisticsRendererClass *klass)
{
GObjectClass *oclass = G_OBJECT_CLASS(klass);
oclass->set_property = cell_statistics_renderer_set_property;
oclass->get_property = cell_statistics_renderer_get_property;
properties[PROP_CELL_STAT] = g_param_spec_pointer("cell-stat", "cell-stat",
"Cell statistics", G_PARAM_WRITABLE);
g_object_class_install_properties(oclass, PROP_COUNT, properties);
}
void cell_statistics_renderer_init(CellStatisticsRenderer *self)
{
(void)self;
}
GtkCellRenderer *cell_statistics_renderer_new(void)
{
return GTK_CELL_RENDERER(g_object_new(TYPE_GDS_RENDER_CELL_STAT_RENDERER, NULL));
}
/** @} */

View File

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <string.h>
#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>
@ -38,6 +39,41 @@
#include <gds-render/output-renderers/latex-renderer.h> #include <gds-render/output-renderers/latex-renderer.h>
#include <gds-render/output-renderers/external-renderer.h> #include <gds-render/output-renderers/external-renderer.h>
#include <gds-render/gds-utils/gds-tree-checker.h> #include <gds-render/gds-utils/gds-tree-checker.h>
#include <gds-render/gds-utils/gds-statistics.h>
#include <fort.h>
#ifndef COUNT_OF
#define COUNT_OF(x) (sizeof((x))/sizeof(0[(x)]))
#endif
enum analysis_format {
ANA_FORMAT_SIMPLE = 0,
ANA_FORMAT_CELLS_ONLY,
ANA_FORMAT_PRETTY,
};
struct analysis_format_cmdarg {
enum analysis_format format;
const char *argument;
};
static const struct analysis_format_cmdarg analysis_format_lookup[] = {
{
.format = ANA_FORMAT_SIMPLE,
.argument = "simple",
},
{
.format = ANA_FORMAT_PRETTY,
.argument = "pretty",
},
{
.format = ANA_FORMAT_CELLS_ONLY,
.argument = "cellsonly"
}
};
static int string_array_count(char **string_array) static int string_array_count(char **string_array)
{ {
@ -146,7 +182,6 @@ int command_line_convert_gds(const char *gds_name,
double scale) double scale)
{ {
int ret = -1; int ret = -1;
int render_ret;
GList *libs = NULL; GList *libs = NULL;
int res; int res;
GList *renderer_list = NULL; GList *renderer_list = NULL;
@ -156,6 +191,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"));
@ -164,14 +203,7 @@ int command_line_convert_gds(const char *gds_name,
/* Load layer_settings */ /* Load layer_settings */
layer_sett = layer_settings_new(); layer_sett = layer_settings_new();
if (!layer_sett) layer_settings_load_from_csv(layer_sett, layer_file);
goto return_value;
ret = layer_settings_load_from_csv(layer_sett, layer_file);
if (ret) {
fprintf(stderr, _("Loading layer mapping file failed.\n"));
goto ret_destroy_layer_mapping;
}
/* Create renderers */ /* Create renderers */
if (create_renderers(renderers, output_file_names, tex_layers, tex_standalone, if (create_renderers(renderers, output_file_names, tex_layers, tex_standalone,
@ -181,7 +213,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;
@ -229,11 +261,11 @@ int command_line_convert_gds(const char *gds_name,
/* Execute all rendererer instances */ /* Execute all rendererer instances */
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) { for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) {
current_renderer = GDS_RENDER_OUTPUT_RENDERER(list_iter->data); current_renderer = GDS_RENDER_OUTPUT_RENDERER(list_iter->data);
render_ret = gds_output_renderer_render_output(current_renderer, toplevel_cell, scale); gds_output_renderer_render_output(current_renderer, toplevel_cell, scale);
if (render_ret)
fprintf(stderr, "Rendering failed with error code: %d\n", render_ret);
} }
ret = 0;
ret_destroy_library_list: ret_destroy_library_list:
clear_lib_list(&libs); clear_lib_list(&libs);
ret_clear_renderers: ret_clear_renderers:
@ -241,7 +273,194 @@ ret_clear_renderers:
g_object_unref(list_iter->data); g_object_unref(list_iter->data);
ret_destroy_layer_mapping: ret_destroy_layer_mapping:
g_object_unref(layer_sett); g_object_unref(layer_sett);
return_value: return ret;
}
static void indent_line(int level)
{
while (level--)
printf("\t");
}
static int printf_indented(int level, const char *format, ...)
{
int ret;
va_list a_list;
va_start(a_list, format);
indent_line(level);
ret = vprintf(format, a_list);
va_end(a_list);
return ret;
}
static void print_simple_stat(GList *lib_stat_list)
{
int indentation_level = 0;
GList *lib_iter;
GList *cell_iter;
const struct gds_library *lib;
const struct gds_cell *cell;
const struct gds_lib_statistics *lib_stat;
const struct gds_cell_statistics *cell_stat;
for (lib_iter = lib_stat_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
lib = (const struct gds_library *)lib_iter->data;
lib_stat = &lib->stats;
printf_indented(indentation_level, "Library %s\n", lib->name);
indentation_level++;
for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
cell = (const struct gds_cell *)cell_iter->data;
cell_stat = &cell->stats;
printf_indented(indentation_level, "Cell %s\n", cell->name);
indentation_level++;
printf_indented(indentation_level, "Reference count: %zu\n", cell_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", cell_stat->gfx_count);
printf_indented(indentation_level, "Total Graphics count: %zu\n", cell_stat->total_gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", cell_stat->vertex_count);
printf_indented(indentation_level, "Total Vertex count: %zu\n", cell_stat->total_vertex_count);
printf_indented(indentation_level, "Unresolved children: %d\n",
cell->checks.unresolved_child_count);
printf_indented(indentation_level, "Reference loop: %s\n",
cell->checks.affected_by_reference_loop ? "yes" : "no");
indentation_level--;
}
printf_indented(indentation_level, "Cell count: %zu\n", lib_stat->cell_count);
printf_indented(indentation_level, "Reference count: %zu\n", lib_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", lib_stat->gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", lib_stat->vertex_count);
}
}
static void table_stat_create_cell_row(struct gds_cell *cell, ft_table_t *tab)
{
ft_printf_ln(tab, "%s|%s|%zu|%zu|%zu|%zu|%zu|%d|%s",
cell->parent_library->name,
cell->name,
cell->stats.gfx_count,
cell->stats.total_gfx_count,
cell->stats.vertex_count,
cell->stats.total_vertex_count,
cell->stats.reference_count,
cell->checks.unresolved_child_count,
cell->checks.affected_by_reference_loop ? "yes" : "no");
}
static void table_stat_table_for_lib(struct gds_library *lib, ft_table_t *tab)
{
ft_printf_ln(tab, "%s|%zu|%zu|-|%zu|-|%zu|-|-",
lib->name,
lib->stats.cell_count,
lib->stats.gfx_count,
lib->stats.vertex_count,
lib->stats.reference_count);
g_list_foreach(lib->cells, (GFunc)table_stat_create_cell_row, tab);
}
static void print_table_stat(GList *lib_list)
{
ft_table_t *table;
table = ft_create_table();
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
ft_write_ln(table, "Library", "Cell", "GFX", "GFX+", "Vertices", "Vertices+", "Refs", "Unresolved Refs", "Loops");
g_list_foreach(lib_list, (GFunc)table_stat_table_for_lib, table);
printf("%s\n", ft_to_string(table));
ft_destroy_table(table);
}
static void print_statistics(enum analysis_format format, GList *lib_list)
{
switch (format) {
case ANA_FORMAT_PRETTY:
print_table_stat(lib_list);
break;
default:
print_simple_stat(lib_list);
break;
}
}
static void print_cell_names(GList *lib_list)
{
GList *lib_iter;
GList *name_iter;
struct gds_library *lib;
for (lib_iter = lib_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
lib = (struct gds_library *)lib_iter->data;
for (name_iter = lib->cell_names; name_iter; name_iter = name_iter->next) {
printf("%s\n", (const char *)name_iter->data);
}
}
}
int command_line_analyze_lib(const char *format, const char *gds_name)
{
enum analysis_format fmt = ANA_FORMAT_SIMPLE;
size_t idx;
int found = 0;
GList *lib_list = NULL;
const struct gds_library_parsing_opts parsing_opts = {
.simplified_polygons = 0,
};
int res;
int ret = 0;
GList *lib_iter;
g_return_val_if_fail(gds_name, -1002);
if (format && *format) {
/* Check format if it is not empty */
for (idx = 0; idx < COUNT_OF(analysis_format_lookup); idx++) {
if (!strcmp(analysis_format_lookup[idx].argument, format)) {
/* Format specifier matches */
fmt = analysis_format_lookup[idx].format;
found = 1;
}
}
if (!found) {
fprintf(stderr, "No format matches %s. Using default.\n", format);
}
}
/* Load the GDS file */
res = parse_gds_from_file(gds_name, &lib_list, &parsing_opts);
if (res) {
fprintf(stderr, "Error parsing GDS file\n");
(void)clear_lib_list(&lib_list);
ret = res;
goto return_val;
}
for (lib_iter = lib_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
res = gds_tree_check_cell_references((struct gds_library *)lib_iter->data);
if (res < 0) {
fprintf(stderr, "Error checking cell references. Will continue...\n");
}
res = gds_tree_check_reference_loops((struct gds_library *)lib_iter->data);
if (res < 0) {
fprintf(stderr, "Error checking cell reference loops. Will continue...\n");
}
}
if (fmt == ANA_FORMAT_CELLS_ONLY) {
print_cell_names(lib_list);
goto return_clear_libs;
}
print_statistics(fmt, lib_list);
return_clear_libs:
clear_lib_list(&lib_list);
return_val:
return ret; return ret;
} }

View File

@ -22,6 +22,5 @@
* @ref EXTERNAL_LIBRARY_RENDER_FUNCTION | int EXTERNAL_LIBRARY_RENDER_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale) | Render cell to output file * @ref EXTERNAL_LIBRARY_RENDER_FUNCTION | int EXTERNAL_LIBRARY_RENDER_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale) | Render cell to output file
* @ref EXTERNAL_LIBRARY_INIT_FUNCTION | int EXTERNAL_LIBRARY_INIT_FUNCTION(const char *option_string, const char *version_string) | Init function. Executed before rendering. This is given the command line parameters specified for the external renderer and the version string of the currently running gds-render program. * @ref EXTERNAL_LIBRARY_INIT_FUNCTION | int EXTERNAL_LIBRARY_INIT_FUNCTION(const char *option_string, const char *version_string) | Init function. Executed before rendering. This is given the command line parameters specified for the external renderer and the version string of the currently running gds-render program.
* @ref EXTERNAL_LIBRARY_FORK_REQUEST | int EXTERNAL_LIBRARY_FORK_REQUEST; | The pure presence of this integer results in the execution inside a subprocess of hte whole shared object's code * @ref EXTERNAL_LIBRARY_FORK_REQUEST | int EXTERNAL_LIBRARY_FORK_REQUEST; | The pure presence of this integer results in the execution inside a subprocess of hte whole shared object's code
* @ref EXTERNAL_LIBRARY_FINALIZE_FUNCTION | int EXTERNAL_LIBRARY_FINALIZE_FUNCTION(void) | Called after rendering
* *
*/ */

View File

@ -37,6 +37,7 @@
#include <gds-render/layer/layer-selector.h> #include <gds-render/layer/layer-selector.h>
#include <gds-render/widgets/activity-bar.h> #include <gds-render/widgets/activity-bar.h>
#include <gds-render/cell-selector/lib-cell-renderer.h> #include <gds-render/cell-selector/lib-cell-renderer.h>
#include <gds-render/cell-selector/cell-statistics-renderer.h>
#include <gds-render/output-renderers/latex-renderer.h> #include <gds-render/output-renderers/latex-renderer.h>
#include <gds-render/output-renderers/cairo-renderer.h> #include <gds-render/output-renderers/cairo-renderer.h>
#include <gds-render/widgets/conv-settings-dialog.h> #include <gds-render/widgets/conv-settings-dialog.h>
@ -48,6 +49,7 @@ enum cell_store_columns {
CELL_SEL_LIBRARY = 0, CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL, CELL_SEL_CELL,
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */ CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
CELL_SEL_STAT,
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */ CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
}; };
@ -187,7 +189,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;
} }
@ -218,10 +221,11 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
{ {
GtkCellRenderer *render_cell; GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib; GtkCellRenderer *render_lib;
GtkCellRenderer *render_vertex_count;
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER,
G_TYPE_POINTER, G_TYPE_UINT); G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER);
/* Searching */ /* Searching */
self->cell_filter = GTK_TREE_MODEL_FILTER( self->cell_filter = GTK_TREE_MODEL_FILTER(
@ -237,6 +241,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
render_cell = lib_cell_renderer_new(); render_cell = lib_cell_renderer_new();
render_lib = lib_cell_renderer_new(); render_lib = lib_cell_renderer_new();
render_vertex_count = cell_statistics_renderer_new();
column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL); column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column); gtk_tree_view_append_column(self->cell_tree_view, column);
@ -245,6 +250,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL); "error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column); gtk_tree_view_append_column(self->cell_tree_view, column);
column = gtk_tree_view_column_new_with_attributes(_("Vertex | GFX Count"), render_vertex_count, "cell-stat", CELL_SEL_STAT,
NULL);
gtk_tree_view_append_column(self->cell_tree_view, column);
/* Callback for selection /* Callback for selection
* This prevents selecting a library * This prevents selecting a library
*/ */
@ -254,6 +263,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
return 0; return 0;
} }
const struct gds_cell_statistics cc = {
.vertex_count = 12,
};
/** /**
* @brief Callback function of Load GDS button * @brief Callback function of Load GDS button
* @param button * @param button
@ -277,6 +290,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 +323,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);
@ -348,6 +365,7 @@ static void on_load_gds(gpointer button, gpointer user)
CELL_SEL_CELL, gds_c, CELL_SEL_CELL, gds_c,
CELL_SEL_CELL_ERROR_STATE, cell_error_level, CELL_SEL_CELL_ERROR_STATE, cell_error_level,
CELL_SEL_LIBRARY, gds_c->parent_library, CELL_SEL_LIBRARY, gds_c->parent_library,
CELL_SEL_STAT, &gds_c->stats,
-1); -1);
} /* for cells */ } /* for cells */
} /* for libraries */ } /* for libraries */
@ -690,19 +708,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 +731,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

@ -43,6 +43,7 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gds-render/gds-utils/gds-parser.h> #include <gds-render/gds-utils/gds-parser.h>
#include <gds-render/gds-utils/gds-statistics.h>
/** /**
* @brief Default units assumed for library. * @brief Default units assumed for library.
@ -50,8 +51,8 @@
*/ */
#define GDS_DEFAULT_UNITS (10E-9) #define GDS_DEFAULT_UNITS (10E-9)
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/ #define GDS_ERROR(fmt, ...) fprintf(stderr, "[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 */ #define GDS_WARN(fmt, ...) fprintf(stderr, "[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
#if GDS_PRINT_DEBUG_INFOS #if GDS_PRINT_DEBUG_INFOS
/**< @brief standard printf. But can be disabled in code. */ /**< @brief standard printf. But can be disabled in code. */
@ -266,7 +267,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,8 +278,15 @@ 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;
} else /* Copy the settings into the library */
memcpy(&lib->parsing_opts, opts, sizeof(struct gds_library_parsing_opts));
lib->stats.cell_count = 0;
lib->stats.gfx_count = 0;
lib->stats.reference_count = 0;
lib->stats.vertex_count = 0;
} else {
return NULL; return NULL;
}
if (library_ptr) if (library_ptr)
*library_ptr = lib; *library_ptr = lib;
@ -353,6 +362,11 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
cell->parent_library = NULL; cell->parent_library = NULL;
cell->checks.unresolved_child_count = GDS_CELL_CHECK_NOT_RUN; cell->checks.unresolved_child_count = GDS_CELL_CHECK_NOT_RUN;
cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN; cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN;
cell->stats.reference_count = 0;
cell->stats.total_vertex_count = 0;
cell->stats.total_gfx_count = 0;
cell->stats.gfx_count = 0;
cell->stats.vertex_count = 0;
} else } else
return NULL; return NULL;
/* return cell */ /* return cell */
@ -488,20 +502,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 +613,16 @@ 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);
}
static void calc_library_stats(gpointer library_list_item, gpointer user)
{
struct gds_library *lib = (struct gds_library *)library_list_item;
(void)user;
GDS_INF("Calculating stats for Library: %s\n", lib->name);
gds_statistics_calc_cummulative_counts_in_lib(lib);
} }
/** /**
@ -601,6 +706,7 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
for (row = 0; row < aref->rows; row++) { for (row = 0; row < aref->rows; row++) {
/* Create new instance for this row/column and configure data */ /* Create new instance for this row/column and configure data */
container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst); container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst);
container_cell->stats.reference_count++;
if (!sref_inst) { if (!sref_inst) {
GDS_ERROR("Appending cell ref failed!"); GDS_ERROR("Appending cell ref failed!");
continue; continue;
@ -617,7 +723,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 +804,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 +878,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) {
@ -781,6 +888,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} }
current_cell->child_cells = append_cell_ref(current_cell->child_cells, current_cell->child_cells = append_cell_ref(current_cell->child_cells,
&current_s_reference); &current_s_reference);
current_cell->stats.reference_count++;
if (current_cell->child_cells == NULL) { if (current_cell->child_cells == NULL) {
GDS_ERROR("Memory allocation failed"); GDS_ERROR("Memory allocation failed");
run = -4; run = -4;
@ -806,8 +914,13 @@ 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_cell) {
current_cell->stats.gfx_count++;
}
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
GDS_INF("\tLeaving Reference\n"); GDS_INF("\tLeaving Reference\n");
@ -825,11 +938,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:
@ -957,7 +1070,9 @@ int parse_gds_from_file(const char *filename, GList **library_list)
current_graphics->vertices = current_graphics->vertices =
append_vertex(current_graphics->vertices, x, y); append_vertex(current_graphics->vertices, x, y);
GDS_INF("\t\tSet coordinate: %d/%d\n", x, y); GDS_INF("\t\tSet coordinate: %d/%d\n", x, y);
if (current_cell) {
current_cell->stats.vertex_count++;
}
} }
} else if (current_a_reference) { } else if (current_a_reference) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -1073,8 +1188,13 @@ int parse_gds_from_file(const char *filename, GList **library_list)
if (!run) { if (!run) {
/* Iterate and find references to cells */ /* Iterate and find references to cells */
g_list_foreach(lib_list, scan_library_references, NULL); g_list_foreach(lib_list, scan_library_references, NULL);
/* Calculate lib stats and cummulative total counts */
g_list_foreach(lib_list, calc_library_stats, NULL);
} }
*library_list = lib_list; *library_list = lib_list;
free(workbuff); free(workbuff);

View File

@ -0,0 +1,93 @@
/*
* 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 gds-statistics.c
* @brief Statistics of GDS files
* @author Mario Hüttel <mario.huettel@gmx.net>
*
*/
#include <gds-render/gds-utils/gds-statistics.h>
#include <stdio.h>
/**
* @addtogroup GDS-Utilities
* @{
*/
#define MAX_RECURSION_DEPTH (1024)
static void calculate_vertex_gfx_count_cell(struct gds_cell *cell, unsigned int recursion_depth)
{
GList *cell_iter;
struct gds_cell_instance *cell_ref;
struct gds_cell *sub_cell;
g_return_if_fail(cell);
/* Check if cell has already been calculated */
if (cell->stats.total_gfx_count && cell->stats.total_vertex_count) {
/* Return. This cell and all of its subcells have been calculated */
return;
}
/* Update with own vertex / GFX count */
cell->stats.total_vertex_count = cell->stats.vertex_count;
cell->stats.total_gfx_count = cell->stats.gfx_count;
/* Do not analyze further, if maximum recursion depth is reached */
if (!recursion_depth)
return;
for (cell_iter = cell->child_cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
/* Scan all subcells recursively, if there are any */
cell_ref = (struct gds_cell_instance *)cell_iter->data;
sub_cell = (struct gds_cell *)cell_ref->cell_ref;
calculate_vertex_gfx_count_cell(sub_cell, recursion_depth - 1);
/* Increment count */
cell->stats.total_vertex_count += sub_cell->stats.total_vertex_count;
cell->stats.total_gfx_count += sub_cell->stats.total_vertex_count;
}
}
void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib)
{
GList *cell_iter;
struct gds_cell *cell;
g_return_if_fail(lib);
for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
cell = (struct gds_cell *)cell_iter->data;
calculate_vertex_gfx_count_cell(cell, MAX_RECURSION_DEPTH);
lib->stats.vertex_count += cell->stats.vertex_count;
lib->stats.cell_count++;
lib->stats.gfx_count += cell->stats.gfx_count;
lib->stats.reference_count += cell->stats.reference_count;
}
}
/** @} */

View File

@ -0,0 +1,56 @@
/*
* GDSII-Converter
* Copyright (C) 2022 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 cell-statistics-renderer.h
* @brief Header file for the CellStatisticsRenderer GObject Class
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup CellStatisticsRenderer
* @{
*/
#ifndef _CELL_STATISTICS_RENDERER_H_
#define _CELL_STATISTICS_RENDERER_H_
#include <gtk/gtk.h>
#include <gds-render/gds-utils/gds-statistics.h>
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GDS_RENDER, CELL_STAT_RENDERER, GtkCellRendererText)
#define TYPE_GDS_RENDER_CELL_STAT_RENDERER (cell_statistics_renderer_get_type())
typedef struct _CellStatisticsRenderer {
GtkCellRendererText super;
} CellStatisticsRenderer;
/**
* @brief New Cell statistics renderer
* @return GObject
*/
GtkCellRenderer *cell_statistics_renderer_new(void);
G_END_DECLS
#endif /* _CELL_STATISTICS_RENDERER_H_ */
/** @} */

View File

@ -71,6 +71,14 @@ int command_line_convert_gds(const char *gds_name,
gboolean tex_layers, gboolean tex_layers,
double scale); double scale);
/**
* @brief Analyze the given GDS file
* @param format Output format of the analysis result
* @param gds_name GDS file name
* @return 0 if successful
*/
int command_line_analyze_lib(const char *format, const char *gds_name);
#endif /* _COMMAND_LINE_H_ */ #endif /* _COMMAND_LINE_H_ */
/** @} */ /** @} */

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

@ -1,6 +1,6 @@
/* /*
* GDSII-Converter Python Plugin * GDSII-Converter
* Copyright (C) 2019 Mario Hüttel <mario.huettel@gmx.net> * Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
* *
* This file is part of GDSII-Converter. * This file is part of GDSII-Converter.
* *
@ -18,20 +18,25 @@
*/ */
/** /**
* @file python-renderer/force-fork.c * @file gds-parser.h
* @brief Header file for the GDS statistics
* @author Mario Hüttel <mario.huettel@gmx.net> * @author Mario Hüttel <mario.huettel@gmx.net>
*/ */
#include <python-renderer/force-fork.h> #ifndef _GDS_STATISTICS_H_
#define _GDS_STATISTICS_H_
/** /**
* @addtogroup python-plugin * @addtogroup GDS-Utilities
* @{ * @{
*/ */
/* The precense of this variable tells the gds-render application to execute this plugin in a separate process #include <glib.h>
* The variable's value is don't care
*/ #include <gds-render/gds-utils/gds-types.h>
const int EXPORTED_VAR_DECL(EXTERNAL_LIBRARY_FORK_REQUEST) = 1;
void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib);
/** @} */ /** @} */
#endif /* _GDS_STATISTICS_H_ */

View File

@ -65,6 +65,22 @@ struct gds_point {
int y; int y;
}; };
struct gds_cell_statistics {
size_t gfx_count;
size_t vertex_count;
size_t total_vertex_count;
size_t total_gfx_count;
size_t reference_count;
};
struct gds_lib_statistics {
size_t gfx_count;
size_t vertex_count;
size_t reference_count;
size_t cell_count;
};
/** /**
* @brief Stores the result of the cell checks. * @brief Stores the result of the cell checks.
*/ */
@ -127,6 +143,14 @@ struct gds_cell {
GList *graphic_objs; /**< @brief List of #gds_graphics */ GList *graphic_objs; /**< @brief List of #gds_graphics */
struct gds_library *parent_library; /**< @brief Pointer to parent library */ struct gds_library *parent_library; /**< @brief Pointer to parent library */
struct gds_cell_checks checks; /**< @brief Checking results */ struct gds_cell_checks checks; /**< @brief Checking results */
struct gds_cell_statistics stats; /**< @brief Optional statistic info */
};
/**
* @brief Options, hwo this liobrary was parsed.
*/
struct gds_library_parsing_opts {
int simplified_polygons; /**< @brief Polygons have been simplified. Coincident end point removed. */
}; };
/** /**
@ -136,11 +160,14 @@ 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 */;
struct gds_lib_statistics stats;
}; };
/** @} */ /** @} */
#endif /* __GDS_TYPES_H__ */ #endif /* __GDS_TYPES_H__ */

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

@ -37,11 +37,6 @@
*/ */
#define EXPORT_FUNC __attribute__((visibility("default"))) #define EXPORT_FUNC __attribute__((visibility("default")))
/**
* @brief This define is used to export a variable symbol from a shared object
*/
#define EXPORT_VAR EXPORT_FUNC
/** /**
* @brief Function name expected to be found in external library for rendering. * @brief Function name expected to be found in external library for rendering.
* *
@ -61,15 +56,6 @@
*/ */
#define EXTERNAL_LIBRARY_INIT_FUNCTION exported_init #define EXTERNAL_LIBRARY_INIT_FUNCTION exported_init
/**
* @brief Function name expected to be found in external library for finalizing.
*
* @code
* int EXTERNAL_LIBRARY_FINALIZE_FUNCTION(void);
* @endcode
*/
#define EXTERNAL_LIBRARY_FINALIZE_FUNCTION exported_finalize
/** /**
* @brief Global integer specified by an external renderer to signal, that the init and render functions shall be executed in a subprocess * @brief Global integer specified by an external renderer to signal, that the init and render functions shall be executed in a subprocess
* *
@ -81,29 +67,10 @@
/** /**
* @brief Define for declaring the exported functions. * @brief Define for declaring the exported functions.
* *
* This not only helps with the declaration but also makes the symbols visible, so they can be called from outside the library * This not only helps with the declaration but also makes the symbols visible, so they can be called form outside the library
*/ */
#define EXPORTED_FUNC_DECL(FUNC) EXPORT_FUNC FUNC #define EXPORTED_FUNC_DECL(FUNC) EXPORT_FUNC FUNC
/**
* @brief Define for declaring exported variables
*
* This not only helps with the declaration but also makes the symbols visible, so they can be accessed from outside the library
*/
#define EXPORTED_VAR_DECL(VAR) EXPORT_VAR VAR
/**
* @brief Define for declaring variables based on a define expansion
* @note If you want to declare an exported variable use @ref EXPORTED_VAR_DECL
*/
#define VAR_DECL(VAR) VAR
/**
* @brief Define for declaring functions based on a define expansion
* @note If you want to declare an exported function use @ref EXPORTED_FUNC_DECL
*/
#define FUNC_DECL(FUNC) FUNC
/** @} */ /** @} */
#endif /* __EXTERNAL_RENDERER_INTERFACES_H__ */ #endif /* __EXTERNAL_RENDERER_INTERFACES_H__ */

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;
}
/** @} */ /** @} */

9
main.c
View File

@ -262,6 +262,8 @@ int main(int argc, char **argv)
gchar *cellname = NULL; gchar *cellname = NULL;
gchar **renderer_args = NULL; gchar **renderer_args = NULL;
gboolean version = FALSE, pdf_standalone = FALSE, pdf_layers = FALSE; gboolean version = FALSE, pdf_standalone = FALSE, pdf_layers = FALSE;
gboolean analyze = FALSE;
gchar *format = NULL;
int scale = 1000; int scale = 1000;
int app_status = 0; int app_status = 0;
struct external_renderer_params so_render_params; struct external_renderer_params so_render_params;
@ -275,6 +277,8 @@ int main(int argc, char **argv)
GOptionEntry entries[] = { GOptionEntry entries[] = {
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, _("Print version"), NULL}, {"version", 'v', 0, G_OPTION_ARG_NONE, &version, _("Print version"), NULL},
{"analyze", 'A', 0, G_OPTION_ARG_NONE, &analyze, _("Anaylze GDS file"), NULL},
{"format", 'f', 0, G_OPTION_ARG_STRING, &format, _("Output format of analysis result, Default simple"), "[simple | pretty | cellsonly]"},
{"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args, {"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args,
_("Renderer to use. Can be used multiple times."), "pdf|svg|tikz|ext"}, _("Renderer to use. Can be used multiple times."), "pdf|svg|tikz|ext"},
{"scale", 's', 0, G_OPTION_ARG_INT, &scale, _("Divide output coordinates by <SCALE>"), "<SCALE>" }, {"scale", 's', 0, G_OPTION_ARG_INT, &scale, _("Divide output coordinates by <SCALE>"), "<SCALE>" },
@ -320,10 +324,13 @@ int main(int argc, char **argv)
for (i = 2; i < argc; i++) for (i = 2; i < argc; i++)
printf(_("Ignored argument: %s"), argv[i]); printf(_("Ignored argument: %s"), argv[i]);
if (analyze) {
app_status = command_line_analyze_lib(format, gds_name);
} else {
app_status = app_status =
command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname, command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
&so_render_params, pdf_standalone, pdf_layers, scale); &so_render_params, pdf_standalone, pdf_layers, scale);
}
} else { } else {
app_status = start_gui(argc, argv); app_status = start_gui(argc, argv);
} }

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

@ -67,7 +67,6 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
{ {
int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL; int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL;
int (*so_init_func)(const char *, const char *) = NULL; int (*so_init_func)(const char *, const char *) = NULL;
int (*so_finalize_func)(void) = NULL;
void *so_handle = NULL; void *so_handle = NULL;
char *error_msg; char *error_msg;
int forking_req; int forking_req;
@ -95,7 +94,7 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double)) so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))
dlsym(so_handle, xstr(EXTERNAL_LIBRARY_RENDER_FUNCTION)); dlsym(so_handle, xstr(EXTERNAL_LIBRARY_RENDER_FUNCTION));
error_msg = dlerror(); error_msg = dlerror();
if (error_msg) { if (error_msg != NULL) {
fprintf(stderr, _("Rendering function not found in library:\n%s\n"), error_msg); fprintf(stderr, _("Rendering function not found in library:\n%s\n"), error_msg);
goto ret_close_so_handle; goto ret_close_so_handle;
} }
@ -103,16 +102,8 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
/* Load the init function */ /* Load the init function */
so_init_func = (int (*)(const char *, const char *))dlsym(so_handle, xstr(EXTERNAL_LIBRARY_INIT_FUNCTION)); so_init_func = (int (*)(const char *, const char *))dlsym(so_handle, xstr(EXTERNAL_LIBRARY_INIT_FUNCTION));
error_msg = dlerror(); error_msg = dlerror();
if (error_msg) { if (error_msg != NULL) {
fprintf(stderr, _("Rendering function not found in library:\n%s\n"), error_msg); fprintf(stderr, _("Init function not found in library:\n%s\n"), error_msg);
goto ret_close_so_handle;
}
/* Load the finalize function */
so_finalize_func = (int (*)(void))dlsym(so_handle, xstr(EXTERNAL_LIBRARY_FINALIZE_FUNCTION));
error_msg = dlerror();
if (error_msg) {
fprintf(stderr, "Finalize function not found in library:\n%s\n", error_msg);
goto ret_close_so_handle; goto ret_close_so_handle;
} }
@ -137,9 +128,6 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
if (!ret) if (!ret)
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale); ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
/* Finalize the external renderer */
ret |= so_finalize_func();
/* If we are in a separate process, terminate here */ /* If we are in a separate process, terminate here */
if (forking_req) if (forking_req)
exit(ret); exit(ret);

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,4 +1,2 @@
add_subdirectory(plugin-example) add_subdirectory(plugin-example)
add_subdirectory(python-renderer) add_custom_target(plugins DEPENDS pluginexample)
add_custom_target(plugins DEPENDS pluginexample pythonrenderer)

View File

@ -1,11 +1,12 @@
project(pluginexample) project(pluginexample)
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(PYTHON REQUIRED python3)
aux_source_directory(src SOURCES) aux_source_directory(src SOURCES)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
link_libraries(version) link_libraries(${PYTHON_LDFLAGS} version)
add_library(${PROJECT_NAME} SHARED EXCLUDE_FROM_ALL ${SOURCES}) add_library(${PROJECT_NAME} SHARED EXCLUDE_FROM_ALL ${SOURCES})
add_dependencies(${PROJECT_NAME} version) add_dependencies(${PROJECT_NAME} version)

View File

@ -25,6 +25,7 @@
* @{ * @{
*/ */
#include <stdio.h> #include <stdio.h>
#include <glib.h> #include <glib.h>
#include <gds-render/gds-utils/gds-types.h> #include <gds-render/gds-utils/gds-types.h>
@ -45,10 +46,4 @@ int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_INIT_FUNCTION)(const char *params, const
return 0; return 0;
} }
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_FINALIZE_FUNCTION)(void)
{
printf("Finalize function called.\n");
return 0;
}
/** @} */ /** @} */

View File

@ -1,34 +0,0 @@
project(pythonrenderer)
cmake_minimum_required(VERSION 2.8.8)
find_package(PythonLibs)
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(ColorBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
aux_source_directory(src SOURCES)
include_directories(${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
link_libraries(${PYTHON_LIBRARIES} version)
message("${BoldCyan}Python version found: ${PYTHONLIBS_VERSION_STRING}${ColorReset}")
add_library(${PROJECT_NAME} SHARED EXCLUDE_FROM_ALL ${SOURCES})
add_dependencies(${PROJECT_NAME} version)

View File

@ -1,43 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2019 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 force-fork.h
* @brief Header file force fork variabel definition.
*
* This file makes the force fork variable accessible.
* Actually this is kind of useless. However, here it is :)
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __PYTHON_PLUGIN_FORCE_FORK_H__
#define __PYTHON_PLUGIN_FORCE_FORK_H__
/**
* @addtogroup python-plugin
* @{
*/
#include <gds-render/output-renderers/external-renderer-interfaces.h>
extern const int VAR_DECL(EXTERNAL_LIBRARY_FORK_REQUEST);
/** @} */
#endif /* __PYTHON_PLUGIN_FORCE_FORK_H__ */

View File

@ -1,49 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2019 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 gds-render-module.h
* @brief Header file for the gds-render python module implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __GDS_RENDER_MODULE_H__
#define __GDS_RENDER_MODULE_H__
/**
* @addtogroup python-renderer
* @{
*/
#include <Python.h>
/**
* @brief The gds_render python module name as string
*/
#define GDS_RENDER_MOD_NAME "gds_render"
/**
* @brief Set up the gds_render python module
* @return New module reference
*/
PyObject *init_gds_render_module();
/** @} */
#endif /* __GDS_RENDER_MODULE_H__ */

View File

@ -1,50 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2020 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 python-renderer/glist.c
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @defgroup python-plugin-glist GList wrapper for python
* @ingroup python-plugin
* This is a wrapping class for GLists
* @addtogroup python-plugin-glist
* @{
*/
#ifndef __GLIST_H__
#define __GLIST_H__
#ifndef PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#endif
#include <Python.h>
#include <glib.h>
extern PyTypeObject GListType;
typedef struct _GListObject GListObject;
void glist_set_head_ptr(GListObject *self, GList *head);
#endif /* __GLIST_H__ */
/** @} */

View File

@ -1,100 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2019 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 gds-render-module.c
* @brief Gds-render python module implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#include <python-renderer/gds-render-module.h>
#include <gds-render/gds-utils/gds-types.h>
#include <python-renderer/glist.h>
static PyObject *test(PyObject *self, PyObject *args)
{
long int i;
if(!PyArg_ParseTuple(args, "l:get_number", &i))
return NULL;
i *= i;
return PyLong_FromLong(i);
}
static PyMethodDef gds_render_methods[] = {
{"get_number", test, METH_VARARGS, "Return the number of arguments received by the process."},
{NULL, NULL, 0, NULL}
};
static PyModuleDef gds_render_module_def = {
PyModuleDef_HEAD_INIT,
.m_name = GDS_RENDER_MOD_NAME,
.m_doc = "GDS Render Base App Module",
.m_size = -1,
.m_methods = gds_render_methods,
NULL, NULL, NULL, NULL
};
static int gds_render_module_check_types_ready()
{
if (!PyType_Ready(&GListType))
return -1;
return 0;
}
static int gds_render_module_add_types(PyObject *module)
{
int err;
Py_INCREF(&GListType);
err = PyModule_AddObject(module, "GdsPoint", (PyObject *)&GListType);
if (err < 0) {
goto decref_glist;
}
return 0;
decref_glist:
Py_DECREF(&GListType);
return -1;
}
PyObject *init_gds_render_module(void)
{
int err;
PyObject *gds_render_module;
if (gds_render_module_check_types_ready())
return NULL;
gds_render_module = PyModule_Create(&gds_render_module_def);
err = gds_render_module_add_types(gds_render_module);
if (err) {
Py_DECREF(gds_render_module);
gds_render_module = NULL;
goto return_module;
}
return_module:
return gds_render_module;
}

View File

@ -1,72 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2020 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 python-renderer/glist.c
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @defgroup python-plugin-glist GList wrapper for python
* @ingroup python-plugin
* This is a wrapping class for GLists
* This wrpper acts as a read only access to the lists
*
* @addtogroup python-plugin-glist
* @{
*/
#include <python-renderer/glist.h>
struct _GListObject {
PyObject_HEAD
GList *head;
size_t len;
};
static PyObject *glist_to_list(GListObject *self, PyObject *Py_UNUSED(ignored))
{
return Py_BuildValue("");
}
static PyMethodDef glist_methods[] = {
{"tolist", (PyCFunction)glist_to_list, METH_NOARGS, "Convert GList to editable list"}
};
void glist_set_head_ptr(GListObject *self, GList *head)
{
if (!self || !head)
return;
self->head = head;
self->len = g_list_length(self->head);
}
PyTypeObject GListType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "gds_render.GList",
.tp_doc = "Read only GList",
.tp_basicsize = sizeof(GListObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = PyType_GenericNew,
.tp_methods = glist_methods
};
/** @} */

View File

@ -1,173 +0,0 @@
/*
* GDSII-Converter Python Plugin
* Copyright (C) 2019 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 python-renderer/plugin-main.c
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @defgroup python-plugin Python Plugin for External Renderer
* @ingroup plugins
* This is a plugin for calling an external python script as renderer
* @addtogroup python-plugin
* @{
*/
#include <stdio.h>
#include <libgen.h>
#include <glib.h>
#include <unistd.h>
#include <Python.h>
#include <gds-render/gds-utils/gds-types.h>
#include <gds-render/output-renderers/external-renderer-interfaces.h>
#include <python-renderer/gds-render-module.h>
/**
* @brief Global variable for loaded module. This is not very nice.
* @warning This has to be changed, if this api wants to be re-entrant.
*/
static PyObject *p_module = NULL;
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_RENDER_FUNCTION)(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale)
{
int ret = 0;
PyObject *p_render_func;
PyObject *p_return_value;
if (!toplevel)
return -1000;
if (!p_module)
return -2000;
printf("Rendering %s\n", toplevel->name);
p_render_func = PyObject_GetAttrString(p_module, "test_func");
if (!p_render_func && !PyCallable_Check(p_render_func)) {
if (PyErr_Occurred())
PyErr_Print();
else
fprintf(stderr, "Function not found in python module\n");
ret = -1;
goto return_value;
}
p_return_value = PyObject_CallObject(p_render_func, NULL);
if (p_return_value) {
printf("Result of call: %ld\n", PyLong_AsLong(p_return_value));
Py_DECREF(p_return_value);
}
Py_XDECREF(p_render_func);
return_value:
return ret;
}
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_INIT_FUNCTION)(const char *params, const char *version)
{
int ret = 0;
PyObject *p_name;
PyObject *p_sys_path;
PyObject *p_mod_dir_string;
PyObject *gds_render_module;
char file_path[PATH_MAX];
char *file_path_for_dir;
char *file_path_for_base;
char *dir_name;
char *base_name;
if (!params || !version)
return -1000;
printf("Init with params: %s\ngds-render version: %s\n", params, version);
ret = PyImport_AppendInittab("gds_render", &init_gds_render_module);
if (ret) {
ret = -1;
fprintf(stderr, "Registration of gds_render python module failed\n");
goto return_value;
}
Py_Initialize();
if (!realpath(params, file_path)) {
ret = -2;
fprintf(stderr, "Invalid file name.\n");
goto return_value;
}
file_path_for_dir = strdup(file_path);
if (!file_path_for_dir) {
ret = -3;
goto return_value;
}
file_path_for_base = strdup(file_path);
if (!file_path_for_base) {
ret = -3;
free (file_path_for_dir);
goto return_value;
}
dir_name = dirname(file_path_for_dir);
base_name = basename(file_path_for_base);
printf("Dir name : %s\n BAse name: %s\n", dir_name, base_name);
p_sys_path = PySys_GetObject("path");
p_mod_dir_string = PyUnicode_FromString(dir_name);
PyList_Append(p_sys_path, p_mod_dir_string);
Py_DECREF(p_mod_dir_string);
p_name = PyUnicode_DecodeFSDefault(strtok(base_name, "."));
p_module = PyImport_Import(p_name);
Py_DECREF(p_name);
if (!p_module) {
PyErr_Print();
fprintf(stderr, "Failed to load %s\n", params);
ret = -1;
goto return_value;
}
free(file_path_for_dir);
free(file_path_for_base);
return_value:
return ret;
}
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_FINALIZE_FUNCTION)(void)
{
int ret;
printf("Finalizing\n");
if (p_module)
Py_DECREF(p_module);
ret = Py_FinalizeEx();
return ret;
}
/** @} */

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>