Compare commits

..

46 Commits

Author SHA1 Message Date
504dc476b1 Fix recursive clone in github actions 2022-12-17 19:00:16 +01:00
8ff872cf36 Fix recursive clone in github actions 2022-12-17 18:57:19 +01:00
9c4dbd51c8 Merge branch 'dev' 2022-12-17 18:52:05 +01:00
2829143bbe Merge pull request 'Fix #49: Initialize variable' (#50) from fix-issue-49 into dev
Reviewed-on: #50
2022-12-17 18:43:56 +01:00
5185097075 Fix #49: Initialize variable 2022-12-17 18:43:10 +01:00
573cd59892 Merge branch 'dev' 2022-04-17 22:21:38 +02:00
8b1f667819 Merge pull request 'issue/47-add-vertex-count-to-gui' (#48) from issue/47-add-vertex-count-to-gui into dev
Reviewed-on: #48
2022-04-17 20:09:47 +02:00
c2ca2ff573 Rework the analysis cmd option to work with new statistics functions 2022-04-17 20:07:57 +02:00
c0ac6cc3c5 Move statistic calculation to parser. Show Vertex and GFX count in GUI. CLI -A param is now broken. Will implement in next commits. 2022-04-17 18:37:32 +02:00
22bc3a18d7 Issue #47: Add renderer for cell statistics and render dummy value 2022-04-17 17:40:18 +02:00
dbc9fcdf34 Issue #47: AddVertex count column to tree view 2022-04-17 16:54:57 +02:00
b39030aeaa Fix PKGBUILD 2022-04-17 00:47:41 +02:00
2f59a762cd Fix PKGBUILD 2022-04-17 00:46:51 +02:00
ab26f8a2af Fix PKGBUILD 2022-04-17 00:45:49 +02:00
9a43cd53f8 Update PKGBUILD 2022-04-17 00:38:50 +02:00
ba6b07c8a2 Implement cell statistics command line interface 2022-04-17 00:37:26 +02:00
1548c82542 Add libfort for pretty console tables 2022-04-16 16:13:22 +02:00
fb6d31c120 Fix stuck at -1 return value when executing command line interface 2022-04-16 16:00:50 +02:00
f6c65d9c7a Merge branch 'dev' 2022-04-10 15:35:14 +02:00
d43bec2cea Merge pull request 'issue/44-remove-duplicate-vertices' (#45) from issue/44-remove-duplicate-vertices into dev
Reviewed-on: #45
2022-04-10 15:33:41 +02:00
05a1ef9014 Disable debug output of parser. 2022-04-10 15:31:55 +02:00
a36b78b237 Add vertex simplification to parser
* Duplicate / Redundant vertices of polygons are now removed during parsing.
* Implications: Reduced output size of tex document, faster rendering.
2022-04-10 15:28:23 +02:00
ac87cafa37 Merge pull request 'Merge new features and minor fixes for v1.2.1 release' (#43) from dev into master
Reviewed-on: #43
2022-04-09 20:39:09 +02:00
091729841a Merge branch 'master' into dev 2022-04-09 20:39:07 +02:00
28368e8a32 Cairo Renderer: Only print notification that layer is rendered, if it is actually rendered 2022-04-09 20:36:49 +02:00
2b3cc8222a Merge pull request 'Change icons to new Adwaita icons' (#42) from update-icons into dev
Reviewed-on: #42
2022-04-09 20:15:26 +02:00
c23150b819 Merge branch 'dev' into update-icons 2022-04-09 20:15:01 +02:00
049e6c2a4c Merge pull request 'Improve some features' (#41) from improve-features into dev
Reviewed-on: #41
2022-04-09 20:13:47 +02:00
600e10e4d5 Increase layer count of Cairo renderer as this turned out to be too low for some semiconductor technologies 2022-04-09 20:10:11 +02:00
238f2cea82 Improve Autonaming in GUI
Autonaming now only asks for overwrite confirmation, if there
are layers with non empty names. Otherwise, the dialog is not shown.
2022-04-09 20:08:24 +02:00
91706ccf2e Change icons to new Adwaita icons 2022-04-09 19:40:39 +02:00
17e7239e54 Merge branch 'dev' 2022-02-11 21:57:10 +01:00
554b73c406 Fix hard crash in case of a unwritable Latex Output file. Print warnign instead of hard stop 2022-02-11 21:56:54 +01:00
4eebff04a4
Update README.MD
Add github status badge for CI
2021-10-01 23:46:32 +02:00
04525611fa
Update cmake.yml
Add gettext to dependencies
2021-10-01 23:43:37 +02:00
cb92d64ec3
Update cmake.yml 2021-10-01 23:41:40 +02:00
37ff2080f9
Create cmake.yml 2021-10-01 23:35:16 +02:00
e1b85d1a99 Merge branch 'issue/39-fix-search' of mhu/gds-render into dev 2020-11-26 23:08:55 +01:00
b0c9afdae5 Fix #39: Checking of pure library entry in cell selector was broken 2020-11-26 23:07:48 +01:00
f6abfada2c ColorPalette: Fix Dispose function
* Set freed pointer to NULL in dispose function because dispose cna be run multiple times. This fixes the case of freeing an already freed pointer.
2020-07-09 23:54:40 +02:00
f135b42d8a make clear we're not getting a return value from vector_2d_copy 2020-06-29 20:03:38 +02:00
058564326b Update library and compiler versions in doxygen 2020-04-24 01:17:20 +02:00
fd1eac7fda Merge branch 'master' into dev 2020-04-24 01:07:50 +02:00
2c91956b32 Doxygen: Update calculate_cell_bounding_box()
* Fix typo
* Extend description
2020-04-24 01:05:37 +02:00
232d025211 Doxygen: Update calculate_cell_bounding_box()
* Add note about problematic behaviour
* Fix typos
2020-04-24 01:02:10 +02:00
e461b0be1d Merge branch 'dev' 2020-04-19 00:52:42 +02:00
34 changed files with 1029 additions and 742 deletions

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

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

4
.gitmodules vendored
View File

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

1
3rdparty/libfort vendored Submodule

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

View File

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

View File

@ -1,4 +1,4 @@
project(gds-render) project(gds-render LANGUAGES C)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE) set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE)
@ -77,6 +77,9 @@ add_subdirectory(resources)
add_subdirectory(doxygen) add_subdirectory(doxygen)
add_subdirectory(translations) add_subdirectory(translations)
add_subdirectory(version) add_subdirectory(version)
set(FORT_ENABLE_TESTING OFF CACHE INTERNAL "")
add_subdirectory(3rdparty/libfort)
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS}) link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER}) add_definitions(${GLIB2_CFLAGS_OTHER})
@ -90,5 +93,5 @@ install (TARGETS ${PROJECT_NAME}
RUNTIME RUNTIME
DESTINATION bin DESTINATION bin
) )
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS}) target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS} fort)

View File

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

View File

@ -0,0 +1,106 @@
/*
* GDSII-Converter
* Copyright (C) 2022 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file cell-statistics-renderer.c
* @brief CellStatisticsRenderer GObject Class
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup CellStatisticsRenderer
* @{
*/
#include <gds-render/cell-selector/cell-statistics-renderer.h>
G_DEFINE_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GTK_TYPE_CELL_RENDERER_TEXT)
enum {
PROP_CELL_STAT = 1,
PROP_COUNT
};
static void cell_statistics_renderer_set_property(GObject *object,
guint param_id,
const GValue *value,
GParamSpec *pspec)
{
GValue val = G_VALUE_INIT;
GString *string;
const struct gds_cell_statistics *cell_stat;
switch (param_id) {
case PROP_CELL_STAT:
cell_stat = (const struct gds_cell_statistics *)g_value_get_pointer(value);
g_value_init(&val, G_TYPE_STRING);
string = g_string_new_len("", 5);
if (cell_stat)
g_string_printf(string, "%zu (%zu) | %zu (%zu)", cell_stat->total_vertex_count,
cell_stat->vertex_count, cell_stat->total_gfx_count, cell_stat->gfx_count);
g_value_set_string(&val, string->str);
g_object_set_property(object, "text", &val);
g_value_unset(&val);
g_string_free(string, TRUE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static void cell_statistics_renderer_get_property(GObject *object,
guint param_id,
GValue *value,
GParamSpec *pspec)
{
(void)value;
switch (param_id) {
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
break;
}
}
static GParamSpec *properties[PROP_COUNT];
void cell_statistics_renderer_class_init(CellStatisticsRendererClass *klass)
{
GObjectClass *oclass = G_OBJECT_CLASS(klass);
oclass->set_property = cell_statistics_renderer_set_property;
oclass->get_property = cell_statistics_renderer_get_property;
properties[PROP_CELL_STAT] = g_param_spec_pointer("cell-stat", "cell-stat",
"Cell statistics", G_PARAM_WRITABLE);
g_object_class_install_properties(oclass, PROP_COUNT, properties);
}
void cell_statistics_renderer_init(CellStatisticsRenderer *self)
{
(void)self;
}
GtkCellRenderer *cell_statistics_renderer_new(void)
{
return GTK_CELL_RENDERER(g_object_new(TYPE_GDS_RENDER_CELL_STAT_RENDERER, NULL));
}
/** @} */

View File

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <string.h>
#include <gds-render/command-line.h> #include <gds-render/command-line.h>
#include <gds-render/gds-utils/gds-parser.h> #include <gds-render/gds-utils/gds-parser.h>
@ -38,6 +39,41 @@
#include <gds-render/output-renderers/latex-renderer.h> #include <gds-render/output-renderers/latex-renderer.h>
#include <gds-render/output-renderers/external-renderer.h> #include <gds-render/output-renderers/external-renderer.h>
#include <gds-render/gds-utils/gds-tree-checker.h> #include <gds-render/gds-utils/gds-tree-checker.h>
#include <gds-render/gds-utils/gds-statistics.h>
#include <fort.h>
#ifndef COUNT_OF
#define COUNT_OF(x) (sizeof((x))/sizeof(0[(x)]))
#endif
enum analysis_format {
ANA_FORMAT_SIMPLE = 0,
ANA_FORMAT_CELLS_ONLY,
ANA_FORMAT_PRETTY,
};
struct analysis_format_cmdarg {
enum analysis_format format;
const char *argument;
};
static const struct analysis_format_cmdarg analysis_format_lookup[] = {
{
.format = ANA_FORMAT_SIMPLE,
.argument = "simple",
},
{
.format = ANA_FORMAT_PRETTY,
.argument = "pretty",
},
{
.format = ANA_FORMAT_CELLS_ONLY,
.argument = "cellsonly"
}
};
static int string_array_count(char **string_array) static int string_array_count(char **string_array)
{ {
@ -136,14 +172,14 @@ static struct gds_cell *find_gds_cell_in_lib(struct gds_library *lib, const char
} }
int command_line_convert_gds(const char *gds_name, int command_line_convert_gds(const char *gds_name,
const char *cell_name, const char *cell_name,
char **renderers, char **renderers,
char **output_file_names, char **output_file_names,
const char *layer_file, const char *layer_file,
struct external_renderer_params *ext_param, struct external_renderer_params *ext_param,
gboolean tex_standalone, gboolean tex_standalone,
gboolean tex_layers, gboolean tex_layers,
double scale) double scale)
{ {
int ret = -1; int ret = -1;
GList *libs = NULL; GList *libs = NULL;
@ -155,6 +191,10 @@ int command_line_convert_gds(const char *gds_name,
LayerSettings *layer_sett; LayerSettings *layer_sett;
GdsOutputRenderer *current_renderer; GdsOutputRenderer *current_renderer;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
/* Check if parameters are valid */ /* Check if parameters are valid */
if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) { if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) {
printf(_("Probably missing argument. Check --help option\n")); printf(_("Probably missing argument. Check --help option\n"));
@ -173,7 +213,7 @@ int command_line_convert_gds(const char *gds_name,
/* Load GDS */ /* Load GDS */
clear_lib_list(&libs); clear_lib_list(&libs);
res = parse_gds_from_file(gds_name, &libs); res = parse_gds_from_file(gds_name, &libs, &gds_parsing_options);
if (res) if (res)
goto ret_destroy_library_list; goto ret_destroy_library_list;
@ -224,6 +264,8 @@ int command_line_convert_gds(const char *gds_name,
gds_output_renderer_render_output(current_renderer, toplevel_cell, scale); gds_output_renderer_render_output(current_renderer, toplevel_cell, scale);
} }
ret = 0;
ret_destroy_library_list: ret_destroy_library_list:
clear_lib_list(&libs); clear_lib_list(&libs);
ret_clear_renderers: ret_clear_renderers:
@ -234,4 +276,192 @@ ret_destroy_layer_mapping:
return ret; return ret;
} }
static void indent_line(int level)
{
while (level--)
printf("\t");
}
static int printf_indented(int level, const char *format, ...)
{
int ret;
va_list a_list;
va_start(a_list, format);
indent_line(level);
ret = vprintf(format, a_list);
va_end(a_list);
return ret;
}
static void print_simple_stat(GList *lib_stat_list)
{
int indentation_level = 0;
GList *lib_iter;
GList *cell_iter;
const struct gds_library *lib;
const struct gds_cell *cell;
const struct gds_lib_statistics *lib_stat;
const struct gds_cell_statistics *cell_stat;
for (lib_iter = lib_stat_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
lib = (const struct gds_library *)lib_iter->data;
lib_stat = &lib->stats;
printf_indented(indentation_level, "Library %s\n", lib->name);
indentation_level++;
for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
cell = (const struct gds_cell *)cell_iter->data;
cell_stat = &cell->stats;
printf_indented(indentation_level, "Cell %s\n", cell->name);
indentation_level++;
printf_indented(indentation_level, "Reference count: %zu\n", cell_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", cell_stat->gfx_count);
printf_indented(indentation_level, "Total Graphics count: %zu\n", cell_stat->total_gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", cell_stat->vertex_count);
printf_indented(indentation_level, "Total Vertex count: %zu\n", cell_stat->total_vertex_count);
printf_indented(indentation_level, "Unresolved children: %d\n",
cell->checks.unresolved_child_count);
printf_indented(indentation_level, "Reference loop: %s\n",
cell->checks.affected_by_reference_loop ? "yes" : "no");
indentation_level--;
}
printf_indented(indentation_level, "Cell count: %zu\n", lib_stat->cell_count);
printf_indented(indentation_level, "Reference count: %zu\n", lib_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", lib_stat->gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", lib_stat->vertex_count);
}
}
static void table_stat_create_cell_row(struct gds_cell *cell, ft_table_t *tab)
{
ft_printf_ln(tab, "%s|%s|%zu|%zu|%zu|%zu|%zu|%d|%s",
cell->parent_library->name,
cell->name,
cell->stats.gfx_count,
cell->stats.total_gfx_count,
cell->stats.vertex_count,
cell->stats.total_vertex_count,
cell->stats.reference_count,
cell->checks.unresolved_child_count,
cell->checks.affected_by_reference_loop ? "yes" : "no");
}
static void table_stat_table_for_lib(struct gds_library *lib, ft_table_t *tab)
{
ft_printf_ln(tab, "%s|%zu|%zu|-|%zu|-|%zu|-|-",
lib->name,
lib->stats.cell_count,
lib->stats.gfx_count,
lib->stats.vertex_count,
lib->stats.reference_count);
g_list_foreach(lib->cells, (GFunc)table_stat_create_cell_row, tab);
}
static void print_table_stat(GList *lib_list)
{
ft_table_t *table;
table = ft_create_table();
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
ft_write_ln(table, "Library", "Cell", "GFX", "GFX+", "Vertices", "Vertices+", "Refs", "Unresolved Refs", "Loops");
g_list_foreach(lib_list, (GFunc)table_stat_table_for_lib, table);
printf("%s\n", ft_to_string(table));
ft_destroy_table(table);
}
static void print_statistics(enum analysis_format format, GList *lib_list)
{
switch (format) {
case ANA_FORMAT_PRETTY:
print_table_stat(lib_list);
break;
default:
print_simple_stat(lib_list);
break;
}
}
static void print_cell_names(GList *lib_list)
{
GList *lib_iter;
GList *name_iter;
struct gds_library *lib;
for (lib_iter = lib_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
lib = (struct gds_library *)lib_iter->data;
for (name_iter = lib->cell_names; name_iter; name_iter = name_iter->next) {
printf("%s\n", (const char *)name_iter->data);
}
}
}
int command_line_analyze_lib(const char *format, const char *gds_name)
{
enum analysis_format fmt = ANA_FORMAT_SIMPLE;
size_t idx;
int found = 0;
GList *lib_list = NULL;
const struct gds_library_parsing_opts parsing_opts = {
.simplified_polygons = 0,
};
int res;
int ret = 0;
GList *lib_iter;
g_return_val_if_fail(gds_name, -1002);
if (format && *format) {
/* Check format if it is not empty */
for (idx = 0; idx < COUNT_OF(analysis_format_lookup); idx++) {
if (!strcmp(analysis_format_lookup[idx].argument, format)) {
/* Format specifier matches */
fmt = analysis_format_lookup[idx].format;
found = 1;
}
}
if (!found) {
fprintf(stderr, "No format matches %s. Using default.\n", format);
}
}
/* Load the GDS file */
res = parse_gds_from_file(gds_name, &lib_list, &parsing_opts);
if (res) {
fprintf(stderr, "Error parsing GDS file\n");
(void)clear_lib_list(&lib_list);
ret = res;
goto return_val;
}
for (lib_iter = lib_list; lib_iter; lib_iter = g_list_next(lib_iter)) {
res = gds_tree_check_cell_references((struct gds_library *)lib_iter->data);
if (res < 0) {
fprintf(stderr, "Error checking cell references. Will continue...\n");
}
res = gds_tree_check_reference_loops((struct gds_library *)lib_iter->data);
if (res < 0) {
fprintf(stderr, "Error checking cell reference loops. Will continue...\n");
}
}
if (fmt == ANA_FORMAT_CELLS_ONLY) {
print_cell_names(lib_list);
goto return_clear_libs;
}
print_statistics(fmt, lib_list);
return_clear_libs:
clear_lib_list(&lib_list);
return_val:
return ret;
}
/** @} */ /** @} */

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,53 +0,0 @@
/**
@page translation Translations / Internationalization
@section lang-available Available Languages
The development, documentation and default application language of gds-render is English.
Translations of GUI and console output exist for the following locales/languages
- de German (Deutsch)
- ja Japanese (日本語) (Work in progess)
On how to add new languages, see @ref lang-add
@section lang-internals Internals
This progamm uses gettext for translations.
@subsection lang-coding Make Strings Translatable in Code
Only strings, that are marked as translatable are actually available for translation and shown in the user's language.
All other text is displayed as written in the source files.
@subsubsection lang-add-glade Make GUI Elements in Glade Files Translatable
Text inside Glade's GUI files can be made translatable by checking the *translatable* option for the specific text property.
The following image shows the label property of a button. Notice the checked Translatable option.
@image html translate-glade.png
@image latex translate-glade.png
@subsubsection lang-add-c Make C Strings Translatable
In order to make strings in C code translatable, the following header has to be included:
@code
#inlcude <glib/gi18n.h>
@endcode
This header provides a few macros useful for translation. The most important one is the function-like macro
@code
_("Text here")
@endcode
which is just a underline character.
You can use this marco to encapsulate all static strings that shall be translated. The whole expression is still usable like any other string (except for compile time concatenation, like: "This is foo" " and this is bar")
Example:
@code
printf(_("The value of foo is %d\n"), foo);
@endcode
Text that must not be translated can be encapsulated inside a N_ macro like
@code
N_("This has to stay in English")
@endcode
The N_ macro is basically an empty macro and just for visualization.
@subsection lang-add Add a New Language
*/

View File

@ -2,8 +2,8 @@
@page versioning Version Number @page versioning Version Number
@section main-version Main Versioning Scheme @section main-version Main Versioning Scheme
The version number of this application consists of a given version in the format of 'v1.0.0' (formely only 2 digits). The version number of this application consists of a given version in the format of 'v1.0'.
Where the first number indicates a major release and the second and third numbers indicate minor changes. Where the first number indicates a major release and the second number indicates minor changes.
Versions, including release candidates and patch-levels, are tagged in git. Versions, including release candidates and patch-levels, are tagged in git.
@ -13,7 +13,7 @@ The 3rd release candidate of version 4.2 would be '*v4.2-rc3*'.
Release candidates are in a frozen state. Only bugfixes that are necessary for functionality are applied to these versions before releasing the final version. Release candidates are in a frozen state. Only bugfixes that are necessary for functionality are applied to these versions before releasing the final version.
@subsection patch-level Patch Levels @subsection patch-level Patch Levels
If an already released version contains bugs that need to be fixed, the version number is not incremented. Insted a new version number with a patch-level is created. The patch-level is appended with a dash directly after the version number. The fist patch-level of version 3.5.2 would be: 'v3.5.2-1'. If an already released version contains bugs that need to be fixed, the version number is not incremented. Insted a new version number with a patch-level is created. The patch-level is appended with a dash directly after the version number. The fist patch-level of version 3.5 would be: 'v3.5-1'.
@section git-version-num Git Based Version Number @section git-version-num Git Based Version Number

View File

@ -37,6 +37,7 @@
#include <gds-render/layer/layer-selector.h> #include <gds-render/layer/layer-selector.h>
#include <gds-render/widgets/activity-bar.h> #include <gds-render/widgets/activity-bar.h>
#include <gds-render/cell-selector/lib-cell-renderer.h> #include <gds-render/cell-selector/lib-cell-renderer.h>
#include <gds-render/cell-selector/cell-statistics-renderer.h>
#include <gds-render/output-renderers/latex-renderer.h> #include <gds-render/output-renderers/latex-renderer.h>
#include <gds-render/output-renderers/cairo-renderer.h> #include <gds-render/output-renderers/cairo-renderer.h>
#include <gds-render/widgets/conv-settings-dialog.h> #include <gds-render/widgets/conv-settings-dialog.h>
@ -48,6 +49,7 @@ enum cell_store_columns {
CELL_SEL_LIBRARY = 0, CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL, CELL_SEL_CELL,
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */ CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
CELL_SEL_STAT,
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */ CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
}; };
@ -187,7 +189,8 @@ static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1); gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
if (lib) { /* Show always, if this is a pure lib entry */
if (lib && !cell) {
result = TRUE; result = TRUE;
goto exit_filter; goto exit_filter;
} }
@ -218,10 +221,11 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
{ {
GtkCellRenderer *render_cell; GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib; GtkCellRenderer *render_lib;
GtkCellRenderer *render_vertex_count;
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER,
G_TYPE_POINTER, G_TYPE_UINT); G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER);
/* Searching */ /* Searching */
self->cell_filter = GTK_TREE_MODEL_FILTER( self->cell_filter = GTK_TREE_MODEL_FILTER(
@ -237,6 +241,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
render_cell = lib_cell_renderer_new(); render_cell = lib_cell_renderer_new();
render_lib = lib_cell_renderer_new(); render_lib = lib_cell_renderer_new();
render_vertex_count = cell_statistics_renderer_new();
column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL); column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column); gtk_tree_view_append_column(self->cell_tree_view, column);
@ -245,6 +250,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL); "error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column); gtk_tree_view_append_column(self->cell_tree_view, column);
column = gtk_tree_view_column_new_with_attributes(_("Vertex | GFX Count"), render_vertex_count, "cell-stat", CELL_SEL_STAT,
NULL);
gtk_tree_view_append_column(self->cell_tree_view, column);
/* Callback for selection /* Callback for selection
* This prevents selecting a library * This prevents selecting a library
*/ */
@ -254,6 +263,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
return 0; return 0;
} }
const struct gds_cell_statistics cc = {
.vertex_count = 12,
};
/** /**
* @brief Callback function of Load GDS button * @brief Callback function of Load GDS button
* @param button * @param button
@ -277,6 +290,10 @@ static void on_load_gds(gpointer button, gpointer user)
char *filename; char *filename;
unsigned int cell_error_level; unsigned int cell_error_level;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
self = RENDERER_GUI(user); self = RENDERER_GUI(user);
if (!self) if (!self)
return; return;
@ -306,7 +323,7 @@ static void on_load_gds(gpointer button, gpointer user)
clear_lib_list(&self->gds_libraries); clear_lib_list(&self->gds_libraries);
/* Parse new GDSII file */ /* Parse new GDSII file */
gds_result = parse_gds_from_file(filename, &self->gds_libraries); gds_result = parse_gds_from_file(filename, &self->gds_libraries, &gds_parsing_options);
/* Delete file name afterwards */ /* Delete file name afterwards */
g_free(filename); g_free(filename);
@ -348,6 +365,7 @@ static void on_load_gds(gpointer button, gpointer user)
CELL_SEL_CELL, gds_c, CELL_SEL_CELL, gds_c,
CELL_SEL_CELL_ERROR_STATE, cell_error_level, CELL_SEL_CELL_ERROR_STATE, cell_error_level,
CELL_SEL_LIBRARY, gds_c->parent_library, CELL_SEL_LIBRARY, gds_c->parent_library,
CELL_SEL_STAT, &gds_c->stats,
-1); -1);
} /* for cells */ } /* for cells */
} /* for libraries */ } /* for libraries */
@ -690,19 +708,13 @@ static void on_select_all_layers_clicked(GtkWidget *button, gpointer user_data)
layer_selector_select_all_layers(gui->layer_selector, TRUE); layer_selector_select_all_layers(gui->layer_selector, TRUE);
} }
static void auto_naming_clicked(GtkWidget *button, gpointer user_data) static gboolean auto_naming_ask_for_override(GdsRenderGui *gui)
{ {
GdsRenderGui *gui;
GtkDialog *dialog; GtkDialog *dialog;
gboolean overwrite; gint dialog_result;
int dialog_result; gboolean overwrite = FALSE;
(void)button;
gui = RENDERER_GUI(user_data); g_return_val_if_fail(RENDERER_IS_GUI(gui), FALSE);
/* Don't do anything if the selector is empty. */
if (!layer_selector_contains_elements(gui->layer_selector))
return;
/* Ask for overwrite */ /* Ask for overwrite */
dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION, dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION,
@ -719,6 +731,25 @@ static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
} }
gtk_widget_destroy(GTK_WIDGET(dialog)); gtk_widget_destroy(GTK_WIDGET(dialog));
return overwrite;
}
static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
{
GdsRenderGui *gui;
gboolean overwrite = FALSE;
(void)button;
gui = RENDERER_GUI(user_data);
/* Don't do anything if the selector is empty. */
if (!layer_selector_contains_elements(gui->layer_selector))
return;
/* Ask, if names shall be overwritten, if they are not empty */
if (layer_selector_num_of_named_elements(gui->layer_selector) > 0)
overwrite = auto_naming_ask_for_override(gui);
layer_selector_auto_name_layers(gui->layer_selector, overwrite); layer_selector_auto_name_layers(gui->layer_selector, overwrite);
} }

View File

@ -43,6 +43,7 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gds-render/gds-utils/gds-parser.h> #include <gds-render/gds-utils/gds-parser.h>
#include <gds-render/gds-utils/gds-statistics.h>
/** /**
* @brief Default units assumed for library. * @brief Default units assumed for library.
@ -50,8 +51,8 @@
*/ */
#define GDS_DEFAULT_UNITS (10E-9) #define GDS_DEFAULT_UNITS (10E-9)
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/ #define GDS_ERROR(fmt, ...) fprintf(stderr, "[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */ #define GDS_WARN(fmt, ...) fprintf(stderr, "[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
#if GDS_PRINT_DEBUG_INFOS #if GDS_PRINT_DEBUG_INFOS
/**< @brief standard printf. But can be disabled in code. */ /**< @brief standard printf. But can be disabled in code. */
@ -266,7 +267,8 @@ static uint16_t gds_convert_unsigned_int16(const char *data)
* @param library_ptr Return of newly created library. * @param library_ptr Return of newly created library.
* @return Newly created list pointer * @return Newly created list pointer
*/ */
static GList *append_library(GList *curr_list, struct gds_library **library_ptr) static GList *append_library(GList *curr_list, const struct gds_library_parsing_opts *opts,
struct gds_library **library_ptr)
{ {
struct gds_library *lib; struct gds_library *lib;
@ -276,8 +278,15 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
lib->name[0] = 0; lib->name[0] = 0;
lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten lib->unit_in_meters = GDS_DEFAULT_UNITS; // Default. Will be overwritten
lib->cell_names = NULL; lib->cell_names = NULL;
} else /* Copy the settings into the library */
memcpy(&lib->parsing_opts, opts, sizeof(struct gds_library_parsing_opts));
lib->stats.cell_count = 0;
lib->stats.gfx_count = 0;
lib->stats.reference_count = 0;
lib->stats.vertex_count = 0;
} else {
return NULL; return NULL;
}
if (library_ptr) if (library_ptr)
*library_ptr = lib; *library_ptr = lib;
@ -353,6 +362,11 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
cell->parent_library = NULL; cell->parent_library = NULL;
cell->checks.unresolved_child_count = GDS_CELL_CHECK_NOT_RUN; cell->checks.unresolved_child_count = GDS_CELL_CHECK_NOT_RUN;
cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN; cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN;
cell->stats.reference_count = 0;
cell->stats.total_vertex_count = 0;
cell->stats.total_gfx_count = 0;
cell->stats.gfx_count = 0;
cell->stats.vertex_count = 0;
} else } else
return NULL; return NULL;
/* return cell */ /* return cell */
@ -488,20 +502,102 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
} }
/** /**
* @brief Scans cell references inside cell * @brief Simplify graphics objects
This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance * @param graphics gfx struct
* @param user_data GDS library
*/
static void simplify_graphics(gpointer graphics, gpointer user_data)
{
struct gds_graphics *gfx;
const struct gds_point *first_vertex = NULL;
const struct gds_point *prev_vertex = NULL;
const struct gds_point *current_vertex;
GList *vertex_iter;
GList *next_iter;
(void)user_data;
size_t processed_count = 0U;
size_t removed_count = 0U;
gfx = (struct gds_graphics *)graphics;
if (gfx->gfx_type == GRAPHIC_POLYGON) {
GDS_INF("\t\t\tPolygon found\n");
/* Loop over all vertices */
for (vertex_iter = gfx->vertices; vertex_iter;) {
current_vertex = (const struct gds_point *)vertex_iter->data;
next_iter = g_list_next(vertex_iter);
processed_count++;
if (vertex_iter == gfx->vertices) {
/* This is the first vertex */
first_vertex = current_vertex;
prev_vertex = NULL;
}
if (prev_vertex) {
if (current_vertex->x == prev_vertex->x && current_vertex->y == prev_vertex->y) {
/* Vertex is the same as the previous one */
GDS_INF("\t\t\t\tDuplicate vertex (%d,%d). Removing...\n",
current_vertex->x, current_vertex->y);
/* Delete the current one from the list */
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
/* Free the data */
if (vertex_iter->data)
free(vertex_iter->data);
vertex_iter->data = NULL;
g_list_free_1(vertex_iter);
removed_count++;
} else if (!g_list_next(vertex_iter)) {
/* This is the last element in the list */
if (current_vertex->x == first_vertex->x &&
current_vertex->y == first_vertex->y) {
GDS_INF("\t\t\t\tLast vertex is identical to first vertex (%d,%d). Removing\n",
current_vertex->x, current_vertex->y);
gfx->vertices = g_list_remove_link(gfx->vertices, vertex_iter);
if (vertex_iter->data)
free(vertex_iter->data);
g_list_free_1(vertex_iter);
removed_count++;
} else {
GDS_WARN("First vertex is not coincident with first vertex, although the GDS file format specifies this. However, this is not a problem.");
}
}
}
vertex_iter = next_iter;
prev_vertex = current_vertex;
}
GDS_INF("\t\t\tProcessed %zu vertices. %zu removed.\n", processed_count, removed_count);
}
}
/**
* @brief Scans cell and resolves references and simplifies polygons
* This function searches all the references in \p gcell and updates the gds_cell_instance::cell_ref field in each instance
*
* @param gcell pointer cast of #gds_cell * * @param gcell pointer cast of #gds_cell *
* @param library Library where the cell references are searched in * @param library Library where the cell references are searched in
*/ */
static void scan_cell_reference_dependencies(gpointer gcell, gpointer library) static void scan_cell_references_and_polygons(gpointer gcell, gpointer library)
{ {
struct gds_cell *cell = (struct gds_cell *)gcell; struct gds_cell *cell = (struct gds_cell *)gcell;
struct gds_library *my_lib = (struct gds_library *)library;
int simplify_polygons;
simplify_polygons = my_lib->parsing_opts.simplified_polygons;
GDS_INF("\tScanning cell: %s\n", cell->name); GDS_INF("\tScanning cell: %s\n", cell->name);
GDS_INF("\t\tCell references\n");
/* Scan all library references */ /* Scan all library references */
g_list_foreach(cell->child_cells, parse_reference_list, library); g_list_foreach(cell->child_cells, parse_reference_list, library);
GDS_INF("\t\tSimplifying Polygons%s\n", simplify_polygons ? "" : ": skipped");
if (simplify_polygons) {
g_list_foreach(cell->graphic_objs, simplify_graphics, library);
}
} }
/** /**
@ -517,7 +613,16 @@ static void scan_library_references(gpointer library_list_item, gpointer user)
(void)user; (void)user;
GDS_INF("Scanning Library: %s\n", lib->name); GDS_INF("Scanning Library: %s\n", lib->name);
g_list_foreach(lib->cells, scan_cell_reference_dependencies, lib); g_list_foreach(lib->cells, scan_cell_references_and_polygons, lib);
}
static void calc_library_stats(gpointer library_list_item, gpointer user)
{
struct gds_library *lib = (struct gds_library *)library_list_item;
(void)user;
GDS_INF("Calculating stats for Library: %s\n", lib->name);
gds_statistics_calc_cummulative_counts_in_lib(lib);
} }
/** /**
@ -601,6 +706,7 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
for (row = 0; row < aref->rows; row++) { for (row = 0; row < aref->rows; row++) {
/* Create new instance for this row/column and configure data */ /* Create new instance for this row/column and configure data */
container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst); container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst);
container_cell->stats.reference_count++;
if (!sref_inst) { if (!sref_inst) {
GDS_ERROR("Appending cell ref failed!"); GDS_ERROR("Appending cell ref failed!");
continue; continue;
@ -617,7 +723,8 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
GDS_INF("Converted AREF to SREFs\n"); GDS_INF("Converted AREF to SREFs\n");
} }
int parse_gds_from_file(const char *filename, GList **library_list) int parse_gds_from_file(const char *filename, GList **library_list,
const struct gds_library_parsing_opts *parsing_options)
{ {
char *workbuff; char *workbuff;
int read; int read;
@ -697,7 +804,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
/* if begin: Allocate structures */ /* if begin: Allocate structures */
switch (rec_type) { switch (rec_type) {
case BGNLIB: case BGNLIB:
lib_list = append_library(lib_list, &current_lib); lib_list = append_library(lib_list, parsing_options, &current_lib);
if (lib_list == NULL) { if (lib_list == NULL) {
GDS_ERROR("Allocating memory failed"); GDS_ERROR("Allocating memory failed");
run = -3; run = -3;
@ -771,7 +878,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -4; run = -4;
break; break;
} }
GDS_INF("\tEntering boundary/Box\n"); GDS_INF("\tEntering boundary of type %s\n", rec_type==BOUNDARY ? "polygon" : "box");
break; break;
case SREF: case SREF:
if (current_cell == NULL) { if (current_cell == NULL) {
@ -781,6 +888,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} }
current_cell->child_cells = append_cell_ref(current_cell->child_cells, current_cell->child_cells = append_cell_ref(current_cell->child_cells,
&current_s_reference); &current_s_reference);
current_cell->stats.reference_count++;
if (current_cell->child_cells == NULL) { if (current_cell->child_cells == NULL) {
GDS_ERROR("Memory allocation failed"); GDS_ERROR("Memory allocation failed");
run = -4; run = -4;
@ -806,8 +914,13 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
case ENDEL: case ENDEL:
if (current_graphics != NULL) { if (current_graphics != NULL) {
GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path")); GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary"
: (current_graphics->gfx_type == GRAPHIC_PATH ? "path"
: "box")));
current_graphics = NULL; current_graphics = NULL;
if (current_cell) {
current_cell->stats.gfx_count++;
}
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
GDS_INF("\tLeaving Reference\n"); GDS_INF("\tLeaving Reference\n");
@ -825,11 +938,11 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} else if (current_s_reference) { } else if (current_s_reference) {
if (rec_data_length != 8) { if (rec_data_length != 8) {
GDS_WARN("Instance has weird coordinates. Rendered output might be screwed!"); GDS_WARN("Instance has weird coordinates. Rendered output might be wrong!");
} }
} else if (current_a_reference) { } else if (current_a_reference) {
if (rec_data_length != (3*(4+4))) if (rec_data_length != (3*(4+4)))
GDS_WARN("Array instance has weird coordinates. Rendered output might be screwed!"); GDS_WARN("Array instance has weird coordinates. Rendered output might be wrong!");
} }
break; break;
case AREF: case AREF:
@ -957,7 +1070,9 @@ int parse_gds_from_file(const char *filename, GList **library_list)
current_graphics->vertices = current_graphics->vertices =
append_vertex(current_graphics->vertices, x, y); append_vertex(current_graphics->vertices, x, y);
GDS_INF("\t\tSet coordinate: %d/%d\n", x, y); GDS_INF("\t\tSet coordinate: %d/%d\n", x, y);
if (current_cell) {
current_cell->stats.vertex_count++;
}
} }
} else if (current_a_reference) { } else if (current_a_reference) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -1073,8 +1188,13 @@ int parse_gds_from_file(const char *filename, GList **library_list)
if (!run) { if (!run) {
/* Iterate and find references to cells */ /* Iterate and find references to cells */
g_list_foreach(lib_list, scan_library_references, NULL); g_list_foreach(lib_list, scan_library_references, NULL);
/* Calculate lib stats and cummulative total counts */
g_list_foreach(lib_list, calc_library_stats, NULL);
} }
*library_list = lib_list; *library_list = lib_list;
free(workbuff); free(workbuff);

View File

@ -0,0 +1,93 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file gds-statistics.c
* @brief Statistics of GDS files
* @author Mario Hüttel <mario.huettel@gmx.net>
*
*/
#include <gds-render/gds-utils/gds-statistics.h>
#include <stdio.h>
/**
* @addtogroup GDS-Utilities
* @{
*/
#define MAX_RECURSION_DEPTH (1024)
static void calculate_vertex_gfx_count_cell(struct gds_cell *cell, unsigned int recursion_depth)
{
GList *cell_iter;
struct gds_cell_instance *cell_ref;
struct gds_cell *sub_cell;
g_return_if_fail(cell);
/* Check if cell has already been calculated */
if (cell->stats.total_gfx_count && cell->stats.total_vertex_count) {
/* Return. This cell and all of its subcells have been calculated */
return;
}
/* Update with own vertex / GFX count */
cell->stats.total_vertex_count = cell->stats.vertex_count;
cell->stats.total_gfx_count = cell->stats.gfx_count;
/* Do not analyze further, if maximum recursion depth is reached */
if (!recursion_depth)
return;
for (cell_iter = cell->child_cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
/* Scan all subcells recursively, if there are any */
cell_ref = (struct gds_cell_instance *)cell_iter->data;
sub_cell = (struct gds_cell *)cell_ref->cell_ref;
calculate_vertex_gfx_count_cell(sub_cell, recursion_depth - 1);
/* Increment count */
cell->stats.total_vertex_count += sub_cell->stats.total_vertex_count;
cell->stats.total_gfx_count += sub_cell->stats.total_vertex_count;
}
}
void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib)
{
GList *cell_iter;
struct gds_cell *cell;
g_return_if_fail(lib);
for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
cell = (struct gds_cell *)cell_iter->data;
calculate_vertex_gfx_count_cell(cell, MAX_RECURSION_DEPTH);
lib->stats.vertex_count += cell->stats.vertex_count;
lib->stats.cell_count++;
lib->stats.gfx_count += cell->stats.gfx_count;
lib->stats.reference_count += cell->stats.reference_count;
}
}
/** @} */

View File

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

View File

@ -0,0 +1,56 @@
/*
* GDSII-Converter
* Copyright (C) 2022 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file cell-statistics-renderer.h
* @brief Header file for the CellStatisticsRenderer GObject Class
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup CellStatisticsRenderer
* @{
*/
#ifndef _CELL_STATISTICS_RENDERER_H_
#define _CELL_STATISTICS_RENDERER_H_
#include <gtk/gtk.h>
#include <gds-render/gds-utils/gds-statistics.h>
G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GDS_RENDER, CELL_STAT_RENDERER, GtkCellRendererText)
#define TYPE_GDS_RENDER_CELL_STAT_RENDERER (cell_statistics_renderer_get_type())
typedef struct _CellStatisticsRenderer {
GtkCellRendererText super;
} CellStatisticsRenderer;
/**
* @brief New Cell statistics renderer
* @return GObject
*/
GtkCellRenderer *cell_statistics_renderer_new(void);
G_END_DECLS
#endif /* _CELL_STATISTICS_RENDERER_H_ */
/** @} */

View File

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

View File

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

View File

@ -0,0 +1,42 @@
/*
* 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-parser.h
* @brief Header file for the GDS statistics
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef _GDS_STATISTICS_H_
#define _GDS_STATISTICS_H_
/**
* @addtogroup GDS-Utilities
* @{
*/
#include <glib.h>
#include <gds-render/gds-utils/gds-types.h>
void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib);
/** @} */
#endif /* _GDS_STATISTICS_H_ */

View File

@ -65,6 +65,22 @@ struct gds_point {
int y; int y;
}; };
struct gds_cell_statistics {
size_t gfx_count;
size_t vertex_count;
size_t total_vertex_count;
size_t total_gfx_count;
size_t reference_count;
};
struct gds_lib_statistics {
size_t gfx_count;
size_t vertex_count;
size_t reference_count;
size_t cell_count;
};
/** /**
* @brief Stores the result of the cell checks. * @brief Stores the result of the cell checks.
*/ */
@ -127,6 +143,14 @@ struct gds_cell {
GList *graphic_objs; /**< @brief List of #gds_graphics */ GList *graphic_objs; /**< @brief List of #gds_graphics */
struct gds_library *parent_library; /**< @brief Pointer to parent library */ struct gds_library *parent_library; /**< @brief Pointer to parent library */
struct gds_cell_checks checks; /**< @brief Checking results */ struct gds_cell_checks checks; /**< @brief Checking results */
struct gds_cell_statistics stats; /**< @brief Optional statistic info */
};
/**
* @brief Options, hwo this liobrary was parsed.
*/
struct gds_library_parsing_opts {
int simplified_polygons; /**< @brief Polygons have been simplified. Coincident end point removed. */
}; };
/** /**
@ -136,11 +160,14 @@ struct gds_library {
char name[CELL_NAME_MAX]; char name[CELL_NAME_MAX];
struct gds_time_field mod_time; struct gds_time_field mod_time;
struct gds_time_field access_time; struct gds_time_field access_time;
struct gds_library_parsing_opts parsing_opts;
double unit_in_meters; /**< Length of a database unit in meters */ double unit_in_meters; /**< Length of a database unit in meters */
GList *cells; /**< List of #gds_cell that contains all cells in this library*/ GList *cells; /**< List of #gds_cell that contains all cells in this library*/
GList *cell_names /**< List of strings that contains all cell names */; GList *cell_names /**< List of strings that contains all cell names */;
struct gds_lib_statistics stats;
}; };
/** @} */ /** @} */
#endif /* __GDS_TYPES_H__ */ #endif /* __GDS_TYPES_H__ */

View File

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

View File

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

View File

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

View File

@ -238,6 +238,7 @@ static void color_palette_dispose(GObject *gobj)
if (palette->color_array) { if (palette->color_array) {
palette->color_array_length = 0; palette->color_array_length = 0;
free(palette->color_array); free(palette->color_array);
palette->color_array = NULL;
} }
/* Chain up to parent class */ /* Chain up to parent class */

View File

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

15
main.c
View File

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

View File

@ -371,8 +371,6 @@ static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) { for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
linfo = (struct layer_info *)info_list->data; linfo = (struct layer_info *)info_list->data;
dprintf(comm_pipe[1], _("Exporting layer %d to file\n"), linfo->layer);
if (linfo->layer >= MAX_LAYERS) { if (linfo->layer >= MAX_LAYERS) {
printf(_("Layer outside of spec.\n")); printf(_("Layer outside of spec.\n"));
continue; continue;
@ -381,6 +379,8 @@ static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer
if (!linfo->render) if (!linfo->render)
continue; continue;
dprintf(comm_pipe[1], _("Exporting layer %d to file\n"), linfo->layer);
if (pdf_file && pdf_cr) { if (pdf_file && pdf_cr) {
cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin); cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
cairo_paint_with_alpha(pdf_cr, linfo->color.alpha); cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
*.mo

View File

@ -1,7 +1,7 @@
# German translations for gds-render package. # German translations for gds-render package.
# Copyright (C) 2019 THE gds-render'S COPYRIGHT HOLDER # Copyright (C) 2019 THE gds-render'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gds-render package. # This file is distributed under the same license as the gds-render package.
# Mario Hüttel <mario.huettel@gmx.net>, 2019. # マリオ <mario.huettel@gmx.net>, 2019.
# #
msgid "" msgid ""
msgstr "" msgstr ""

View File

@ -1,460 +0,0 @@
# Japanese translations for gds-render package.
# Copyright (C) 2019 THE gds-render'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gds-render package.
# Mario Hüttel <mario.huettel@gmx.net>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: gds-render\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-12-16 18:27+0100\n"
"PO-Revision-Date: 2020-01-16 22:54+0100\n"
"Last-Translator: Mario Hüttel <mario.huettel@gmx.net>\n"
"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 2.2.4\n"
#: ../main.c:97
#, c-format
msgid ""
"\n"
"\n"
"Full git commit: %s"
msgstr ""
"\n"
"\n"
"git コミット: %s"
#: ../main.c:294
msgid " FILE - Convert GDS file <FILE> to graphic"
msgstr " ファイル - ファイルを変換する"
#: ../resources/about.glade:10
msgid "!! Replaced during runtime !!"
msgstr "!! ランタイムで代わる !!"
#: ../command-line.c:205
#, c-format
msgid "%d reference loops found.\n"
msgstr "%d 参照ループが見つかりました.\n"
#: ../main.c:220
msgid "About"
msgstr "情報"
#: ../main.c:290
msgid "Argument string passed to render lib"
msgstr "レンダリングに渡されるデタ"
#: ../resources/main.glade:225
msgid "Automatically color layers"
msgstr "レイヤーを自動的に色付けする"
#: ../resources/main.glade:255
msgid "Automatically name layers"
msgstr "レイヤーに自動的に名前を付ける"
#: ../gds-utils/gds-tree-checker.c:71
#, c-format
msgid "Broken cell list item found in cell %s. Will continue.\n"
msgstr "%sのセルで壊れたセルリストアイテムが見つかりました。続けます。\n"
#: ../gds-utils/gds-tree-checker.c:57
#, c-format
msgid "Broken cell list item found. Will continue.\n"
msgstr "壊れたセルリストアイテムが見つかりました。続けます。\n"
#: ../output-renderers/cairo-renderer.c:409
#, c-format
msgid "Cairo export finished. It might still be buggy!\n"
msgstr "Cairoの変換が終了しました.\n"
#. Execute
#: ../output-renderers/external-renderer.c:120
msgid "Calling external renderer."
msgstr "外部レンダラーの実行。"
#: ../gds-render-gui.c:286 ../widgets/conv-settings-dialog.c:291
msgid "Cancel"
msgstr "キャンセル"
#: ../gds-render-gui.c:244
msgid "Cell"
msgstr "セル"
#: ../command-line.c:209
#, c-format
msgid "Cell is affected by reference loop. Abort!\n"
msgstr "このセルに参照ループがあります。アボート!\n"
#: ../main.c:284
msgid "Cell to render"
msgstr "レンダリングされるセル"
#: ../command-line.c:215
#, c-format
msgid ""
"Cell was not checked. This should not happen. Please report this issue. Will "
"continue either way.\n"
msgstr "セルのチェックはしませんでした。これは問題です。\n"
#: ../command-line.c:202
#, c-format
msgid "Checking library %s failed.\n"
msgstr "ライブラリ %s のチェックは失敗しました。\n"
#: ../resources/dialog.glade:79
msgid "Configure LaTeX as standalone document"
msgstr ""
#: ../resources/main.glade:109
msgid "Convert selected cell"
msgstr ""
#: ../output-renderers/external-renderer.c:89
#, c-format
msgid ""
"Could not load external library '%s'\n"
"Detailed error is:\n"
"%s\n"
msgstr ""
#: ../output-renderers/latex-renderer.c:373
msgid "Could not open LaTeX output file"
msgstr ""
#: ../command-line.c:195
#, c-format
msgid "Couldn't find cell in first library!\n"
msgstr ""
#: ../command-line.c:81
#, c-format
msgid "Count of renderers %d does not match count of output file names %d\n"
msgstr ""
#: ../main.c:286
msgid "Create PDF Layers (OCG)"
msgstr ""
#: ../main.c:285
msgid "Create standalone TeX"
msgstr ""
#: ../main.c:280
msgid "Divide output coordinates by <SCALE>"
msgstr ""
#: ../resources/layer-widget.glade:62
msgid "Export Layer"
msgstr ""
#: ../output-renderers/cairo-renderer.c:366
#, c-format
msgid "Exporting layer %d to file\n"
msgstr ""
#: ../output-renderers/external-renderer.c:142
msgid "External renderer finished."
msgstr ""
#. This should not happen
#: ../output-renderers/cairo-renderer.c:271
#, c-format
msgid "Fatal error: Cairo Renderer: Could not spawn child process!"
msgstr ""
#: ../resources/main.glade:50
msgid "GDS-Render"
msgstr ""
#: ../gds-render-gui.c:294
msgid "GDSII-Files"
msgstr ""
#: ../resources/dialog.glade:18
msgid "Generate LaTeX/TikZ output"
msgstr ""
#: ../resources/dialog.glade:93
msgid "Generate PDF Layers"
msgstr ""
#: ../output-renderers/latex-renderer.c:253
#, c-format
msgid "Generating cell %s"
msgstr ""
#: ../resources/about.glade:12
msgid "Git Repository"
msgstr ""
#: ../widgets/conv-settings-dialog.c:246
#, c-format
msgid "Height: %.3lf %sm"
msgstr ""
#: ../main.c:321
#, c-format
msgid "Ignored argument: %s"
msgstr ""
#: ../output-renderers/external-renderer.c:106
#, c-format
msgid ""
"Init function not found in library:\n"
"%s\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:321
#, c-format
msgid "Layer number too high / outside of spec.\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:369
#, c-format
msgid "Layer outside of spec.\n"
msgstr ""
#: ../widgets/layer-element.c:102
#, c-format
msgid "Layer: %d"
msgstr ""
#: ../gds-render-gui.c:241
msgid "Library"
msgstr ""
#: ../resources/main.glade:68
msgid "Load Mapping"
msgstr ""
#: ../resources/main.glade:73
msgid "Load the current layer configuration from CSV"
msgstr ""
#: ../main.c:116
#, c-format
msgid "Logo could not be displayed: %s\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:293
msgid "No layer specification supplied."
msgstr ""
#: ../command-line.c:186
#, c-format
msgid "No library in library list. This should not happen.\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:288
msgid "No/invalid output file set."
msgstr ""
#: ../widgets/conv-settings-dialog.c:291
msgid "OK"
msgstr ""
#: ../resources/main.glade:58
msgid "Open GDS2 Database"
msgstr ""
#: ../gds-render-gui.c:287
msgid "Open GDSII"
msgstr ""
#: ../gds-render-gui.c:284
msgid "Open GDSII File"
msgstr ""
#: ../main.c:299
#, c-format
msgid "Option parsing failed: %s\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:255
#, c-format
msgid "Output Height: %u px"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:283
msgid "Output Renderer not valid."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:304
msgid "Output Renderer: Rendering function broken. This is a bug."
msgstr ""
#. Set the pixel sizes
#: ../widgets/conv-settings-dialog.c:252
#, c-format
msgid "Output Width: %u px"
msgstr ""
#: ../main.c:282
msgid "Output file path. Can be used multiple times."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:298
msgid "Output renderer called without cell to render."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:74
msgid "Output renderer does not define a render_output function!"
msgstr ""
#: ../main.c:283
msgid "Path for Layer Mapping File"
msgstr ""
#: ../main.c:288
msgid ""
"Path to a custom shared object, that implements the necessary rendering "
"functions"
msgstr ""
#: ../output-renderers/external-renderer.c:78
#, c-format
msgid "Path to shared object not set!\n"
msgstr ""
#: ../command-line.c:74
#, c-format
msgid "Please specify renderers and file names\n"
msgstr ""
#: ../command-line.c:104
#, c-format
msgid ""
"Please specify shared object for external renderer. Will ignore this "
"renderer.\n"
msgstr ""
#: ../main.c:277
msgid "Print version"
msgstr ""
#: ../command-line.c:160
#, c-format
msgid "Probably missing argument. Check --help option\n"
msgstr ""
#: ../main.c:219
msgid "Quit"
msgstr ""
#: ../widgets/activity-bar.c:104
msgid "Ready"
msgstr ""
#: ../resources/dialog.glade:33
msgid "Render PDF using Cairographics"
msgstr ""
#: ../resources/dialog.glade:48
msgid "Render SVG using Cairographics (too buggy at the moment)"
msgstr ""
#: ../widgets/conv-settings-dialog.c:293
msgid "Renderer Settings"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:365
msgid "Renderer already started asynchronously"
msgstr ""
#: ../main.c:279
msgid "Renderer to use. Can be used multiple times."
msgstr ""
#: ../output-renderers/cairo-renderer.c:467
msgid "Rendering Cairo Output..."
msgstr ""
#: ../gds-render-gui.c:554
msgid "Rendering cell..."
msgstr ""
#: ../output-renderers/external-renderer.c:98
#, c-format
msgid ""
"Rendering function not found in library:\n"
"%s\n"
msgstr ""
#: ../resources/main.glade:86
msgid "Save Mapping"
msgstr ""
#: ../resources/main.glade:23
msgid "Save the current layer configuration to CSV"
msgstr ""
#: ../main.c:312
#, c-format
msgid "Scale < 1 not allowed. Setting to 1\n"
msgstr ""
#: ../resources/layer-widget.glade:51
msgid "Select Layer Color and Opacity"
msgstr ""
#: ../resources/main.glade:240
msgid "Select all layers for export"
msgstr ""
#: ../output-renderers/cairo-renderer.c:331
#, c-format
msgid "Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"
msgstr ""
#: ../resources/main.glade:195
msgid "Sort layers ascending"
msgstr ""
#: ../resources/main.glade:210
msgid "Sort layers descending"
msgstr ""
#: ../main.c:212
#, c-format
msgid ""
"There is already an open instance. Will open second window in that "
"instance.\n"
msgstr ""
#: ../main.c:244
#, c-format
msgid ""
"This is gds-render, version: %s\n"
"\n"
"For a list of supported commands execute with --help option.\n"
msgstr ""
#: ../gds-utils/gds-tree-checker.c:188
#, c-format
msgid "Visited cell list should be empty. This is a bug. Please report this.\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:244
#, c-format
msgid "Width: %.3lf %sm"
msgstr ""
#: ../widgets/activity-bar.c:110
msgid "Working..."
msgstr ""
#: ../main.c:96
msgid ""
"gds-render is a free tool for rendering GDS2 layout files into vector "
"graphics."
msgstr ""
#: ../resources/layer-widget.glade:37
msgid "label"
msgstr ""