46 Commits

Author SHA1 Message Date
c28da2ab71 Update doxygen color 2019-02-05 20:54:29 +01:00
6937d24699 Remove old search and implement new search using filtering. 2019-02-05 20:38:52 +01:00
1d67424bc9 Tree storage modified to use combination struct 2019-02-05 19:45:02 +01:00
c7ffcf68ed Add readme 2019-02-04 21:52:50 +01:00
8306c34292 Implement first draft of cell search 2019-02-04 20:02:10 +01:00
9f2544ee94 fix double 0 in layer mapping 2019-02-03 22:50:34 +01:00
1f281119df Fix the better solution. This makes it an even better solution 2019-02-03 22:47:54 +01:00
bdb06c4d6e Fix segfault and implement better *cough* fix for locale problems 2019-02-03 22:44:03 +01:00
1fa2d75abd Fix broken layer mapping if locale is different than english 2019-02-03 22:29:06 +01:00
a3be13bc7c Update doyygen look 2018-12-15 00:21:01 +01:00
4cc519a661 Update usage page 2018-12-15 00:13:01 +01:00
f3968bee48 fix file tag in doxygen header 2018-12-15 00:08:37 +01:00
f54ff7ded6 Add support for external shared object renderer 2018-12-15 00:05:34 +01:00
f025a0233d fix doxygen header 2018-12-15 00:04:53 +01:00
bbdc6c9049 remove unused variable warnings 2018-12-15 00:03:40 +01:00
03a5aea335 Edit Doxygen config. Add image to latex output 2018-12-11 00:19:25 +01:00
3e1a4c7d92 Fixed style and warnings 2018-12-11 00:06:27 +01:00
fc6756b1fb Add doxygen to build system 2018-12-10 23:53:57 +01:00
d7293de1dc Fix doxygen foo 2018-12-10 23:37:00 +01:00
37c21ced04 Fix typo 2018-12-10 21:30:07 +01:00
179dfa0724 Add description to bounding box 2018-12-10 21:28:43 +01:00
3c1f4f9c97 Doxygen Docu 2018-12-10 21:24:52 +01:00
d4ba826474 Update doxygen 2018-12-10 19:36:00 +01:00
8b1626c111 Revert previous commit, fix typos 2018-12-10 19:23:54 +01:00
2a860ab949 Update doxygen 2018-12-10 19:16:07 +01:00
eaf692e046 Add .buildconfig to gitignore 2018-12-06 23:05:56 +01:00
2fe6358815 remove buildconfig 2018-12-06 23:05:19 +01:00
e8b7bd65ac Add static to global variable 2018-09-22 23:32:22 +02:00
d69082a676 Fix CmakeLists File. Project command has to be first to prevent errors 2018-09-22 23:29:31 +02:00
b6ea48ba47 Merge branch 'master' of git.shimatta.de:mhu/gds-render 2018-08-24 16:15:42 +02:00
cf7e4ccad0 trigonometric operations added 2018-08-24 16:15:36 +02:00
1a6fdf59ab edit error handling 2018-08-01 12:42:41 +02:00
299d65aa6c cairo ouput svg modifications. Still doesn't work. Only for integer coordinates (scaling 1) it seems to work 2018-08-01 12:36:31 +02:00
54d5148c9d update doxygen 2018-07-30 12:44:37 +02:00
6a01d67594 Add cairo SVG export. However, cairo is buggy so it is on hold for the time being 2018-07-30 12:35:30 +02:00
01367af99c vector operations added 2018-07-28 10:37:00 +02:00
f04418376c add overwrite confirmation to file dialogs 2018-07-28 10:01:02 +02:00
74783f312a bounding box functions added 2018-07-27 21:08:45 +02:00
d4517aa493 add trigonometric sub library, add function to calculate bounding box of polygon 2018-07-27 21:00:30 +02:00
13676deb34 doxygen documentation, add image of GUI 2018-07-26 15:03:06 +02:00
f204d4c2e8 Fix bug in LaTeX renderer 2018-07-26 15:02:44 +02:00
7047315892 Describe layer mapping file 2018-07-26 14:44:52 +02:00
a56bec272b Doxygen documentation 2018-07-25 16:44:04 +02:00
8f9531d63f fix absolute paths in Doxygen documentation 2018-07-25 12:31:18 +02:00
5aaa4d85b8 fix PKGBUILD 2018-07-25 11:25:58 +02:00
6f9b23301e Add PKGBUILD to build Pacman package 2018-07-25 11:19:15 +02:00
42 changed files with 3509 additions and 267 deletions

View File

@@ -1,10 +0,0 @@
[default]
name=Default
runtime=host
config-opts=
run-opts=
prefix=/home/mari/.cache/gnome-builder/install/gds-render/host
app-id=
postbuild=
prebuild=
default=true

2
.gitignore vendored
View File

@@ -72,3 +72,5 @@ Thumbs.db
*.exe
*.user
*.user*
*.buildconfig

37
AUR/PKGBUILD Normal file
View File

@@ -0,0 +1,37 @@
# Maintainer: Mario Hüttel <mario (dot) huettel (!) gmx (dot) net>
pkgname=gds-render
pkgver=20180725.001
pkgrel=1
pkgdesc="Conversion tool for converting GDS layout files into TikZ Code and PDF"
arch=('i686' 'x86_64')
url="https://git.shimatta.de/mhu/gds-render"
licence=('GPLv2')
depends=('glib2' 'gtk3' 'cairo')
makedepends=('cmake' 'git')
privides=('gds-render')
source=("${pkgname}-git"::"git+https://git.shimatta.de/mhu/gds-render.git")
sha1sums=('SKIP')
pkgver () {
_date=`date +"%Y%m%d"`
cd "${srcdir}/${pkgname}-git"
echo "$_date.$(git rev-list --count master).$(git rev-parse --short master)"
}
build () {
cd "$srcdir/$pkgname-git"
cmake .
make
}
package () {
cd "$srcdir/$pkgname-git"
make DESTDIR="${pkgdir}" install
install -D -m664 "$srcdir/$pkgname-git/AUR/gds-render.desktop" \
"$pkgdir/usr/share/applications/gds-render.desktop"
install -D -m664 "$srcdir/$pkgname-git/icon/gds-render.svg" \
"$pkgdir/usr/share/icons/hicolor/scalable/apps/gds-render.svg"
install -D -m664 "$srcdir/$pkgname-git/icon/128x128/gds-render.png" \
"$pkgdir/usr/share/icons/hicolor/128x128/apps/gds-render.png"
}

9
AUR/gds-render.desktop Normal file
View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=GDS-Render
Comment=Converter for GDS layout files
Icon=gds-render
Exec=gds-render
Categories=Graphics

View File

@@ -1,24 +1,25 @@
project(gds-render)
cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(CAIRO REQUIRED cairo)
project(gds-render)
add_subdirectory(glade)
add_subdirectory(doxygen)
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS})
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER})
aux_source_directory("widgets" LAYER_SOURCES)
aux_source_directory("tree-renderer" RENDERER_SOURCES)
aux_source_directory("gds-parser" PARSER_SOURCES)
aux_source_directory("latex-output" LATEX_SOURCES)
aux_source_directory("cairo-output" CAIRO_SOURCES)
set(SOURCE "main.c" "layer-selector.c" "mapping-parser.c" "command-line.c" "main-window.c")
aux_source_directory("trigonometric" TRIG_SOURCES)
set(SOURCE "main.c" "layer-selector.c" "mapping-parser.c" "command-line.c" "main-window.c" "external-renderer.c")
set(SOURCE
${SOURCE}
@@ -27,6 +28,7 @@ set(SOURCE
${PARSER_SOURCES}
${LATEX_SOURCES}
${CAIRO_SOURCES}
${TRIG_SOURCES}
)
add_compile_options(-Wall)
@@ -34,5 +36,6 @@ add_compile_options(-Wall)
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
add_dependencies(${PROJECT_NAME} glib-resources)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m)
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m ${CMAKE_DL_LIBS})
install (TARGETS ${PROJECT_NAME} DESTINATION bin)

21
README.MD Normal file
View File

@@ -0,0 +1,21 @@
# GDS-Render
This software is a rendering programm for GDS2 layout files.
The GDS2 format is mainly used in integrated circuit development.
This program allows the conversion of a GDS file to a vector graphics file.
## Output Formats
* Export GDS Layout to LaTeX (using TikZ).
* Export to PDF (Cairographics).
# Features
Note: Due to various size limitations of both TikZ and the PDF export, the layout might not render correctly. In this case adjust the scale value. A higher scale value scales down your design.
* Configurable layer stack-up.
* Layer colors configurable as ARGB color values.
* Command line interface.
* ~~Awesome~~ Somehow usable GUI.
# License and Other Stuff
* Free software (GPLv2 _only_)
* Coded in plain C using GTK+3.0, Glib2, and Cairographics

View File

@@ -16,7 +16,7 @@
* 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 cairo-output.c
* @brief Output renderer for Cairo PDF export
* @author Mario Hüttel <mario.huettel@gmx.net>
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <cairo.h>
#include <cairo-pdf.h>
#include <cairo-svg.h>
/**
* @brief The cairo_layer struct
@@ -177,10 +178,10 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
}
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale)
void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale)
{
cairo_surface_t *pdf_surface;
cairo_t *pdf_cr;
cairo_surface_t *pdf_surface, *svg_surface;
cairo_t *pdf_cr, *svg_cr;
struct layer_info *linfo;
struct cairo_layer *layers;
struct cairo_layer *lay;
@@ -189,6 +190,11 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
double rec_x0, rec_y0, rec_width, rec_height;
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
if (pdf_file == NULL && svg_file == NULL) {
/* No output specified */
return;
}
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
/* Clear layers */
@@ -246,8 +252,15 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
printf("Bounding box: (%lf,%lf) -- (%lf,%lf)\n", xmin, ymin, xmax, ymax);
if (pdf_file) {
pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
pdf_cr = cairo_create(pdf_surface);
}
if (svg_file) {
svg_surface = cairo_svg_surface_create(svg_file, xmax-xmin, ymax-ymin);
svg_cr = cairo_create(svg_surface);
}
/* Write layers to PDF */
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
@@ -258,13 +271,29 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
continue;
}
if (pdf_file) {
cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);
}
if (svg_file) {
cairo_set_source_surface(svg_cr, layers[linfo->layer].rec, -xmin, -ymin);
cairo_paint_with_alpha(svg_cr, linfo->color.alpha);
}
}
if (pdf_file) {
cairo_show_page(pdf_cr);
cairo_destroy(pdf_cr);
cairo_surface_destroy(pdf_surface);
}
if (svg_file) {
cairo_show_page(svg_cr);
cairo_destroy(svg_cr);
cairo_surface_destroy(svg_surface);
}
ret_clear_layers:
for (i = 0; i < MAX_LAYERS; i++) {

View File

@@ -35,12 +35,13 @@
/**
* @brief Render \p cell to a PDF file specified by \p pdf_file
* @param cell Toplevel cell to render
* @param cell Toplevel cell to @ref Cairo-Renderer
* @param layer_infos List of layer information. Specifies color and layer stacking
* @param pdf_file Output file
* @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated
* @param svg_file SVG output file. Set to NULL if no SVG file has to be generated
* @param scale Scale the output image down by \p scale
*/
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale);
void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale);
/** @} */

View File

@@ -34,6 +34,7 @@
#include "mapping-parser.h"
#include "cairo-output/cairo-output.h"
#include "latex-output/latex-output.h"
#include "external-renderer.h"
/**
* @brief Delete layer_info and free nem element.
@@ -50,21 +51,9 @@ static void delete_layer_info_with_name(struct layer_info *info)
}
}
/**
* @brief Convert GDS according to supplied parameters
* @param gds_name GDS File path
* @param pdf_name Cairo-PDF path
* @param tex_name TeX/TikZ path
* @param pdf Render Cairo
* @param tex Render LaTeX
* @param layer_file Layer mapping file
* @param cell_name Cell name to render
* @param scale Scale image down by this value
* @param pdf_layers TikZ creates OCG layers
* @param pdf_standalone LaTeX document is standalone
*/
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
char *layer_file, char *cell_name, double scale, gboolean pdf_layers, gboolean pdf_standalone)
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file)
{
GList *libs = NULL;
FILE *tex_file;
@@ -83,7 +72,7 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
struct gds_cell *toplevel_cell = NULL, *temp_cell;
/* Check if parameters are valid */
if (!gds_name || ! pdf_name || !tex_name || !layer_file || !cell_name) {
if (!gds_name || (!pdf_name && pdf) || (!tex_name && tex) || !layer_file || !cell_name) {
printf("Probably missing argument. Check --help option\n");
return;
}
@@ -143,8 +132,9 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
}
/* Render outputs */
if (pdf == TRUE) {
cairo_render_cell_to_pdf(toplevel_cell, layer_info_list, pdf_name, scale);
if (pdf == TRUE || svg == TRUE) {
cairo_render_cell_to_vector_file(toplevel_cell, layer_info_list, (pdf == TRUE ? pdf_name : NULL),
(svg == TRUE ? svg_name : NULL), scale);
}
if (tex == TRUE) {
@@ -155,6 +145,16 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
fclose(tex_file);
}
if (so_name && so_out_file) {
if (strlen(so_name) == 0 || strlen(so_out_file) == 0)
goto ret_clear_list;
/* Render output using external renderer */
printf("Invoking external renderer!\n");
external_renderer_render_cell(toplevel_cell, layer_info_list, so_out_file, so_name);
printf("External renderer finished!\n");
}
ret_clear_list:
g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name);

View File

@@ -18,7 +18,7 @@
*/
/**
* @file command-line.c
* @file command-line.h
* @brief Render according to command line parameters
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -32,8 +32,26 @@
#define _COMMAND_LINE_H_
#include <glib.h>
/**
* @brief Convert GDS according to supplied parameters
* @param gds_name GDS File path
* @param pdf_name Cairo-PDF path
* @param tex_name TeX/TikZ path
* @param pdf Render Cairo
* @param tex Render LaTeX
* @param layer_file Layer mapping file
* @param cell_name Cell name to render
* @param scale Scale image down by this value
* @param pdf_layers TikZ creates OCG layers
* @param pdf_standalone LaTeX document is standalone7
* @param svg Render to SVG file
* @param so_name Path to shared object of custom renderer
* @param so_out_file Output file path for custom renderer
* @param svg_name SVG file name
*/
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
char *layer_file, char *cell_name, double scale, gboolean pdf_layers, gboolean pdf_standalone);
char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
gboolean pdf_standalone, gboolean svg, char *svg_name, char *so_name, char *so_out_file);
#endif /* _COMMAND_LINE_H_ */

10
doxygen/CMakeLists.txt Normal file
View File

@@ -0,0 +1,10 @@
find_package(Doxygen)
if (DOXYGEN_FOUND)
add_custom_target(doxygen
COMMAND ./build-doxygen.sh "${PROJECT_BINARY_DIR}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating documentation with Doxygen")
else (DOXYGEN_FOUND)
message("Doxygen need to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.8.14
# Doxyfile 1.8.15
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -17,10 +17,10 @@
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See
# This tag specifies the encoding used for all characters in the configuration
# file that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
# The default value is: UTF-8.
@@ -38,7 +38,7 @@ PROJECT_NAME = GDS-Render
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
PROJECT_NUMBER = $(PROJECT_NUMBER)
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -51,14 +51,14 @@ PROJECT_BRIEF =
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
PROJECT_LOGO = ../icon/gds-render.svg
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = ./output
OUTPUT_DIRECTORY = $(OUTPUT_DIRECTORY)
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -93,6 +93,14 @@ ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all generated output in the proper direction.
# Possible values are: None, LTR, RTL and Context.
# The default value is: None.
OUTPUT_TEXT_DIRECTION = None
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
@@ -150,7 +158,7 @@ INLINE_INHERITED_MEMB = NO
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
FULL_PATH_NAMES = NO
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
@@ -238,6 +246,10 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines (in the resulting output). You can put ^^ in the value part of an
# alias to insert a newline as if a physical newline was in the original file.
# When you need a literal { or } or , in the value part of an alias you have to
# escape them by means of a backslash (\), this can lead to conflicts with the
# commands \{ and \} for these it is advised to use the version @{ and @} or use
# a double escape (\\{ and \\})
ALIASES =
@@ -275,17 +287,26 @@ OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice
# sources only. Doxygen will then generate output that is more tailored for that
# language. For instance, namespaces will be presented as modules, types will be
# separated into more groups, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_SLICE = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
# tries to guess whether the code is fixed or free formatted code, this is the
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
# .inc files as Fortran files (default is PHP), and .f files as C (default is
# Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
@@ -296,7 +317,7 @@ EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -754,7 +775,8 @@ WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# parameter documentation, but not about the absence of documentation. If
# EXTRACT_ALL is set to YES then this flag will automatically be disabled.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
@@ -814,7 +836,7 @@ INPUT_ENCODING = UTF-8
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
*.cc \
@@ -927,7 +949,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = images
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -1012,7 +1034,7 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# entity all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
@@ -1049,7 +1071,7 @@ SOURCE_TOOLTIPS = YES
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
@@ -1195,7 +1217,7 @@ HTML_EXTRA_FILES =
# Minimum value: 0, maximum value: 359, default value: 220.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_HUE = 49
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
@@ -1203,7 +1225,7 @@ HTML_COLORSTYLE_HUE = 220
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_SAT = 155
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
# luminance component of the colors in the HTML output. Values below 100
@@ -1214,7 +1236,7 @@ HTML_COLORSTYLE_SAT = 100
# Minimum value: 40, maximum value: 240, default value: 80.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_GAMMA = 80
HTML_COLORSTYLE_GAMMA = 240
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
@@ -1259,13 +1281,13 @@ HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: https://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
# genXcode/_index.html for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1304,7 +1326,7 @@ DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
@@ -1380,7 +1402,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1388,7 +1410,8 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1396,21 +1419,23 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
@@ -1468,7 +1493,7 @@ DISABLE_INDEX = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
GENERATE_TREEVIEW = YES
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
@@ -1523,7 +1548,7 @@ FORMULA_TRANSPARENT = YES
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
USE_MATHJAX = NO
USE_MATHJAX = YES
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
@@ -1543,7 +1568,7 @@ MATHJAX_FORMAT = HTML-CSS
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from https://www.mathjax.org before deployment.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/.
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
@@ -1669,21 +1694,34 @@ LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# Note that when not enabling USE_PDFLATEX the default is latex when enabling
# USE_PDFLATEX the default is pdflatex and when in the later case latex is
# chosen this is overwritten by pdflatex. For specific output languages the
# default can have been set differently, this depends on the implementation of
# the output language.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# Note: This tag is used in the Makefile / make.bat.
# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file
# (.tex).
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to
# generate index for LaTeX.
# Note: This tag is used in the generated output file (.tex).
# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat.
# The default value is: \makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_MAKEINDEX_CMD = \makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
@@ -1800,7 +1838,7 @@ LATEX_HIDE_INDICES = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
LATEX_SOURCE_CODE = YES
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
@@ -1818,6 +1856,14 @@ LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
# LATEX_OUTPUT directory will be used.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -1857,9 +1903,9 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# configuration file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
@@ -1868,8 +1914,8 @@ RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# similar to doxygen's configuration file. A template extensions file can be
# generated using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
@@ -1955,6 +2001,13 @@ XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include
# namespace members in file scope as well, matching the HTML output.
# The default value is: NO.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------

20
doxygen/build-doxygen.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
cd "$DIR"
export PROJECT_NUMBER=`git describe --tags`
if [ $# != 1 ]; then
export OUTPUT_DIRECTORY="./output"
else
export OUTPUT_DIRECTORY="$1"
fi
doxygen Doxyconfig

BIN
doxygen/images/gui.pdf Normal file

Binary file not shown.

2036
doxygen/images/gui.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 114 KiB

34
doxygen/lmf-spec.dox Normal file
View File

@@ -0,0 +1,34 @@
/**
@page lmf-spec Layer Mapping File Specification
File Format
-----------
The layer mapping file contains information on how to render the layers.
The information is stored in CSV format -- *True CSV*; not that rubbish with semicolons that Excel calls CSV.
Each line representing a layer consists of following fields:
> layer,r,g,b,a,export,name
- **layer**: Layer number identifiying this layer.
- **r**,**b**,**g**,**a**: RGBA color value uning double precision float values in the range from 0 to 1.
- **export**: Either '1' or '0'. Defining whether to render this layer into the output file.
- **name**: The name of the layer.
the order of the layers inside the layer mapping file defines the layer stack in the rendered output.
The first layer is at the bottom, the last at the top.
Handling Inside the GUI
-----------------------
The layer mapping file can be imported and exported inside the GUI.
### Export
During export, all layer configurations are written to the mapping file
### Import
During import, all layer configurations are loaded from the mapping file. This overwrites any configuration done to that layer. Layers that are not present in the layer mapping file are appended at the end of the list. This means, they are rendered on top of the other layers. Because the layer mapping file does not contain any information on these layers, their configuration is not reset during import.
*/

26
doxygen/main-page.dox Normal file
View File

@@ -0,0 +1,26 @@
/**
@mainpage
This programm converts GDS layout files to
- PDF Files using the @ref Cairo-Renderer
- Latex code (TikZ) using the @ref LaTeX-Renderer
See the @subpage usage page for details
*/

View File

@@ -0,0 +1,8 @@
/* This file only contains help information for doxygen */
/**
* @defgroup trigonometric Trigonometric Helper Functions
* @description The trigonometric helper function will be used in future releases to pcalculate bounding boxes
* @note Currently not in use!
* @warning Code is incomplete. DO NOT USE!
*/

30
doxygen/usage.dox Normal file
View File

@@ -0,0 +1,30 @@
/**
@page usage Usage
@section cmd Command Line Interface
To use the application on the command line check 'gds-render --help'.
Application Options:
- -t, --tikz Output TikZ code
- -p, --pdf Output PDF document
- -s, --scale=<SCALE> Divide output coordinates by <SCALE>
- -o, --tex-output=PATH Optional path for TeX file
- -O, --pdf-output=PATH Optional path for PDF file
- -m, --mapping=PATH Path for Layer Mapping File
- -c, --cell=NAME Cell to render
- -a, --tex-standalone Create standalone PDF
- -l, --tex-layers Create PDF Layers (OCG)
- -P, --custom-render-lib=PATH Path to a custom shared object, that implements the render_cell_to_file function
- -e, --external-lib-output=PATH Output path for external render library
- --display=DISPLAY X display to use
@section gui Graphical User Interface
The graphical user interface (GUI) can be used to open GDS Files, configure the layer rendering (colors, order, transparency etc.), and convert cells.
It is possible to export the layer configurations so they can be used later on. Even in the @ref cmd
@image html gui.svg
@image latex gui.pdf
*/

6
doxygen/widgets.dox Normal file
View File

@@ -0,0 +1,6 @@
/* This file only contains help information for doxygen */
/**
* @defgroup Widgets Custom GTK Widgets
*
*/

70
external-renderer.c Normal file
View File

@@ -0,0 +1,70 @@
/*
* 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 external-renderer.c
* @brief This file implements the dynamic library loading for the external rendering feature
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#include "external-renderer.h"
#include <dlfcn.h>
#include <stdio.h>
int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path)
{
int (*so_render_func)(struct gds_cell *, GList *, char *) = NULL;
void *so_handle = NULL;
char *error_msg;
int ret = 0;
/* Check parameter sanity */
if (!output_file || !so_path || !toplevel_cell || !layer_info_list) {
return -3000;
}
/* Load shared object */
so_handle = dlopen(so_path, RTLD_LAZY);
if (!so_handle) {
printf("Could not load external library '%s'\nDetailed error is:\n%s\n", so_path, dlerror());
return -2000;
}
/* Load symbol from library */
so_render_func = (int (*)(struct gds_cell *, GList *, char *))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
if ((error_msg = dlerror()) != NULL) {
printf("Rendering function not found in library:\n%s\n", error_msg);
goto ret_close_so_handle;
}
/* Execute */
if (so_render_func)
so_render_func(toplevel_cell, layer_info_list, output_file);
ret_close_so_handle:
dlclose(so_handle);
return ret;
}
/** @} */

58
external-renderer.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* 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 external-renderer.h
* @brief Render according to command line parameters
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#ifndef _EXTERNAL_RENDERER_H_
#define _EXTERNAL_RENDERER_H_
#include "gds-parser/gds-types.h"
#include <glib.h>
/**
* @brief function name expected to be found in external library.
* @detail The function has to be defined as follows:
* @code
* int function_name(gds_cell *toplevel, GList *layer_info_list, char *output_file_name)
* @endcode
*/
#define EXTERNAL_LIBRARY_FUNCTION "render_cell_to_file"
/**
* @brief external_renderer_render_cell
* @param toplevel_cell The toplevel cell to render
* @param layer_info_list The layer information. Contains #layer_info elements
* @param output_file Output file
* @param so_path Path to the shared object file containing #EXTERNAL_LIBRARY_FUNCTION
* @return 0 on success
*/
int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list, char *output_file, char *so_path);
#endif /* _EXTERNAL_RENDERER_H_ */
/** @} */

View File

@@ -23,8 +23,8 @@
/**
* @file gds_parser.h
* @brief Header file for the GDS-Parser
* @file gds-parser.c
* @brief Implementation of the GDS-Parser
* @author Mario Hüttel <mario.huettel@gmx.net>
*
* What's missing? - A lot:

View File

@@ -18,7 +18,7 @@
*/
/**
* @file gds_parser.h
* @file gds-parser.h
* @brief Header file for the GDS-Parser
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -39,7 +39,7 @@
int parse_gds_from_file(const char *filename, GList **library_array);
/**
* @brief Deletes all libraries including cells, references etc.
* @param Pointer to a list of #gds_library. Is set to NULL after completion.
* @param library_list Pointer to a list of #gds_library. Is set to NULL after completion.
* @return 0
*/
int clear_lib_list(GList **library_list);

View File

@@ -35,8 +35,8 @@
#include <glib.h>
#define CELL_NAME_MAX (100) /**< @brief Maximum length of a gds_cell::name or a gds_library::name */
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Find return smaller number */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Find return bigger number */
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */
/** @brief Types of graphic objects */
enum graphics_type

View File

@@ -16,6 +16,7 @@
<child>
<object class="GtkRadioButton" id="latex-radio">
<property name="label" translatable="yes">Generate LaTeX/TikZ output</property>
<property name="use_action_appearance">True</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -29,8 +30,9 @@
</packing>
</child>
<child>
<object class="GtkRadioButton" id="cairo-radio">
<object class="GtkRadioButton" id="cairo-pdf-radio">
<property name="label" translatable="yes">Render PDF using Cairographics</property>
<property name="use_action_appearance">True</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -44,6 +46,24 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="cairo-svg-radio">
<property name="label" translatable="yes">Render SVG using Cairographics (too buggy at the moment)</property>
<property name="use_action_appearance">True</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">latex-radio</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="dialog-scale">
<property name="visible">True</property>
@@ -55,7 +75,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
<child>
@@ -69,7 +89,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
<child>
@@ -83,7 +103,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
</object>

View File

@@ -81,6 +81,25 @@
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchEntry" id="cell-search">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="primary_icon_activatable">False</property>
<property name="primary_icon_sensitive">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
@@ -91,12 +110,22 @@
<object class="GtkTreeView" id="cell-tree">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<property name="enable_grid_lines">both</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>

View File

@@ -114,7 +114,7 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
color->red = inf->color.red;
color->green = inf->color.green;
color->blue = inf->color.blue;
g_string_printf(buffer, "\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi]\n",
g_string_printf(buffer, "\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi\n",
layer, layer, inf->name);
WRITEOUT_BUFFER(buffer);
return TRUE;

View File

@@ -18,7 +18,7 @@
*/
/**
* @file layer-selection.c
* @file layer-selector.c
* @brief Implementation of the layer selector
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -321,6 +321,7 @@ static void load_mapping_clicked(GtkWidget *button, gpointer user_data)
*/
static void create_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len)
{
int i;
GString *string;
gboolean export;
const gchar *name;
@@ -336,9 +337,19 @@ static void create_csv_line(LayerElement *layer_element, char *line_buffer, size
layer_element_get_color(layer_element, &color);
/* print values to line */
g_string_printf(string, "%d,%lf,%lf,%lf,%lf,%d,%s\n",
g_string_printf(string, "%d:%lf:%lf:%lf:%lf:%d:%s\n",
layer, color.red, color.green,
color.blue, color.alpha, (export == TRUE ? 1 : 0), name);
/* Fix broken locale settings */
for (i = 0; string->str[i]; i++) {
if (string->str[i] == ',')
string->str[i] = '.';
}
for (i = 0; string->str[i]; i++) {
if (string->str[i] == ':')
string->str[i] = ',';
}
if (string->len > (max_len-1)) {
printf("Layer Definition too long. Please shorten Layer Name!!\n");
@@ -399,6 +410,8 @@ static void save_mapping_clicked(GtkWidget *button, gpointer user_data)
dialog = gtk_file_chooser_dialog_new("Save Mapping File", GTK_WINDOW(user_data), GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL, "Save Mapping", GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

View File

@@ -45,6 +45,7 @@ struct open_button_data {
GList **list_ptr;
GtkTreeStore *cell_store;
GtkListBox *layer_box;
GtkSearchEntry *search_entry;
};
/**
@@ -112,6 +113,7 @@ static void on_load_gds(gpointer button, gpointer user)
char *filename;
GString *mod_date;
GString *acc_date;
GdkRGBA cell_text_color;
open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", ptr->main_window, GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL, "Open GDSII", GTK_RESPONSE_ACCEPT, NULL);
@@ -172,10 +174,20 @@ static void on_load_gds(gpointer button, gpointer user)
mod_date = generate_string_from_date(&gds_c->mod_time);
acc_date = generate_string_from_date(&gds_c->access_time);
cell_text_color.alpha = 1;
cell_text_color.red = (double)61.0/(double)255.0;
cell_text_color.green = (double)152.0/(double)255.0;
cell_text_color.blue = 0.0;
/* Add cell to tree store model
* CELL_SEL_CELL_COLOR will always be green,
* because no cell cehcker is implemented, yet.
*/
gtk_tree_store_set (store, &celliter,
CELL_SEL_CELL, gds_c,
CELL_SEL_MODDATE, mod_date->str,
CELL_SEL_ACCESSDATE, acc_date->str,
CELL_SEL_CELL_COLOR, &cell_text_color, // TODO: implement cell checker
-1);
/* Delete GStrings including string data. */
@@ -251,15 +263,25 @@ static void on_convert_clicked(gpointer button, gpointer user)
"Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
/* Set file filter according to settings */
filter = gtk_file_filter_new();
if (sett.renderer == RENDERER_LATEX_TIKZ) {
switch (sett.renderer) {
case RENDERER_LATEX_TIKZ:
gtk_file_filter_add_pattern(filter, "*.tex");
gtk_file_filter_set_name(filter, "LaTeX-Files");
} else {
break;
case RENDERER_CAIROGRAPHICS_PDF:
gtk_file_filter_add_pattern(filter, "*.pdf");
gtk_file_filter_set_name(filter, "PDF-Files");
break;
case RENDERER_CAIROGRAPHICS_SVG:
gtk_file_filter_add_pattern(filter, "*.svg");
gtk_file_filter_set_name(filter, "SVG-Files");
break;
}
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@@ -272,8 +294,12 @@ static void on_convert_clicked(gpointer button, gpointer user)
sett.tex_pdf_layers, sett.tex_standalone);
fclose(output_file);
break;
case RENDERER_CAIROGRAPHICS:
cairo_render_cell_to_pdf(cell_to_render, layer_list, file_name, sett.scale);
case RENDERER_CAIROGRAPHICS_SVG:
case RENDERER_CAIROGRAPHICS_PDF:
cairo_render_cell_to_vector_file(cell_to_render, layer_list,
(sett.renderer == RENDERER_CAIROGRAPHICS_PDF ? file_name : NULL),
(sett.renderer == RENDERER_CAIROGRAPHICS_SVG ? file_name : NULL),
sett.scale);
break;
}
g_free(file_name);
@@ -311,23 +337,23 @@ GtkWindow *create_main_window()
{
GtkBuilder *main_builder;
GtkTreeView *cell_tree;
GtkTreeStore *cell_store;
GtkWidget *listbox;
GtkWidget *conv_button;
GtkWidget *search_entry;
static GList *gds_libs;
static struct open_button_data open_data;
static struct convert_button_data conv_data;
struct tree_stores *cell_selector_stores;
main_builder = gtk_builder_new_from_resource("/main.glade");
gtk_builder_connect_signals(main_builder, NULL);
cell_tree = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
cell_store = setup_cell_selector(cell_tree);
search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
open_data.search_entry = GTK_SEARCH_ENTRY(search_entry);
cell_selector_stores = setup_cell_selector(cell_tree, GTK_ENTRY(search_entry));
open_data.cell_store = cell_store;
open_data.cell_store = cell_selector_stores->base_store;
open_data.list_ptr = &gds_libs;
open_data.main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
g_signal_connect(GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds")),
@@ -357,6 +383,8 @@ GtkWindow *create_main_window()
g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(cell_tree)), "changed",
G_CALLBACK(cell_selection_changed), conv_button);
g_object_unref(main_builder);
return (conv_data.main_window);
}

79
main.c
View File

@@ -22,16 +22,19 @@
#include <glib.h>
#include "main-window.h"
#include "command-line.h"
#include "external-renderer.h"
struct application_data {
GtkApplication *app;
GtkWindow *main_window;
};
static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{
struct application_data *appdata = (struct application_data *)user_data;
(void)action;
(void)parameter;
gtk_widget_destroy(GTK_WIDGET(appdata->main_window));
}
@@ -40,6 +43,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
GtkBuilder *builder;
GtkDialog *dialog;
struct application_data *appdata = (struct application_data *)user_data;
(void)action;
(void)parameter;
builder = gtk_builder_new_from_resource("/about.glade");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
@@ -50,7 +55,7 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
g_object_unref(builder);
}
const GActionEntry app_actions[] = {
const static GActionEntry app_actions[] = {
{ "quit", app_quit },
{ "about", app_about }
};
@@ -78,10 +83,7 @@ static int start_gui(int argc, char **argv)
gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE);
g_application_register(G_APPLICATION(gapp), NULL, NULL);
//g_action_map_add_action_entries(G_ACTION_MAP(gapp), app_actions, G_N_ELEMENTS(app_actions), &appdata);
g_signal_connect (gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
menu = g_menu_new();
m_quit = g_menu_new();
@@ -90,7 +92,8 @@ static int start_gui(int argc, char **argv)
g_menu_append(m_about, "About", "app.about");
g_menu_append_section(menu, NULL, G_MENU_MODEL(m_about));
g_menu_append_section(menu, NULL, G_MENU_MODEL(m_quit));
g_action_map_add_action_entries(G_ACTION_MAP(gapp), app_actions, G_N_ELEMENTS(app_actions), &appdata);
g_action_map_add_action_entries(G_ACTION_MAP(gapp), app_actions,
G_N_ELEMENTS(app_actions), &appdata);
gtk_application_set_app_menu(GTK_APPLICATION(gapp), G_MENU_MODEL(menu));
g_object_unref(m_quit);
@@ -98,8 +101,8 @@ static int start_gui(int argc, char **argv)
g_object_unref(menu);
app_status = g_application_run (G_APPLICATION(gapp), argc, argv);
g_object_unref (gapp);
app_status = g_application_run(G_APPLICATION(gapp), argc, argv);
g_object_unref(gapp);
return app_status;
}
@@ -110,32 +113,36 @@ int main(int argc, char **argv)
GOptionContext *context;
gchar *gds_name;
gchar *basename;
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL;
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE;
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE, svg = FALSE;
gchar *custom_library_path = NULL;
gchar *custom_library_file_name = NULL;
int scale = 1000;
int app_status;
GOptionEntry entries[] =
{
{ "tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
{ "pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", NULL },
{ "scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by <SCALE>", "<SCALE>" },
{ "tex-output", 'o', 0, G_OPTION_ARG_FILENAME, &texname, "Optional path for TeX file", "PATH" },
{ "pdf-output", 'O', 0, G_OPTION_ARG_FILENAME, &pdfname, "Optional path for PDF file", "PATH" },
{ "mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
{ "cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
{ "tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
{ "tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create PDF Layers (OCG)", NULL },
GOptionEntry entries[] = {
{"tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
{"pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", NULL },
//{"svg", 'S', 0, G_OPTION_ARG_NONE, &svg, "Output SVG image", NULL },
{"scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by <SCALE>", "<SCALE>" },
{"tex-output", 'o', 0, G_OPTION_ARG_FILENAME, &texname, "Optional path for TeX file", "PATH" },
{"pdf-output", 'O', 0, G_OPTION_ARG_FILENAME, &pdfname, "Optional path for PDF file", "PATH" },
//{"svg-output", 0, 0, G_OPTION_ARG_FILENAME, &svgname, "Optional path for PDF file", "PATH"},
{"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
{"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
{"tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
{"tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create PDF Layers (OCG)", NULL },
{"custom-render-lib", 'P', 0, G_OPTION_ARG_FILENAME, &custom_library_path, "Path to a custom shared object, that implements the " EXTERNAL_LIBRARY_FUNCTION " function", "PATH"},
{"external-lib-output", 'e', 0, G_OPTION_ARG_FILENAME, &custom_library_file_name, "Output path for external render library", "PATH"},
{ NULL }
};
context = g_option_context_new(" FILE - Convert GDS file <FILE> to graphic");
g_option_context_add_main_entries(context, entries, NULL);
g_option_context_add_group(context, gtk_get_option_group(TRUE));
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_print ("Option parsing failed: %s\n", error->message);
if (!g_option_context_parse(context, &argc, &argv, &error)) {
g_print("Option parsing failed: %s\n", error->message);
exit(1);
}
@@ -146,9 +153,8 @@ int main(int argc, char **argv)
}
/* No format selected */
if (!(tikz || pdf)) {
if (!(tikz || pdf || svg))
tikz = TRUE;
}
/* Get gds name */
gds_name = argv[1];
@@ -156,19 +162,24 @@ int main(int argc, char **argv)
/* Check if PDF/TeX names are supplied. if not generate */
basename = g_path_get_basename(gds_name);
if (!texname) {
if (!texname)
texname = g_strdup_printf("./%s.tex", basename);
}
if (!pdfname) {
if (!pdfname)
pdfname = g_strdup_printf("./%s.pdf", basename);
}
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz, mappingname, cellname,
(double)scale, pdf_layers, pdf_standalone);
if (!pdfname)
pdfname = g_strdup_printf("./%s.svg", basename);
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz,
mappingname, cellname, (double)scale,
pdf_layers, pdf_standalone, svg, svgname,
custom_library_path, custom_library_file_name);
/* Clean up */
g_free(pdfname);
g_free(texname);
g_free(svgname);
g_free(basename);
if (mappingname)
g_free(mappingname);
if (cellname)

View File

@@ -1,7 +1,46 @@
/*
* 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 tree-store.h
* @brief Tree store implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#include "tree-store.h"
#include "lib-cell-renderer.h"
#include "../gds-parser/gds-types.h"
/**
* @brief this function olny allows cells to be selected
* @param selection
* @param model
* @param path
* @param path_currently_selected
* @param data
* @return TRUE if element is selectable, FALSE if not
*/
static gboolean tree_sel_func(GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
@@ -21,48 +60,95 @@ static gboolean tree_sel_func(GtkTreeSelection *selection,
return FALSE;
}
GtkTreeStore *setup_cell_selector(GtkTreeView* view)
/**
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
* @param model Tree model
* @param iter Current element / iter in Model to check
* @param data Data. Set to static stores variable
* @return TRUE if visible, else FALSE
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
*/
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
GtkTreeStore *cell_store;
struct tree_stores *stores = (struct tree_stores *)data;
struct gds_cell *cell;
struct gds_library *lib;
gboolean result = FALSE;
const char *search_string;
if (!model || !iter || !stores)
goto exit_filter;
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
if (lib) {
result = TRUE;
goto exit_filter;
}
if (!cell)
goto exit_filter;
search_string = gtk_entry_get_text(stores->search_entry);
/* Show all, if field is empty */
if (!strlen(search_string))
result = TRUE;
if (strstr(cell->name, search_string))
result = TRUE;
gtk_tree_view_expand_all(stores->base_tree_view);
exit_filter:
return result;
}
static void change_filter(GtkWidget *entry, gpointer data)
{
struct tree_stores *stores = (struct tree_stores *)data;
gtk_tree_model_filter_refilter(stores->filter);
}
/**
* @brief Setup a GtkTreeView with the necessary columns
* @param view Tree view to set up
* @param search_entry Entry field for search
* @return Tree stores for storing data inside the GtkTreeView
*/
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry)
{
static struct tree_stores stores;
GtkCellRenderer *render_dates;
GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib;
GtkTreeViewColumn *column;
GdkRGBA cell_text_color;
GValue val = G_VALUE_INIT;
cell_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
gtk_tree_view_set_model(view, GTK_TREE_MODEL(cell_store));
stores.base_tree_view = view;
stores.search_entry = search_entry;
stores.base_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, GDK_TYPE_RGBA, G_TYPE_STRING, G_TYPE_STRING);
/* Searching */
if (search_entry) {
stores.filter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(GTK_TREE_MODEL(stores.base_store), NULL));
gtk_tree_model_filter_set_visible_func (stores.filter,
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
&stores, NULL);
g_signal_connect(GTK_SEARCH_ENTRY(search_entry), "search-changed", G_CALLBACK(change_filter), &stores);
}
gtk_tree_view_set_model(view, GTK_TREE_MODEL(stores.filter));
render_dates = gtk_cell_renderer_text_new();
render_cell = lib_cell_renderer_new();
render_lib = lib_cell_renderer_new();
/* Set foreground color for cell column */
cell_text_color.alpha = 1;
cell_text_color.red = (double)61.0/(double)255.0;
cell_text_color.green = (double)152.0/(double)255.0;
cell_text_color.blue = 0.0;
g_value_init(&val, G_TYPE_BOOLEAN);
g_value_set_boolean(&val, TRUE);
g_object_set_property(G_OBJECT(render_cell), "foreground-set", &val);
g_value_unset(&val);
g_value_init(&val, GDK_TYPE_RGBA);
g_value_set_boxed(&val, &cell_text_color);
g_object_set_property(G_OBJECT(render_cell), "foreground-rgba", &val);
g_value_unset(&val);
column = gtk_tree_view_column_new_with_attributes("Library", render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
gtk_tree_view_append_column(view, column);
/* Cell color: #3D9801 */
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL, NULL);
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL, "foreground-rgba", CELL_SEL_CELL_COLOR, NULL);
gtk_tree_view_append_column(view, column);
column = gtk_tree_view_column_new_with_attributes("Mod. Date", render_dates, "text", CELL_SEL_MODDATE, NULL);
@@ -75,5 +161,6 @@ GtkTreeStore *setup_cell_selector(GtkTreeView* view)
* This prevents selecting a library */
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL);
return cell_store;
return &stores;
}
/** @} */

View File

@@ -1,16 +1,57 @@
/*
* 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 tree-store.h
* @brief Header file for Tree store implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#ifndef __TREE_STORE_H__
#define __TREE_STORE_H__
#include <gtk/gtk.h>
/** @brief Columns of selection tree view */
enum cell_store_columns {
CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL,
CELL_SEL_CELL_COLOR, /**< Cell column color */
CELL_SEL_MODDATE,
CELL_SEL_ACCESSDATE,
CELL_SEL_COLUMN_COUNT
CELL_SEL_COLUMN_COUNT /**< Not a column. Used to determine count of coumns **/
};
GtkTreeStore *setup_cell_selector(GtkTreeView* view);
struct tree_stores {
GtkTreeView *base_tree_view;
GtkTreeStore *base_store;
GtkTreeModelFilter *filter;
GtkEntry *search_entry;
};
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry);
#endif /* __TREE_STORE_H__ */
/** @} */

View File

@@ -0,0 +1,146 @@
/*
* 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 bounding-box.c
* @brief Calculation of bounding boxes
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup trigonometric
* @{
*/
#include <stdio.h>
#include "bounding-box.h"
#include <math.h>
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */
#define ABS_DBL(a) ((a) < 0 ? -(a) : (a))
void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box)
{
double xmin = DBL_MAX, xmax = DBL_MIN, ymin = DBL_MAX, ymax = DBL_MIN;
struct vector_2d temp_vec;
GList *list_item;
/* Check for errors */
if (!conv_func || !box || !vertices)
return;
for (list_item = vertices; list_item != NULL; list_item = g_list_next(list_item)) {
/* Convert generic vertex to vector_2d */
if (conv_func)
conv_func((void *)list_item->data, &temp_vec);
else
vector_2d_copy(&temp_vec, (struct vector_2d *)list_item->data);
/* Update bounding coordinates with vertex */
xmin = MIN(xmin, temp_vec.x);
xmax = MAX(xmax, temp_vec.x);
ymin = MIN(ymin, temp_vec.y);
ymax = MAX(ymax, temp_vec.y);
}
/* Fill bounding box with results */
box->vectors.lower_left.x = xmin;
box->vectors.lower_left.y = ymin;
box->vectors.upper_right.x = xmax;
box->vectors.upper_right.y = ymax;
}
void bounding_box_update_box(union bounding_box *destination, union bounding_box *update)
{
if (!destination || !update)
return;
destination->vectors.lower_left.x = MIN(destination->vectors.lower_left.x,
update->vectors.lower_left.x);
destination->vectors.lower_left.y = MIN(destination->vectors.lower_left.y,
update->vectors.lower_left.y);
destination->vectors.upper_right.x = MAX(destination->vectors.upper_right.x,
update->vectors.upper_right.x);
destination->vectors.upper_right.y = MAX(destination->vectors.upper_right.y,
update->vectors.upper_right.y);
}
void bounding_box_prepare_empty(union bounding_box *box)
{
box->vectors.lower_left.x = DBL_MAX;
box->vectors.lower_left.y = DBL_MAX;
box->vectors.upper_right.x = DBL_MIN;
box->vectors.upper_right.y = DBL_MIN;
}
static void calculate_path_miter_points(struct vector_2d *a, struct vector_2d *b, struct vector_2d *c,
struct vector_2d *m1, struct vector_2d *m2, double width)
{
double angle, angle_sin, u;
struct vector_2d ba, bc, u_vec, v_vec, ba_norm;
if (!a || !b || !c || !m1 || !m2)
return;
vector_2d_subtract(&ba, a, b);
vector_2d_subtract(&bc, c, b);
angle = vector_2d_calculate_angle_between(&ba, &bc);
if (ABS_DBL(angle) < 0.05 || ABS_DBL(angle - M_PI) < 0.1) {
/* Specail cases Don*/
vector_2d_copy(&ba_norm, &ba);
vector_2d_rotate(&ba_norm, DEG2RAD(90));
vector_2d_normalize(&ba_norm);
vector_2d_scale(&ba_norm, width/2.0);
vector_2d_add(m1, b, &ba_norm);
vector_2d_subtract(m2, b, &ba_norm);
return;
}
angle_sin = sin(angle);
u = width/(2*angle_sin);
vector_2d_copy(&u_vec, &ba);
vector_2d_copy(&v_vec, &bc);
vector_2d_normalize(&u_vec);
vector_2d_normalize(&v_vec);
vector_2d_scale(&u_vec, u);
vector_2d_scale(&v_vec, u);
vector_2d_copy(m1, b);
vector_2d_add(m1, m1, &u_vec);
vector_2d_add(m1, m1, &v_vec);
vector_2d_copy(m2, b);
vector_2d_subtract(m2, m2, &u_vec);
vector_2d_subtract(m2, m2, &v_vec);
}
void bounding_box_calculate_path_box(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box)
{
}
void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt)
{
}
/** @} */

View File

@@ -0,0 +1,54 @@
/*
* 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 bounding-box.h
* @brief Header for calculation of bounding boxes
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup trigonometric
* @{
*/
#ifndef _BOUNDING_BOX_H_
#define _BOUNDING_BOX_H_
#include <glib.h>
#include "vector-operations.h"
union bounding_box {
/** Coordinate System is (y up | x right) */
struct _vectors {
struct vector_2d lower_left;
struct vector_2d upper_right;
} vectors;
struct vector_2d vector_array[2];
};
typedef void (*conv_generic_to_vector_2d_t)(void *, struct vector_2d *);
void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box);
void bounding_box_update_box(union bounding_box *destination, union bounding_box *update);
void bounding_box_prepare_empty(union bounding_box *box);
void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt);
#endif /* _BOUNDING_BOX_H_ */
/** @} */

View File

@@ -0,0 +1,150 @@
/*
* 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 vector-operations.c
* @brief 2D Vector operations
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup trigonometric
* @{
*/
#include "vector-operations.h"
#include <math.h>
#include <stdlib.h>
#define ABS_DBL(a) ((a) < 0 ? -(a) : (a))
double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b)
{
if (a && b)
return (a->x * b->x) + (a->y * b->y);
else
return 0.0;
}
void vector_2d_normalize(struct vector_2d *vec)
{
double len;
if (!vec)
return;
len = sqrt(pow(vec->x,2)+pow(vec->y,2));
vec->x = vec->x/len;
vec->y = vec->y/len;
}
void vector_2d_rotate(struct vector_2d *vec, double angle)
{
double sin_val, cos_val;
struct vector_2d temp;
if (!vec)
return;
sin_val = sin(angle);
cos_val = cos(angle);
vector_2d_copy(&temp, vec);
/* Apply rotation matrix */
vec->x = (cos_val * temp.x) - (sin_val * temp.y);
vec->y = (sin_val * temp.x) + (cos_val * temp.y);
}
struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec)
{
struct vector_2d *res;
if (!vec)
return NULL;
if (opt_res) {
opt_res->x = vec->x;
opt_res->y = vec->y;
return opt_res;
} else {
res = vector_2d_alloc();
if (res) {
res->x = vec->x;
res->y = vec->y;
}
return res;
}
}
struct vector_2d *vector_2d_alloc(void)
{
return (struct vector_2d *)malloc(sizeof(struct vector_2d));
}
void vector_2d_free(struct vector_2d *vec)
{
if (vec) {
free(vec);
}
}
void vector_2d_scale(struct vector_2d *vec, double scale)
{
if (!vec)
return;
vec->x *= scale;
vec->y *= scale;
}
double vector_2d_abs(struct vector_2d *vec)
{
double len = 0.0;
if (vec) {
len = sqrt(pow(vec->x,2)+pow(vec->y,2));
}
return len;
}
double vector_2d_calculate_angle_between(struct vector_2d *a, struct vector_2d *b)
{
double cos_angle;
if (!a || !b)
return 0.0;
cos_angle = ABS_DBL(vector_2d_scalar_multipy(a, b)) / (vector_2d_abs(a) * vector_2d_abs(b));
return acos(cos_angle);
}
void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b)
{
if (res && a && b) {
res->x = a->x - b->x;
res->y = a->y - b->y;
}
}
void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b)
{
if (res && a && b) {
res->x = a->x +b->x;
res->y = a->y + b->y;
}
}
/** @} */

View File

@@ -0,0 +1,58 @@
/*
* 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 vector-operations.h
* @brief Header for 2D Vector operations
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup trigonometric
* @{
*/
#ifndef _VECTOR_OPERATIONS_H_
#define _VECTOR_OPERATIONS_H_
#include <math.h>
struct vector_2d {
double x;
double y;
};
#define DEG2RAD(a) ((a)*M_PI/180.0)
double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b);
void vector_2d_normalize(struct vector_2d *vec);
void vector_2d_rotate(struct vector_2d *vec, double angle);
struct vector_2d *vector_2d_copy(struct vector_2d *opt_res, struct vector_2d *vec);
struct vector_2d *vector_2d_alloc(void);
void vector_2d_free(struct vector_2d *vec);
void vector_2d_scale(struct vector_2d *vec, double scale);
double vector_2d_abs(struct vector_2d *vec);
double vector_2d_calculate_angle_between(struct vector_2d *a, struct vector_2d *b);
void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b);
void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b);
#endif /* _VECTOR_OPERATIONS_H_ */
/** @} */

View File

@@ -17,13 +17,25 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file conv-settings-dilaog.c
* @brief Implementation of the setting dialog
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup Widgets
* @{
*/
#include "conv-settings-dialog.h"
struct _RendererSettingsDialog {
GtkDialog parent;
/* Private loot */
GtkWidget *radio_latex;
GtkWidget *radio_cairo;
GtkWidget *radio_cairo_pdf;
GtkWidget *radio_cairo_svg;
GtkWidget *scale;
GtkWidget *layer_check;
GtkWidget *standalone_check;
@@ -72,7 +84,8 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self)
builder = gtk_builder_new_from_resource("/dialog.glade");
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio"));
self->radio_cairo = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-radio"));
self->radio_cairo_pdf = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-pdf-radio"));
self->radio_cairo_svg = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-svg-radio"));
self->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale"));
self->standalone_check = GTK_WIDGET(gtk_builder_get_object(builder, "standalone-check"));
self->layer_check = GTK_WIDGET(gtk_builder_get_object(builder, "layer-check"));
@@ -99,13 +112,27 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
{
/*GList *radio_buttons;
*GList *temp_button_list;
*GtkToggleButton *temp_button = NULL;
*/
if (!settings || !dialog)
return;
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
settings->renderer = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE ? RENDERER_LATEX_TIKZ : RENDERER_CAIROGRAPHICS);
/* Get active radio button selection */
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE) {
settings->renderer = RENDERER_LATEX_TIKZ;
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE) {
settings->renderer = RENDERER_CAIROGRAPHICS_PDF;
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE) {
settings->renderer = RENDERER_CAIROGRAPHICS_SVG;
}
settings->tex_pdf_layers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->layer_check));
settings->tex_standalone = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->standalone_check));
}
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
{
if (!settings || !dialog)
@@ -120,9 +147,17 @@ void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struc
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_latex), TRUE);
show_tex_options(dialog);
break;
case RENDERER_CAIROGRAPHICS:
case RENDERER_CAIROGRAPHICS_PDF:
hide_tex_options(dialog);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo), TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf), TRUE);
break;
case RENDERER_CAIROGRAPHICS_SVG:
hide_tex_options(dialog);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg), TRUE);
break;
}
}
/** @} */

View File

@@ -17,6 +17,17 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file conv-settings-dialog.h
* @brief Header file for the Conversion Settings Dialog
* @author Mario.Huettel@gmx.net <mario.huettel@gmx.net>
*/
/**
* @addtogroup Widgets
* @{
*/
#ifndef __CONV_SETTINGS_DIALOG_H__
#define __CONV_SETTINGS_DIALOG_H__
@@ -24,25 +35,46 @@
G_BEGIN_DECLS
enum output_renderer {RENDERER_LATEX_TIKZ, RENDERER_CAIROGRAPHICS};
/** @brief return type of the RedererSettingsDialog */
enum output_renderer {RENDERER_LATEX_TIKZ, RENDERER_CAIROGRAPHICS_PDF, RENDERER_CAIROGRAPHICS_SVG};
G_DECLARE_FINAL_TYPE(RendererSettingsDialog, renderer_settings_dialog, RENDERER, SETTINGS_DIALOG, GtkDialog)
/**
* @brief Create a new RedererSettingsDialog GObject
* @param parent Parent window
* @return Created dialog object
*/
RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent);
#define RENDERER_TYPE_SETTINGS_DIALOG (renderer_settings_dialog_get_type())
/**
* @brief This struct holds the renderer configuration
*/
struct render_settings {
double scale;
enum output_renderer renderer;
gboolean tex_pdf_layers;
gboolean tex_standalone;
double scale; /**< @brief Scale image down by this factor. @note Used to keep image in bound of maximum coordinate limit */
enum output_renderer renderer; /**< The renderer to use */
gboolean tex_pdf_layers; /**< Create OCG layers when rendering with TikZ */
gboolean tex_standalone; /**< Create a standalone compile TeX file */
};
G_END_DECLS
/**
* @brief Apply settings to dialog
* @param dialog
* @param settings
*/
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
/**
* @brief Get the settings configured in the dialog
* @param dialog
* @param settings
*/
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
#endif /* __CONV_SETTINGS_DIALOG_H__ */
/** @} */

View File

@@ -17,6 +17,17 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file layer-element.c
* @brief Omplementation of the layer element used for configuring layer colors etc.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup Widgets
* @{
*/
#include "layer-element.h"
G_DEFINE_TYPE(LayerElement, layer_element, GTK_TYPE_LIST_BOX_ROW)
@@ -187,3 +198,5 @@ void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba)
{
gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(elem->priv.color), rgba);
}
/** @} */

View File

@@ -17,6 +17,17 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file layer-element.h
* @brief Omplementation of the layer element used for configuring layer colors etc.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup Widgets
* @{
*/
#ifndef __LAYER_ELEMENT_H__
#define __LAYER_ELEMENT_H__
@@ -45,17 +56,70 @@ struct _LayerElement {
LayerElementPriv priv;
};
/**
* @brief Create new layer element object
* @return new object
*/
GtkWidget *layer_element_new(void);
/**
* @brief get name of the layer
* @param elem Layer element
* @return Name. Must not be changed, freed or anything else.
*/
const char *layer_element_get_name(LayerElement *elem);
/**
* @brief layer_element_set_name
* @param elem set the name of the layer
* @param name Name. Can be freed after call to this function
*/
void layer_element_set_name(LayerElement *elem, const char* name);
/**
* @brief Set layer number for this layer
* @param elem Layer element
* @param layer Layer number
*/
void layer_element_set_layer(LayerElement *elem, int layer);
/**
* @brief Get layer number
* @param elem Layer Element
* @return Number of this layer
*/
int layer_element_get_layer(LayerElement *elem);
/**
* @brief Set export flag for this layer
* @param elem Layer Element
* @param export flag
*/
void layer_element_set_export(LayerElement *elem, gboolean export);
/**
* @brief Get export flag of layer
* @param elem Layer Element
* @return
*/
gboolean layer_element_get_export(LayerElement *elem);
/**
* @brief Get color of layer
* @param elem Layer Element
* @param rgba RGBA color
*/
void layer_element_get_color(LayerElement *elem, GdkRGBA *rgba);
/**
* @brief Set color of layer
* @param elem Layer Element
* @param rgba RGBA color
*/
void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba);
G_END_DECLS
#endif /* __LAYER_ELEMENT_H__ */
/** @} */