Compare commits

..

51 Commits

Author SHA1 Message Date
b959f8282a Add Glist wrapper to python renderer 2020-07-04 00:44:46 +02:00
22efe4f8ca Merge branch 'dev' into python-renderer 2020-07-04 00:00:16 +02:00
391789b812 Merge branch 'master' into python-renderer 2020-04-24 01:07:25 +02:00
98483da759 Merge branch 'dev' into python-renderer 2020-04-24 01:06:23 +02:00
aafcb162b7 Merge branch 'dev' into python-renderer 2020-04-24 01:03:05 +02:00
1fac7d7721 Merge branch 'dev' into python-renderer 2020-04-19 03:00:22 +02:00
b30aaa4c4e Merge branch 'dev' into python-renderer 2020-04-19 00:52:22 +02:00
fb6e3a29af Merge branch 'dev' into python-renderer 2020-04-19 00:41:08 +02:00
f03dd0ab19 Add log message to finalize function of example renderer 2020-04-18 03:30:44 +02:00
b6a2f29a2f Merge branch 'dev' into python-renderer 2020-04-16 22:48:05 +02:00
921b55b962 Merge branch 'master' into python-renderer 2020-04-03 20:55:46 +02:00
4d3f0ccb94 Merge branch 'master' into python-renderer 2020-04-02 00:48:15 +02:00
7526597251 Merge branch 'master' into python-renderer 2020-02-10 23:06:40 +01:00
1278af202a Merge branch 'dev' into python-renderer 2019-12-12 20:56:00 +01:00
b63da7bf09 Merge branch 'dev' into python-renderer 2019-12-07 19:08:05 +01:00
23ba7c0136 Fix typo 2019-11-28 18:24:26 +01:00
7721a40912 Merge branch 'dev' into python-renderer 2019-11-28 17:59:22 +01:00
7297800a99 Merge branch 'dev' into python-renderer 2019-11-25 20:57:17 +01:00
943007685c Merge branch 'dev' into python-renderer 2019-11-19 01:34:12 +01:00
7d6faf8db7 Merge branch 'dev' into python-renderer 2019-11-18 22:31:06 +01:00
9eed1ac33d Add header for foced fork variable. Don't know what it is good for yet. But why not... 2019-11-18 22:20:18 +01:00
246695610c plugins: python renderer: Fix broken code due to merge. Functions of plugins now have to be exported explicitly. 2019-11-18 22:07:58 +01:00
bd4d91807b Merge branch 'dev' into python-renderer 2019-11-18 22:00:45 +01:00
2aa1fffa8e plugins: python renderer: Add fork request to python renderer library, so it wont destory the base application 2019-11-18 21:43:49 +01:00
447d583103 plugins: python renderer: Add color output to cmake 2019-11-18 21:29:42 +01:00
394efb79cf Merge branch 'python-renderer' of git.shimatta.de:mhu/gds-render into python-renderer 2019-11-18 20:29:01 +01:00
2420b80c9e plugins: python renderer: Add GdsPoint object type definition to gds_render module. This is still playing around as I don't really know what I'm doing at the moment. 2019-11-18 20:28:43 +01:00
02f221b926 Merge branch 'master' into python-renderer 2019-11-17 22:32:01 +01:00
dd2f21c5cd Fix remaining licence headers 2019-11-17 17:30:08 +01:00
b27676e0a4 plugins: python renderer: Make python scripts work from all directories 2019-11-17 17:12:15 +01:00
b610b1593a Fix author in doxygen tag 2019-11-17 16:25:03 +01:00
95f6b31e4b python renderer: Try out function parameters 2019-11-17 16:18:03 +01:00
a4d84cff43 Fix license header 2019-11-17 15:52:28 +01:00
aa7f5b4745 plugins: python-renderer: Implement first gds_render built-in module with a get_number function 2019-11-17 15:42:17 +01:00
71b500e030 Merge branch 'dev' into python-renderer 2019-11-17 14:49:13 +01:00
d69d4f3f7e plugins: python-renderer: Add gds-render-module 2019-11-17 14:44:21 +01:00
a60fe6543e plugins: python-renderer: Remove unneeded file exists function 2019-11-17 14:15:35 +01:00
dc32499ad7 plugins: python-renderer: Fix missing closing bracket in doxygen group 2019-11-17 14:13:43 +01:00
322439145e plugins: python-renderer: Add license and doxygen 2019-11-17 14:13:06 +01:00
231248e404 Remove empty line 2019-11-17 14:11:16 +01:00
88d912f59d Merge branch 'dev' into python-renderer 2019-11-17 14:10:55 +01:00
f454ca7e71 Merge branch 'dev' into python-renderer 2019-11-17 01:52:17 +01:00
045b9dce30 plugins: python renderer: Dereference function after calling 2019-11-17 01:13:49 +01:00
112a5ac74c plugins: python renderer: Implement first draft that loads a python module and calls a test function. This will be changed later 2019-11-17 00:53:24 +01:00
6b5101ecec plugins: python renderer: Load module 2019-11-17 00:02:42 +01:00
583e5581c0 Find python path correctly 2019-11-17 00:01:55 +01:00
519d2296ad Add more error handling to command line interface to handle empty layer mapping spec 2019-11-16 23:42:48 +01:00
02720ec37b plugins: python-renderer: add finalize function 2019-11-16 22:53:10 +01:00
cf2947d2d5 Add finalize function as exported function to external renderer and use it in the main app after rendering 2019-11-16 22:44:41 +01:00
c7ceef7d66 Merge branch 'dev' into python-renderer 2019-11-16 16:03:05 +01:00
ebce4a2669 Add python renderer to plugins 2019-11-16 14:54:58 +01:00
64 changed files with 864 additions and 1037 deletions

View File

@ -1,40 +0,0 @@
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,7 +2,3 @@
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

@ -1 +0,0 @@
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" "https://git.shimatta.de/3rd-party/libfort.git") source=("${pkgname}-git"::"git+https://git.shimatta.de/mhu/gds-render.git")
sha1sums=('SKIP' 'SKIP') sha1sums=('SKIP')
pkgver () { pkgver () {
_date=`date +"%Y%m%d"` _date=`date +"%Y%m%d"`
@ -26,13 +26,6 @@ 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 LANGUAGES C) project(gds-render)
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("Global locale directory used. Make sure files in /usr/share/locale are available") message("${BoldCyan}Global locale directory used. Make sure files in /usr/share/locale are available${ColorReset}")
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,9 +77,6 @@ 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})
@ -93,5 +90,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} fort) target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})

View File

@ -1,7 +1,5 @@
# 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

@ -1,106 +0,0 @@
/*
* 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,7 +30,6 @@
#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>
@ -39,41 +38,6 @@
#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)
{ {
@ -182,6 +146,7 @@ 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;
@ -191,10 +156,6 @@ 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"));
@ -203,7 +164,14 @@ 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();
layer_settings_load_from_csv(layer_sett, layer_file); if (!layer_sett)
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,
@ -213,7 +181,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, &gds_parsing_options); res = parse_gds_from_file(gds_name, &libs);
if (res) if (res)
goto ret_destroy_library_list; goto ret_destroy_library_list;
@ -261,11 +229,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);
gds_output_renderer_render_output(current_renderer, toplevel_cell, scale); render_ret = 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:
@ -273,194 +241,7 @@ 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 ret; return_value:
}
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,5 +22,6 @@
* @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,7 +37,6 @@
#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>
@ -49,7 +48,6 @@ 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 */
}; };
@ -189,8 +187,7 @@ 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);
/* Show always, if this is a pure lib entry */ if (lib) {
if (lib && !cell) {
result = TRUE; result = TRUE;
goto exit_filter; goto exit_filter;
} }
@ -221,11 +218,10 @@ 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_POINTER, G_TYPE_UINT);
/* Searching */ /* Searching */
self->cell_filter = GTK_TREE_MODEL_FILTER( self->cell_filter = GTK_TREE_MODEL_FILTER(
@ -241,7 +237,6 @@ 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);
@ -250,10 +245,6 @@ 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
*/ */
@ -263,10 +254,6 @@ 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
@ -290,10 +277,6 @@ 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;
@ -323,7 +306,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_parsing_options); gds_result = parse_gds_from_file(filename, &self->gds_libraries);
/* Delete file name afterwards */ /* Delete file name afterwards */
g_free(filename); g_free(filename);
@ -365,7 +348,6 @@ 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 */
@ -708,13 +690,19 @@ 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 gboolean auto_naming_ask_for_override(GdsRenderGui *gui) static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
{ {
GdsRenderGui *gui;
GtkDialog *dialog; GtkDialog *dialog;
gint dialog_result; gboolean overwrite;
gboolean overwrite = FALSE; int dialog_result;
(void)button;
g_return_val_if_fail(RENDERER_IS_GUI(gui), FALSE); gui = RENDERER_GUI(user_data);
/* 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,
@ -731,25 +719,6 @@ static gboolean auto_naming_ask_for_override(GdsRenderGui *gui)
} }
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,7 +43,6 @@
#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.
@ -51,8 +50,8 @@
*/ */
#define GDS_DEFAULT_UNITS (10E-9) #define GDS_DEFAULT_UNITS (10E-9)
#define GDS_ERROR(fmt, ...) fprintf(stderr, "[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/ #define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/
#define GDS_WARN(fmt, ...) fprintf(stderr, "[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */ #define GDS_WARN(fmt, ...) printf("[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. */
@ -267,8 +266,7 @@ 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, const struct gds_library_parsing_opts *opts, static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
struct gds_library **library_ptr)
{ {
struct gds_library *lib; struct gds_library *lib;
@ -278,15 +276,8 @@ static GList *append_library(GList *curr_list, const struct gds_library_parsing_
lib->name[0] = 0; lib->name[0] = 0;
lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten
lib->cell_names = NULL; lib->cell_names = NULL;
/* Copy the settings into the library */ } else
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;
@ -362,11 +353,6 @@ 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 */
@ -502,102 +488,20 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
} }
/** /**
* @brief Simplify graphics objects * @brief Scans cell references inside cell
* @param graphics gfx struct This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance
* @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_references_and_polygons(gpointer gcell, gpointer library) static void scan_cell_reference_dependencies(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);
}
} }
/** /**
@ -613,16 +517,7 @@ static void scan_library_references(gpointer library_list_item, gpointer user)
(void)user; (void)user;
GDS_INF("Scanning Library: %s\n", lib->name); GDS_INF("Scanning Library: %s\n", lib->name);
g_list_foreach(lib->cells, scan_cell_references_and_polygons, lib); g_list_foreach(lib->cells, scan_cell_reference_dependencies, 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);
} }
/** /**
@ -706,7 +601,6 @@ 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;
@ -723,8 +617,7 @@ 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;
@ -804,7 +697,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, parsing_options, &current_lib); lib_list = append_library(lib_list, &current_lib);
if (lib_list == NULL) { if (lib_list == NULL) {
GDS_ERROR("Allocating memory failed"); GDS_ERROR("Allocating memory failed");
run = -3; run = -3;
@ -878,7 +771,7 @@ int parse_gds_from_file(const char *filename, GList **library_list,
run = -4; run = -4;
break; break;
} }
GDS_INF("\tEntering boundary of type %s\n", rec_type==BOUNDARY ? "polygon" : "box"); GDS_INF("\tEntering boundary/Box\n");
break; break;
case SREF: case SREF:
if (current_cell == NULL) { if (current_cell == NULL) {
@ -888,7 +781,6 @@ 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;
@ -914,13 +806,8 @@ 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" GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path"));
: (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");
@ -938,11 +825,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 wrong!"); GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!");
} }
} 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 wrong!"); GDS_WARN("Array instance has weird coordinates. Rendered output might be screwed!");
} }
break; break;
case AREF: case AREF:
@ -1070,9 +957,7 @@ 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++) {
@ -1188,13 +1073,8 @@ 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

@ -1,93 +0,0 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file 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

@ -1,56 +0,0 @@
/*
* 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,14 +71,6 @@ 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,11 +48,9 @@
* *
* @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

@ -65,22 +65,6 @@ 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.
*/ */
@ -143,14 +127,6 @@ 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. */
}; };
/** /**
@ -160,14 +136,11 @@ 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,13 +130,6 @@ 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 (5000) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/ #define MAX_LAYERS (300) /**< \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,6 +37,11 @@
*/ */
#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.
* *
@ -56,6 +61,15 @@
*/ */
#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
* *
@ -67,10 +81,29 @@
/** /**
* @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 form outside the library * This not only helps with the declaration but also makes the symbols visible, so they can be called from 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,7 +238,6 @@ 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,10 +822,12 @@ void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalett
unsigned int color_count; unsigned int color_count;
GdkRGBA color; GdkRGBA color;
g_return_if_fail(GDS_RENDER_IS_COLOR_PALETTE(palette)); if (GDS_RENDER_IS_COLOR_PALETTE(palette) == FALSE || LAYER_IS_SELECTOR(layer_selector) == FALSE)
g_return_if_fail(LAYER_IS_SELECTOR(layer_selector)); return;
g_return_if_fail(global_alpha > 0); if (global_alpha <= 0)
g_return_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box)); return;
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));
@ -896,31 +898,4 @@ 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,8 +262,6 @@ 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;
@ -277,8 +275,6 @@ 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>" },
@ -324,13 +320,10 @@ 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,6 +371,8 @@ 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;
@ -379,8 +381,6 @@ 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,6 +67,7 @@ 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;
@ -94,7 +95,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 != NULL) { if (error_msg) {
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;
} }
@ -102,8 +103,16 @@ 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 != NULL) { if (error_msg) {
fprintf(stderr, _("Init 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;
}
/* 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;
} }
@ -128,6 +137,9 @@ 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_warning(_("Could not open LaTeX output file")); g_error(_("Could not open LaTeX output file"));
} }
if (settings) if (settings)

View File

@ -1,2 +1,4 @@
add_subdirectory(plugin-example) add_subdirectory(plugin-example)
add_custom_target(plugins DEPENDS pluginexample) add_subdirectory(python-renderer)
add_custom_target(plugins DEPENDS pluginexample pythonrenderer)

View File

@ -1,12 +1,11 @@
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(${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
link_libraries(${PYTHON_LDFLAGS} version) link_libraries(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,7 +25,6 @@
* @{ * @{
*/ */
#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>
@ -46,4 +45,10 @@ 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

@ -0,0 +1,34 @@
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

@ -0,0 +1,43 @@
/*
* 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

@ -0,0 +1,49 @@
/*
* 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

@ -0,0 +1,50 @@
/*
* 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,6 +1,6 @@
/* /*
* GDSII-Converter * GDSII-Converter Python Plugin
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net> * Copyright (C) 2019 Mario Hüttel <mario.huettel@gmx.net>
* *
* This file is part of GDSII-Converter. * This file is part of GDSII-Converter.
* *
@ -18,25 +18,20 @@
*/ */
/** /**
* @file gds-parser.h * @file python-renderer/force-fork.c
* @brief Header file for the GDS statistics
* @author Mario Hüttel <mario.huettel@gmx.net> * @author Mario Hüttel <mario.huettel@gmx.net>
*/ */
#ifndef _GDS_STATISTICS_H_ #include <python-renderer/force-fork.h>
#define _GDS_STATISTICS_H_
/** /**
* @addtogroup GDS-Utilities * @addtogroup python-plugin
* @{ * @{
*/ */
#include <glib.h> /* The precense of this variable tells the gds-render application to execute this plugin in a separate process
* 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

@ -0,0 +1,100 @@
/*
* 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

@ -0,0 +1,72 @@
/*
* 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

@ -0,0 +1,173 @@
/*
* 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.38.2 --> <!-- Generated with glade 3.22.1 -->
<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.10</property> <property name="page_increment">0.10000000000000001</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="icon-name">open-menu-symbolic</property> <property name="stock">gtk-justify-fill</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,57 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 --> <!-- Generated with glade 3.22.1 -->
<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="icon-name">format-text-rich-symbolic</property> <property name="stock">gtk-edit</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="icon-name">color-select-symbolic</property> <property name="stock">gtk-select-color</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="icon-name">emblem-ok-symbolic</property> <property name="stock">gtk-apply</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="icon-name">view-sort-descending-symbolic</property> <property name="stock">gtk-sort-ascending</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="icon-name">view-sort-ascending-symbolic</property> <property name="stock">gtk-sort-descending</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>
@ -62,15 +150,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>
@ -93,20 +181,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>
@ -117,11 +205,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>
@ -132,11 +220,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>
@ -147,11 +235,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>
@ -162,11 +250,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>
@ -184,19 +272,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>
@ -225,7 +313,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/>
@ -239,75 +327,5 @@
</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>