Compare commits

...

44 Commits

Author SHA1 Message Date
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
7c47d7207f add preliminary icon, configure icon in widgets 2018-07-25 10:50:22 +02:00
c502b65297 Doxygen Header created 2018-07-24 18:47:29 +02:00
5526e403a3 Disable prints in GDS renderer. Wrote documentation 2018-07-24 17:45:16 +02:00
5c3b299eb0 minor fixes and doxygen Documentation started 2018-07-24 14:42:28 +02:00
6f7feb7aa9 Add doxygen 2018-07-24 10:21:55 +02:00
13aa2c8609 fix typo 2018-07-23 21:16:01 +02:00
942df1d971 fix typo 2018-07-23 21:14:35 +02:00
50 changed files with 6810 additions and 176 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 *.exe
*.user *.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) cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0) pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0) pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(CAIRO REQUIRED cairo) pkg_check_modules(CAIRO REQUIRED cairo)
project(gds-render)
add_subdirectory(glade) add_subdirectory(glade)
add_subdirectory(doxygen)
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS}) include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS})
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})
aux_source_directory("widgets" LAYER_SOURCES) aux_source_directory("widgets" LAYER_SOURCES)
aux_source_directory("tree-renderer" RENDERER_SOURCES) aux_source_directory("tree-renderer" RENDERER_SOURCES)
aux_source_directory("gds-parser" PARSER_SOURCES) aux_source_directory("gds-parser" PARSER_SOURCES)
aux_source_directory("latex-output" LATEX_SOURCES) aux_source_directory("latex-output" LATEX_SOURCES)
aux_source_directory("cairo-output" CAIRO_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 set(SOURCE
${SOURCE} ${SOURCE}
@ -27,6 +28,7 @@ set(SOURCE
${PARSER_SOURCES} ${PARSER_SOURCES}
${LATEX_SOURCES} ${LATEX_SOURCES}
${CAIRO_SOURCES} ${CAIRO_SOURCES}
${TRIG_SOURCES}
) )
add_compile_options(-Wall) 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_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
add_dependencies(${PROJECT_NAME} glib-resources) add_dependencies(${PROJECT_NAME} glib-resources)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1) 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)

View File

@ -16,19 +16,37 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * 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>
*/
/** @addtogroup Cairo-Renderer
* @{
*/
#include "cairo-output.h" #include "cairo-output.h"
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <cairo.h> #include <cairo.h>
#include <cairo-pdf.h> #include <cairo-pdf.h>
#include <cairo-svg.h>
/**
* @brief The cairo_layer struct
* Each rendered layer is represented by this struct.
*/
struct cairo_layer { struct cairo_layer {
cairo_t *cr; cairo_t *cr; /**< @brief cairo context for layer*/
cairo_surface_t *rec; cairo_surface_t *rec; /**< @brief Recording surface to hold the layer */
struct layer_info *linfo; struct layer_info *linfo; /**< @brief Reference to layer information */
}; };
/**
* @brief Revert the last transformation on all layers
* @param layers Pointer to #cairo_layer structures
*/
static void revert_inherited_transform(struct cairo_layer *layers) static void revert_inherited_transform(struct cairo_layer *layers)
{ {
int i; int i;
@ -40,6 +58,15 @@ static void revert_inherited_transform(struct cairo_layer *layers)
} }
} }
/**
* @brief Applies transformation to all layers
* @param layers Array of layers
* @param origin Origin translation
* @param magnification Scaling
* @param flipping Mirror image on x-axis before rotating
* @param rotation Rotattion in degrees
* @param scale Scale the image down by. Only used for sclaing origin coordinates. Not applied to layer.
*/
static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers, static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
const struct gds_point *origin, const struct gds_point *origin,
double magnification, double magnification,
@ -64,6 +91,12 @@ static void apply_inherited_transform_to_all_layers(struct cairo_layer *layers,
} }
} }
/**
* @brief render_cell Render a cell with its sub-cells
* @param cell Cell to render
* @param layers Cell will be rendered into these layers
* @param scale sclae image down by this factor
*/
static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, double scale) static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, double scale)
{ {
GList *instance_list; GList *instance_list;
@ -145,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_surface_t *pdf_surface, *svg_surface;
cairo_t *pdf_cr; cairo_t *pdf_cr, *svg_cr;
struct layer_info *linfo; struct layer_info *linfo;
struct cairo_layer *layers; struct cairo_layer *layers;
struct cairo_layer *lay; struct cairo_layer *lay;
@ -157,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 rec_x0, rec_y0, rec_width, rec_height;
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN; 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)); layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
/* Clear layers */ /* Clear layers */
@ -214,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); 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_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
pdf_cr = cairo_create(pdf_surface); 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 */ /* Write layers to PDF */
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)) {
@ -226,13 +271,29 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
continue; continue;
} }
if (pdf_file) {
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);
} }
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_show_page(pdf_cr);
cairo_destroy(pdf_cr); cairo_destroy(pdf_cr);
cairo_surface_destroy(pdf_surface); 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: ret_clear_layers:
for (i = 0; i < MAX_LAYERS; i++) { for (i = 0; i < MAX_LAYERS; i++) {
@ -246,3 +307,5 @@ ret_clear_layers:
printf("cairo export finished. It might still be buggy!\n"); printf("cairo export finished. It might still be buggy!\n");
} }
/** @} */

View File

@ -16,15 +16,33 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file cairo-output.h
* @brief Header File for Cairo output renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __CAIRO_OUTPUT_H__ #ifndef __CAIRO_OUTPUT_H__
#define __CAIRO_OUTPUT_H__ #define __CAIRO_OUTPUT_H__
#include "../layer-selector.h" #include "../layer-selector.h"
#include "../gds-parser/gds-types.h" #include "../gds-parser/gds-types.h"
#define MAX_LAYERS (300) /** @addtogroup Cairo-Renderer
* @{
*/
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale); #define MAX_LAYERS (300) /**< \brief Maximum layer count the output renderer can process. Typically GDS only specifies up to 255 layers.*/
/**
* @brief Render \p cell to a PDF file specified by \p pdf_file
* @param cell Toplevel cell to @ref Cairo-Renderer
* @param layer_infos List of layer information. Specifies color and layer stacking
* @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_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale);
/** @} */
#endif /* __CAIRO_OUTPUT_H__ */ #endif /* __CAIRO_OUTPUT_H__ */

View File

@ -17,13 +17,31 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file command-line.c
* @brief Function to render according to command line parameters
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#include <stdio.h> #include <stdio.h>
#include "command-line.h" #include "command-line.h"
#include "gds-parser/gds-parser.h" #include "gds-parser/gds-parser.h"
#include "mapping-parser.h" #include "mapping-parser.h"
#include "cairo-output/cairo-output.h" #include "cairo-output/cairo-output.h"
#include "latex-output/latex-output.h" #include "latex-output/latex-output.h"
#include "external-renderer.h"
/**
* @brief Delete layer_info and free nem element.
*
* Like delete_layer_info_struct() but also frees layer_info::name
* @param info
*/
static void delete_layer_info_with_name(struct layer_info *info) static void delete_layer_info_with_name(struct layer_info *info)
{ {
if (info) { if (info) {
@ -34,7 +52,8 @@ static void delete_layer_info_with_name(struct layer_info *info)
} }
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex, 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; GList *libs = NULL;
FILE *tex_file; FILE *tex_file;
@ -53,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; struct gds_cell *toplevel_cell = NULL, *temp_cell;
/* Check if parameters are valid */ /* 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"); printf("Probably missing argument. Check --help option\n");
return; return;
} }
@ -113,8 +132,9 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
} }
/* Render outputs */ /* Render outputs */
if (pdf == TRUE) { if (pdf == TRUE || svg == TRUE) {
cairo_render_cell_to_pdf(toplevel_cell, layer_info_list, pdf_name, scale); 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) { if (tex == TRUE) {
@ -125,6 +145,16 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
fclose(tex_file); 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: ret_clear_list:
g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name); g_list_free_full(layer_info_list, (GDestroyNotify)delete_layer_info_with_name);
@ -135,3 +165,5 @@ destroy_file:
} }
/** @} */

View File

@ -17,11 +17,42 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file command-line.h
* @brief Render according to command line parameters
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#ifndef _COMMAND_LINE_H_ #ifndef _COMMAND_LINE_H_
#define _COMMAND_LINE_H_ #define _COMMAND_LINE_H_
#include <glib.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, 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_ */ #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)

2482
doxygen/Doxyconfig Normal file

File diff suppressed because it is too large Load Diff

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.
*/

View File

@ -0,0 +1,6 @@
/* This file only contains help information for doxygen */
/**
* @defgroup MainApplication Main Application
*
*/

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
*/

3
doxygen/output/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*
*/
!.gitignore

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

@ -18,14 +18,27 @@
*/ */
/* /*
*/
/**
* @file gds-parser.c
* @brief Implementation of the GDS-Parser
* @author Mario Hüttel <mario.huettel@gmx.net>
*
* What's missing? - A lot: * What's missing? - A lot:
* Support for Boxes
* Support for 4 Byte real * Support for 4 Byte real
* Support for pathtypes * Support for pathtypes
* Support for datatypes (only layer so far) * Support for datatypes (only layer so far)
* etc... * etc...
*/ */
/**
* @addtogroup GDS-Parser
* @{
*/
#include "gds-parser.h" #include "gds-parser.h"
#include <stdlib.h> #include <stdlib.h>
@ -35,10 +48,15 @@
#include <math.h> #include <math.h>
#include <cairo.h> #include <cairo.h>
#define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) #define GDS_ERROR(fmt, ...) printf("[PARSE_ERROR] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS error*/
#define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) #define GDS_WARN(fmt, ...) printf("[PARSE_WARNING] " fmt "\n", ##__VA_ARGS__) /**< @brief Print GDS warning */
enum record { #if GDS_PRINT_DEBUG_INFOS
#define GDS_INF(fmt, ...) printf(fmt, ##__VA_ARGS__) /**< @brief standard printf. But cna be disabled in code */
#else
#define GDS_INF(fmt, ...)
#endif
enum gds_record {
INVALID = 0x0000, INVALID = 0x0000,
HEADER = 0x0002, HEADER = 0x0002,
BGNLIB = 0x0102, BGNLIB = 0x0102,
@ -63,6 +81,13 @@ enum record {
PATHTYPE = 0x2102 PATHTYPE = 0x2102
}; };
/**
* @brief Name cell reference
* @param cell_inst Cell reference
* @param bytes Length of name
* @param data Name
* @return 0 if successful
*/
static int name_cell_ref(struct gds_cell_instance *cell_inst, static int name_cell_ref(struct gds_cell_instance *cell_inst,
unsigned int bytes, char *data) unsigned int bytes, char *data)
{ {
@ -73,7 +98,7 @@ static int name_cell_ref(struct gds_cell_instance *cell_inst,
return -1; return -1;
} }
data[bytes] = 0; // Append '0' data[bytes] = 0; // Append '0'
len = strlen(data); len = (int)strlen(data);
if (len > CELL_NAME_MAX-1) { if (len > CELL_NAME_MAX-1) {
GDS_ERROR("Cell name '%s' too long: %d\n", data, len); GDS_ERROR("Cell name '%s' too long: %d\n", data, len);
return -1; return -1;
@ -81,11 +106,16 @@ static int name_cell_ref(struct gds_cell_instance *cell_inst,
/* else: */ /* else: */
strcpy(cell_inst->ref_name, data); strcpy(cell_inst->ref_name, data);
printf("\tCell referenced: %s\n", cell_inst->ref_name); GDS_INF("\tCell referenced: %s\n", cell_inst->ref_name);
return 0; return 0;
} }
/**
* @brief Convert GDS 8-byte real to double
* @param data 8 Byte GDS real
* @return result
*/
static double gds_convert_double(const char *data) static double gds_convert_double(const char *data)
{ {
bool sign_bit; bool sign_bit;
@ -126,6 +156,11 @@ static double gds_convert_double(const char *data)
return ret_val; return ret_val;
} }
/**
* @brief Convert GDS INT32 to int
* @param data Buffer containing the int
* @return result
*/
static signed int gds_convert_signed_int(const char *data) static signed int gds_convert_signed_int(const char *data)
{ {
int ret; int ret;
@ -142,6 +177,11 @@ static signed int gds_convert_signed_int(const char *data)
return ret; return ret;
} }
/**
* @brief Convert GDS INT16 to int16
* @param data Buffer containing the INT16
* @return result
*/
static int16_t gds_convert_signed_int16(const char *data) static int16_t gds_convert_signed_int16(const char *data)
{ {
if (!data) { if (!data) {
@ -152,6 +192,11 @@ static int16_t gds_convert_signed_int16(const char *data)
(((int16_t)(data[1]) & 0xFF) << 0)); (((int16_t)(data[1]) & 0xFF) << 0));
} }
/**
* @brief Convert GDS UINT16 String to uint16
* @param data Buffer containing the uint16
* @return result
*/
static uint16_t gds_convert_unsigend_int16(const char *data) static uint16_t gds_convert_unsigend_int16(const char *data)
{ {
if (!data) { if (!data) {
@ -162,6 +207,12 @@ static uint16_t gds_convert_unsigend_int16(const char *data)
(((uint16_t)(data[1]) & 0xFF) << 0)); (((uint16_t)(data[1]) & 0xFF) << 0));
} }
/**
* @brief Append library to list
* @param curr_list List containing gds_library elements. May be NULL.
* @param library_ptr Return of newly created library.
* @return Newly created list pointer
*/
static GList *append_library(GList *curr_list, struct gds_library **library_ptr) static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
{ {
struct gds_library *lib; struct gds_library *lib;
@ -180,6 +231,13 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
return g_list_append(curr_list, lib); return g_list_append(curr_list, lib);
} }
/**
* @brief Append graphics to list
* @param curr_list List containing gds_graphics elements. May be NULL
* @param type Type of graphics
* @param graphics_ptr newly created graphic is written here
* @return new list pointer
*/
static GList *append_graphics(GList *curr_list, enum graphics_type type, static GList *append_graphics(GList *curr_list, enum graphics_type type,
struct gds_graphics **graphics_ptr) struct gds_graphics **graphics_ptr)
{ {
@ -202,6 +260,13 @@ static GList *append_graphics(GList *curr_list, enum graphics_type type,
return g_list_append(curr_list, gfx); return g_list_append(curr_list, gfx);
} }
/**
* @brief Appends vertext List
* @param curr_list List containing gds_point elements. May be NULL.
* @param x x-coordinate of new point
* @param y y-coordinate of new point
* @return new Pointer to List.
*/
static GList *append_vertex(GList *curr_list, int x, int y) static GList *append_vertex(GList *curr_list, int x, int y)
{ {
struct gds_point *vertex; struct gds_point *vertex;
@ -215,6 +280,14 @@ static GList *append_vertex(GList *curr_list, int x, int y)
return g_list_append(curr_list, vertex); return g_list_append(curr_list, vertex);
} }
/**
* @brief append_cell Append a gds_cell to a list
*
* Usage similar to append_cell_ref().
* @param curr_list List containing gds_cell elements. May be NULL
* @param cell_ptr newly created cell
* @return new pointer to list
*/
static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr) static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
{ {
struct gds_cell *cell; struct gds_cell *cell;
@ -233,6 +306,14 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
return g_list_append(curr_list, cell); return g_list_append(curr_list, cell);
} }
/**
* @brief Append a cell reference to the reference GList.
*
* Appends a new gds_cell_instance to \p curr_list and returns the new element via \p instance_ptr
* @param curr_list List of gds_cell_instance elements. May be NULL
* @param instance_ptr newly created element
* @return new GList pointer
*/
static GList *append_cell_ref(GList *curr_list, struct gds_cell_instance **instance_ptr) static GList *append_cell_ref(GList *curr_list, struct gds_cell_instance **instance_ptr)
{ {
struct gds_cell_instance *inst; struct gds_cell_instance *inst;
@ -254,6 +335,13 @@ static GList *append_cell_ref(GList *curr_list, struct gds_cell_instance **insta
return g_list_append(curr_list, inst); return g_list_append(curr_list, inst);
} }
/**
* @brief Name a gds_library
* @param current_library Library to name
* @param bytes Lenght of name
* @param data Name
* @return 0 if successful
*/
static int name_library(struct gds_library *current_library, static int name_library(struct gds_library *current_library,
unsigned int bytes, char *data) unsigned int bytes, char *data)
{ {
@ -265,18 +353,26 @@ static int name_library(struct gds_library *current_library,
} }
data[bytes] = 0; // Append '0' data[bytes] = 0; // Append '0'
len = strlen(data); len = (int)strlen(data);
if (len > CELL_NAME_MAX-1) { if (len > CELL_NAME_MAX-1) {
GDS_ERROR("Library name '%s' too long: %d\n", data, len); GDS_ERROR("Library name '%s' too long: %d\n", data, len);
return -1; return -1;
} }
strcpy(current_library->name, data); strcpy(current_library->name, data);
printf("Named library: %s\n", current_library->name); GDS_INF("Named library: %s\n", current_library->name);
return 0; return 0;
} }
/**
* @brief Names a gds_cell
* @param cell Cell to name
* @param bytes Length of name
* @param data Name
* @param lib Library in which \p cell is located
* @return 0 id successful
*/
static int name_cell(struct gds_cell *cell, unsigned int bytes, static int name_cell(struct gds_cell *cell, unsigned int bytes,
char *data, struct gds_library *lib) char *data, struct gds_library *lib)
{ {
@ -294,7 +390,7 @@ static int name_cell(struct gds_cell *cell, unsigned int bytes,
} }
strcpy(cell->name, data); strcpy(cell->name, data);
printf("Named cell: %s\n", cell->name); GDS_INF("Named cell: %s\n", cell->name);
/* Append cell name to lib's list of names */ /* Append cell name to lib's list of names */
lib->cell_names = g_list_append(lib->cell_names, cell->name); lib->cell_names = g_list_append(lib->cell_names, cell->name);
@ -302,7 +398,13 @@ static int name_cell(struct gds_cell *cell, unsigned int bytes,
return 0; return 0;
} }
/**
* @brief Search for cell reference \p gcell_ref in \p glibrary
*
* Search cell referenced by \p gcell_ref inside \p glibrary and update gds_cell_instance::cell_ref with found #gds_cell
* @param gcell_ref gpointer cast of struct gds_cell_instance *
* @param glibrary gpointer cast of struct gds_library *
*/
static void parse_reference_list(gpointer gcell_ref, gpointer glibrary) static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
{ {
struct gds_cell_instance *inst = (struct gds_cell_instance *)gcell_ref; struct gds_cell_instance *inst = (struct gds_cell_instance *)gcell_ref;
@ -310,7 +412,7 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
GList *cell_item; GList *cell_item;
struct gds_cell *cell; struct gds_cell *cell;
printf("\t\t\tReference: %s: ", inst->ref_name); GDS_INF("\t\t\tReference: %s: ", inst->ref_name);
/* Find cell */ /* Find cell */
for (cell_item = lib->cells; cell_item != NULL; for (cell_item = lib->cells; cell_item != NULL;
cell_item = cell_item->next) { cell_item = cell_item->next) {
@ -318,36 +420,56 @@ static void parse_reference_list(gpointer gcell_ref, gpointer glibrary)
cell = (struct gds_cell *)cell_item->data; cell = (struct gds_cell *)cell_item->data;
/* Check if cell is found */ /* Check if cell is found */
if (!strcmp(cell->name, inst->ref_name)) { if (!strcmp(cell->name, inst->ref_name)) {
printf("found\n"); GDS_INF("found\n");
/* update reference link */ /* update reference link */
inst->cell_ref = cell; inst->cell_ref = cell;
return; return;
} }
} }
printf("MISSING!\n"); GDS_INF("MISSING!\n");
GDS_WARN("referenced cell could not be found in library"); GDS_WARN("referenced cell could not be found in library");
} }
/**
* @brief Scans cell references inside cell
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 library Library where the cell references are searched in
*/
static void scan_cell_reference_dependencies(gpointer gcell, gpointer library) static void scan_cell_reference_dependencies(gpointer gcell, gpointer library)
{ {
struct gds_cell *cell = (struct gds_cell *)gcell; struct gds_cell *cell = (struct gds_cell *)gcell;
printf("\tScanning cell: %s\n", cell->name); GDS_INF("\tScanning cell: %s\n", cell->name);
/* 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);
} }
/**
* @brief Scans library's cell references
*
* This function searches all the references between cells and updates the gds_cell_instance::cell_ref field in each instance
* @param library_list_item List containing #gds_library elements
* @param user not used
*/
static void scan_library_references(gpointer library_list_item, gpointer user) static void scan_library_references(gpointer library_list_item, gpointer user)
{ {
struct gds_library *lib = (struct gds_library *)library_list_item; struct gds_library *lib = (struct gds_library *)library_list_item;
printf("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_reference_dependencies, lib);
} }
/**
* @brief gds_parse_date
* @param buffer Buffer that contains the GDS Date field
* @param length Length of \p buffer
* @param mod_date Modification Date
* @param access_date Last Access Date
*/
static void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date) static void gds_parse_date(const char *buffer, int length, struct gds_time_field *mod_date, struct gds_time_field *access_date)
{ {
@ -390,7 +512,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
int run = 1; int run = 1;
FILE *gds_file = NULL; FILE *gds_file = NULL;
uint16_t rec_data_length; uint16_t rec_data_length;
enum record rec_type; enum gds_record rec_type;
struct gds_library *current_lib = NULL; struct gds_library *current_lib = NULL;
struct gds_cell *current_cell = NULL; struct gds_cell *current_cell = NULL;
struct gds_graphics *current_graphics = NULL; struct gds_graphics *current_graphics = NULL;
@ -466,7 +588,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
} }
printf("Entering Lib\n"); GDS_INF("Entering Lib\n");
break; break;
case ENDLIB: case ENDLIB:
if (current_lib == NULL) { if (current_lib == NULL) {
@ -482,7 +604,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
} }
current_lib = NULL; current_lib = NULL;
printf("Leaving Library\n"); GDS_INF("Leaving Library\n");
break; break;
case BGNSTR: case BGNSTR:
current_lib->cells = append_cell(current_lib->cells, &current_cell); current_lib->cells = append_cell(current_lib->cells, &current_cell);
@ -491,7 +613,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -3; run = -3;
break; break;
} }
printf("Entering Cell\n"); GDS_INF("Entering Cell\n");
break; break;
case ENDSTR: case ENDSTR:
if (current_cell == NULL) { if (current_cell == NULL) {
@ -506,7 +628,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
} }
current_cell = NULL; current_cell = NULL;
printf("Leaving Cell\n"); GDS_INF("Leaving Cell\n");
break; break;
case BOX: case BOX:
case BOUNDARY: case BOUNDARY:
@ -523,7 +645,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -4; run = -4;
break; break;
} }
printf("\tEntering boundary/Box\n"); GDS_INF("\tEntering boundary/Box\n");
break; break;
case SREF: case SREF:
if (current_cell == NULL) { if (current_cell == NULL) {
@ -539,7 +661,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break; break;
} }
printf("\tEntering reference\n"); GDS_INF("\tEntering reference\n");
break; break;
case PATH: case PATH:
if (current_cell == NULL) { if (current_cell == NULL) {
@ -554,16 +676,16 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -4; run = -4;
break; break;
} }
printf("\tEntering Path\n"); GDS_INF("\tEntering Path\n");
break; break;
case ENDEL: case ENDEL:
if (current_graphics != NULL) { if (current_graphics != NULL) {
printf("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path")); GDS_INF("\tLeaving %s\n", (current_graphics->gfx_type == GRAPHIC_POLYGON ? "boundary" : "path"));
current_graphics = NULL; current_graphics = NULL;
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
printf("\tLeaving Reference\n"); GDS_INF("\tLeaving Reference\n");
current_s_reference = NULL; current_s_reference = NULL;
} }
break; break;
@ -628,17 +750,17 @@ int parse_gds_from_file(const char *filename, GList **library_list)
gds_parse_date(workbuff, read, &current_cell->mod_time, &current_cell->access_time); gds_parse_date(workbuff, read, &current_cell->mod_time, &current_cell->access_time);
break; break;
case LIBNAME: case LIBNAME:
name_library(current_lib, read, workbuff); name_library(current_lib, (unsigned int)read, workbuff);
break; break;
case STRNAME: case STRNAME:
name_cell(current_cell, read, workbuff, current_lib); name_cell(current_cell, (unsigned int)read, workbuff, current_lib);
break; break;
case XY: case XY:
if (current_s_reference) { if (current_s_reference) {
/* Get origin of reference */ /* Get origin of reference */
current_s_reference->origin.x = gds_convert_signed_int(workbuff); current_s_reference->origin.x = gds_convert_signed_int(workbuff);
current_s_reference->origin.y = gds_convert_signed_int(&workbuff[4]); current_s_reference->origin.y = gds_convert_signed_int(&workbuff[4]);
printf("\t\tSet origin to: %d/%d\n", current_s_reference->origin.x, GDS_INF("\t\tSet origin to: %d/%d\n", current_s_reference->origin.x,
current_s_reference->origin.y); current_s_reference->origin.y);
} else if (current_graphics) { } else if (current_graphics) {
for (i = 0; i < read/8; i++) { for (i = 0; i < read/8; i++) {
@ -646,7 +768,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
y = gds_convert_signed_int(&workbuff[i*8+4]); y = gds_convert_signed_int(&workbuff[i*8+4]);
current_graphics->vertices = current_graphics->vertices =
append_vertex(current_graphics->vertices, x, y); append_vertex(current_graphics->vertices, x, y);
printf("\t\tSet coordinate: %d/%d\n", x, y); GDS_INF("\t\tSet coordinate: %d/%d\n", x, y);
} }
} }
@ -677,7 +799,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
if (current_graphics->layer < 0) { if (current_graphics->layer < 0) {
GDS_WARN("Layer negative!\n"); GDS_WARN("Layer negative!\n");
} }
printf("\t\tAdded layer %d\n", (int)current_graphics->layer); GDS_INF("\t\tAdded layer %d\n", (int)current_graphics->layer);
break; break;
case MAG: case MAG:
if (rec_data_length != 8) { if (rec_data_length != 8) {
@ -690,7 +812,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
current_s_reference->magnification = gds_convert_double(workbuff); current_s_reference->magnification = gds_convert_double(workbuff);
printf("\t\tMagnification defined: %lf\n", current_s_reference->magnification); GDS_INF("\t\tMagnification defined: %lf\n", current_s_reference->magnification);
} }
break; break;
case ANGLE: case ANGLE:
@ -704,7 +826,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} }
if (current_s_reference != NULL) { if (current_s_reference != NULL) {
current_s_reference->angle = gds_convert_double(workbuff); current_s_reference->angle = gds_convert_double(workbuff);
printf("\t\tAngle defined: %lf\n", current_s_reference->angle); GDS_INF("\t\tAngle defined: %lf\n", current_s_reference->angle);
} }
break; break;
case PATHTYPE: case PATHTYPE:
@ -714,7 +836,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
} }
if (current_graphics->gfx_type == GRAPHIC_PATH) { if (current_graphics->gfx_type == GRAPHIC_PATH) {
current_graphics->path_render_type = (int)gds_convert_signed_int16(workbuff); current_graphics->path_render_type = (int)gds_convert_signed_int16(workbuff);
printf("\t\tPathtype: %d\n", current_graphics->path_render_type); GDS_INF("\t\tPathtype: %d\n", current_graphics->path_render_type);
} else { } else {
GDS_WARN("Path type defined inside non-path graphics object. Ignoring"); GDS_WARN("Path type defined inside non-path graphics object. Ignoring");
} }
@ -742,22 +864,38 @@ int parse_gds_from_file(const char *filename, GList **library_list)
return run; return run;
} }
/**
* @brief delete_cell_inst_element
* @param cell_inst
*/
static void delete_cell_inst_element(struct gds_cell_instance *cell_inst) static void delete_cell_inst_element(struct gds_cell_instance *cell_inst)
{ {
free(cell_inst); free(cell_inst);
} }
/**
* @brief delete_vertex
* @param vertex
*/
static void delete_vertex(struct gds_point *vertex) static void delete_vertex(struct gds_point *vertex)
{ {
free(vertex); free(vertex);
} }
/**
* @brief delete_graphics_obj
* @param gfx
*/
static void delete_graphics_obj(struct gds_graphics *gfx) static void delete_graphics_obj(struct gds_graphics *gfx)
{ {
g_list_free_full(gfx->vertices, (GDestroyNotify)delete_vertex); g_list_free_full(gfx->vertices, (GDestroyNotify)delete_vertex);
free(gfx); free(gfx);
} }
/**
* @brief delete_cell_element
* @param cell
*/
static void delete_cell_element(struct gds_cell *cell) static void delete_cell_element(struct gds_cell *cell)
{ {
g_list_free_full(cell->child_cells, (GDestroyNotify)delete_cell_inst_element); g_list_free_full(cell->child_cells, (GDestroyNotify)delete_cell_inst_element);
@ -765,6 +903,10 @@ static void delete_cell_element(struct gds_cell *cell)
free(cell); free(cell);
} }
/**
* @brief delete_library_element
* @param lib
*/
static void delete_library_element(struct gds_library *lib) static void delete_library_element(struct gds_library *lib)
{ {
g_list_free(lib->cell_names); g_list_free(lib->cell_names);
@ -780,3 +922,5 @@ int clear_lib_list(GList **library_list)
*library_list = NULL; *library_list = NULL;
return 0; return 0;
} }
/** @} */

View File

@ -17,13 +17,33 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file gds-parser.h
* @brief Header file for the GDS-Parser
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup GDS-Parser
* @{
*/
#ifndef __GDSPARSE_H__ #ifndef __GDSPARSE_H__
#define __GDSPARSE_H__ #define __GDSPARSE_H__
#include <glib.h> #include <glib.h>
#include "gds-types.h" #include "gds-types.h"
#define GDS_PRINT_DEBUG_INFOS (0) /**< @brief 1: Print infos, 0: Don't print */
int parse_gds_from_file(const char *filename, GList **library_array); int parse_gds_from_file(const char *filename, GList **library_array);
/**
* @brief Deletes all libraries including cells, references etc.
* @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); int clear_lib_list(GList **library_list);
/** @} */
#endif /* __GDSPARSE_H__ */ #endif /* __GDSPARSE_H__ */

View File

@ -1,21 +1,67 @@
/*
* 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-types.h
* @brief Defines types and macros used by the GDS-Parser
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup GDS-Parser
* @{
*/
#ifndef __GDS_TYPES_H__ #ifndef __GDS_TYPES_H__
#define __GDS_TYPES_H__ #define __GDS_TYPES_H__
#include <stdint.h> #include <stdint.h>
#include <glib.h> #include <glib.h>
#define CELL_NAME_MAX (100) #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)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */
enum graphics_type {GRAPHIC_PATH = 0, GRAPHIC_POLYGON = 1, GRAPHIC_BOX}; /** @brief Types of graphic objects */
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2}; enum graphics_type
{
GRAPHIC_PATH = 0, /**< @brief Path. Esentially a line */
GRAPHIC_POLYGON = 1, /**< @brief An arbitrary polygon */
GRAPHIC_BOX = 2 /**< @brief A rectangle. @warning Implementation in renderers might be buggy!*/
};
/**
* @brief Defines the line caps of a path
*/
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2}; /**< Path line caps */
/**
* @brief A point in the 2D plane. Sometimes references as vertex
*/
struct gds_point { struct gds_point {
int x; int x;
int y; int y;
}; };
/**
* @brief Date information for cells and libraries
*/
struct gds_time_field { struct gds_time_field {
uint16_t year; uint16_t year;
uint16_t month; uint16_t month;
@ -25,39 +71,53 @@ struct gds_time_field {
uint16_t second; uint16_t second;
}; };
/**
* @brief A GDS graphics object
*/
struct gds_graphics { struct gds_graphics {
enum graphics_type gfx_type; enum graphics_type gfx_type; /**< \brief Type of graphic */
GList *vertices; GList *vertices; /**< @brief List of #gds_point */
enum path_type path_render_type; enum path_type path_render_type; /**< @brief Line cap */
int width_absolute; int width_absolute; /**< @brief Width. Not used for objects other than paths */
int16_t layer; int16_t layer; /**< @brief Layer the graphic object is on */
uint16_t datatype; uint16_t datatype;
}; };
/**
* @brief This represents an instanc of a cell inside another cell
*/
struct gds_cell_instance { struct gds_cell_instance {
char ref_name[CELL_NAME_MAX]; char ref_name[CELL_NAME_MAX]; /**< @brief Name of referenced cell */
struct gds_cell *cell_ref; struct gds_cell *cell_ref; /**< @brief Referenced gds_cell structure */
struct gds_point origin; struct gds_point origin; /**< @brief Origin */
int flipped; int flipped; /**< @brief Mirrored on x-axis before rotation */
double angle; double angle; /**< @brief Angle of rotation (counter clockwise) in degrees */
double magnification; double magnification; /**< @brief magnification */
}; };
/**
* @brief A Cell inside a gds_library
*/
struct gds_cell { struct gds_cell {
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;
GList *child_cells; GList *child_cells; /**< @brief List of #gds_cell_instance elements */
GList *graphic_objs; GList *graphic_objs; /**< @brief List of #gds_graphics */
}; };
/**
* @brief GDS Toplevel library
*/
struct gds_library { 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;
double unit_to_meters; double unit_to_meters; /**< @warning not yet implemented */
GList *cells; GList *cells; /**< List of #gds_cell that contains all cells in this library*/
GList *cell_names; GList *cell_names /**< List of strings that contains all cell names */;
}; };
/** @} */
#endif /* __GDS_TYPES_H__ */ #endif /* __GDS_TYPES_H__ */

View File

@ -10,7 +10,7 @@
<property name="website">https://git.shimatta.de/mhu/gds-render</property> <property name="website">https://git.shimatta.de/mhu/gds-render</property>
<property name="website_label" translatable="yes">Git Repository</property> <property name="website_label" translatable="yes">Git Repository</property>
<property name="authors">Mario Hüttel &lt;mario.huettel@gmx.net&gt;</property> <property name="authors">Mario Hüttel &lt;mario.huettel@gmx.net&gt;</property>
<property name="logo_icon_name">applications-graphics</property> <property name="logo_icon_name">gds-render</property>
<property name="license_type">gpl-2-0-only</property> <property name="license_type">gpl-2-0-only</property>
<child> <child>
<placeholder/> <placeholder/>

View File

@ -16,6 +16,7 @@
<child> <child>
<object class="GtkRadioButton" id="latex-radio"> <object class="GtkRadioButton" id="latex-radio">
<property name="label" translatable="yes">Generate LaTeX/TikZ output</property> <property name="label" translatable="yes">Generate LaTeX/TikZ output</property>
<property name="use_action_appearance">True</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>
@ -29,8 +30,9 @@
</packing> </packing>
</child> </child>
<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="label" translatable="yes">Render PDF using Cairographics</property>
<property name="use_action_appearance">True</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>
@ -44,6 +46,24 @@
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </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> <child>
<object class="GtkScale" id="dialog-scale"> <object class="GtkScale" id="dialog-scale">
<property name="visible">True</property> <property name="visible">True</property>
@ -55,7 +75,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">2</property> <property name="position">3</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -69,7 +89,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">3</property> <property name="position">4</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -83,7 +103,7 @@
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">True</property>
<property name="position">4</property> <property name="position">5</property>
</packing> </packing>
</child> </child>
</object> </object>

View File

@ -5,13 +5,14 @@
<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>
<child type="titlebar"> <child type="titlebar">
<object class="GtkHeaderBar"> <object class="GtkHeaderBar">
<property name="name">header</property> <property name="name">header</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="title" translatable="yes">GDS Renderer</property> <property name="title" translatable="yes">GDS Renderer</property>
<property name="subtitle" translatable="yes">GDSII to PDF Converter</property> <property name="subtitle" translatable="yes">GDSII to PDF/TikZ Converter</property>
<property name="show_close_button">True</property> <property name="show_close_button">True</property>
<child> <child>
<object class="GtkButton" id="button-load-gds"> <object class="GtkButton" id="button-load-gds">

BIN
icon/128x128/gds-render.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

479
icon/gds-render.svg Normal file
View File

@ -0,0 +1,479 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30mm"
height="30mm"
viewBox="0 0 30.000001 29.999999"
version="1.1"
id="svg8"
inkscape:version="0.92.2 2405546, 2018-03-11"
sodipodi:docname="gds-render.svg"
inkscape:export-filename="/home/mari/projects/cpp/gds-render/icon/22x22/gds-render.png"
inkscape:export-xdpi="18.62639"
inkscape:export-ydpi="18.62639">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="123.37499"
inkscape:cy="62.837322"
inkscape:document-units="mm"
inkscape:current-layer="layer2"
showgrid="false"
units="mm"
inkscape:window-width="2880"
inkscape:window-height="1508"
inkscape:window-x="0"
inkscape:window-y="38"
inkscape:window-maximized="1" />
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4825-0">
<stop
style="stop-color:#c4a000;stop-opacity:1"
offset="0"
id="stop4821" />
<stop
style="stop-color:#c4a000;stop-opacity:0"
offset="1"
id="stop4823" />
</linearGradient>
<linearGradient
osb:paint="solid"
id="linearGradient4788">
<stop
id="stop4786"
offset="0"
style="stop-color:#c4a000;stop-opacity:1;" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="298.01938"
x2="29.850964"
y1="268.53937"
x1="1.6864967"
id="linearGradient4806"
xlink:href="#linearGradient4825-0"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="261.9151"
x2="7.7163501"
y1="298.01938"
x1="29.850964"
id="linearGradient4833"
xlink:href="#linearGradient4825-0"
inkscape:collect="always" />
<g
id="g4922">
<symbol
id="lx-text4864-glyph0-0"
overflow="visible"
style="overflow:visible">
<path
id="path4892"
d=""
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-1"
overflow="visible"
style="overflow:visible">
<path
id="path4895"
d="m 7.78125,-2.359375 c 0,-0.46875 0.046875,-0.53125 0.8125,-0.53125 v -0.34375 c -0.3125,0.015625 -1.140625,0.015625 -1.5,0.015625 -0.375,0 -1.421875,0 -1.734375,-0.015625 v 0.34375 H 5.71875 c 1.0625,0 1.09375,0.140625 1.09375,0.578125 v 0.765625 c 0,1.359375 -1.5625,1.453125 -1.875,1.453125 -0.9375,0 -3.1875,-0.578125 -3.1875,-4 0,-3.453125 2.265625,-3.96875 3.109375,-3.96875 1.03125,0 2.28125,0.75 2.59375,2.859375 0.015625,0.140625 0.015625,0.171875 0.15625,0.171875 0.171875,0 0.171875,-0.03125 0.171875,-0.28125 v -2.828125 c 0,-0.21875 0,-0.28125 -0.125,-0.28125 -0.0625,0 -0.078125,0.03125 -0.15625,0.15625 l -0.578125,0.9375 C 6.578125,-7.75 5.84375,-8.421875 4.703125,-8.421875 c -2.15625,0 -4.0625,1.890625 -4.0625,4.328125 0,2.484375 1.90625,4.34375 4.078125,4.34375 0.84375,0 1.8125,-0.28125 2.265625,-1.03125 0.21875,0.375 0.609375,0.765625 0.703125,0.765625 0.09375,0 0.09375,-0.0625 0.09375,-0.265625 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-2"
overflow="visible"
style="overflow:visible">
<path
id="path4898"
d="m 0.5,-8.15625 v 0.34375 h 0.234375 c 0.875,0 0.90625,0.109375 0.90625,0.5625 v 6.34375 c 0,0.4375 -0.03125,0.5625 -0.90625,0.5625 H 0.5 V 0 h 4.1875 c 2,0 3.59375,-1.796875 3.59375,-4 0,-2.3125 -1.609375,-4.15625 -3.59375,-4.15625 z m 2.625,7.8125 c -0.515625,0 -0.546875,-0.09375 -0.546875,-0.484375 V -7.34375 c 0,-0.390625 0.03125,-0.46875 0.546875,-0.46875 h 1.265625 c 0.984375,0 1.78125,0.46875 2.265625,1.265625 0.546875,0.84375 0.546875,2.046875 0.546875,2.53125 0,0.671875 -0.015625,1.796875 -0.703125,2.671875 -0.390625,0.5 -1.109375,1 -2.109375,1 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-3"
overflow="visible"
style="overflow:visible">
<path
id="path4901"
d="M 2.484375,-4.984375 C 1.875,-5.140625 1.34375,-5.734375 1.34375,-6.5 c 0,-0.84375 0.671875,-1.59375 1.59375,-1.59375 1.96875,0 2.21875,1.9375 2.296875,2.453125 0.03125,0.140625 0.03125,0.1875 0.140625,0.1875 0.140625,0 0.140625,-0.0625 0.140625,-0.265625 v -2.421875 c 0,-0.21875 0,-0.28125 -0.125,-0.28125 -0.03125,0 -0.078125,0 -0.171875,0.15625 L 4.828125,-7.53125 C 4.25,-8.265625 3.46875,-8.421875 2.9375,-8.421875 c -1.328125,0 -2.296875,1.078125 -2.296875,2.296875 0,0.5625 0.203125,1.09375 0.65625,1.578125 0.40625,0.453125 0.828125,0.5625 1.671875,0.78125 0.421875,0.09375 1.078125,0.265625 1.25,0.328125 0.5625,0.28125 0.9375,0.921875 0.9375,1.59375 0,0.90625 -0.640625,1.75 -1.625,1.75 -0.546875,0 -1.28125,-0.140625 -1.875,-0.640625 -0.6875,-0.625 -0.734375,-1.484375 -0.75,-1.890625 -0.015625,-0.09375 -0.109375,-0.09375 -0.125,-0.09375 -0.140625,0 -0.140625,0.0625 -0.140625,0.28125 v 2.40625 c 0,0.21875 0,0.28125 0.125,0.28125 C 0.84375,0.25 0.84375,0.234375 0.9375,0.078125 0.984375,-0.015625 1.234375,-0.453125 1.328125,-0.640625 1.75,-0.15625 2.515625,0.25 3.53125,0.25 4.875,0.25 5.84375,-0.890625 5.84375,-2.203125 5.84375,-2.921875 5.5625,-3.46875 5.25,-3.859375 4.8125,-4.40625 4.265625,-4.53125 3.796875,-4.65625 Z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-4"
overflow="visible"
style="overflow:visible">
<path
id="path4904"
d="M 3.234375,-2.265625 V -2.90625 H 0.125 v 0.640625 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-5"
overflow="visible"
style="overflow:visible">
<path
id="path4907"
d="m 5.046875,-4.0625 c 1.1875,-0.28125 2.09375,-1.03125 2.09375,-1.953125 0,-1.15625 -1.34375,-2.140625 -3.0625,-2.140625 H 0.5 v 0.34375 h 0.234375 c 0.875,0 0.90625,0.109375 0.90625,0.5625 v 6.34375 c 0,0.4375 -0.03125,0.5625 -0.90625,0.5625 H 0.5 V 0 c 0.28125,-0.03125 1.25,-0.03125 1.609375,-0.03125 0.34375,0 1.328125,0 1.609375,0.03125 V -0.34375 H 3.484375 c -0.859375,0 -0.90625,-0.125 -0.90625,-0.5625 v -3.0625 H 3.96875 c 0.46875,0 0.90625,0.125 1.234375,0.46875 0.40625,0.453125 0.40625,0.703125 0.40625,1.53125 0,0.9375 0,1.25 0.515625,1.765625 C 6.3125,-0.03125 6.8125,0.25 7.484375,0.25 c 0.9375,0 1.09375,-1.03125 1.09375,-1.296875 0,-0.0625 0,-0.171875 -0.140625,-0.171875 -0.125,0 -0.125,0.078125 -0.125,0.1875 C 8.25,-0.3125 7.90625,0.015625 7.515625,0.015625 6.96875,0.015625 6.84375,-0.546875 6.75,-1.1875 6.734375,-1.265625 6.671875,-1.78125 6.640625,-2.078125 6.546875,-2.671875 6.5,-3.0625 6.140625,-3.4375 c -0.125,-0.125 -0.4375,-0.453125 -1.09375,-0.625 z m -1.125,-0.140625 H 2.578125 V -7.34375 c 0,-0.265625 0,-0.40625 0.25,-0.46875 0.109375,0 0.46875,0 0.703125,0 0.96875,0 2.5,0 2.5,1.796875 0,1.046875 -0.5625,1.8125 -2.109375,1.8125 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-6"
overflow="visible"
style="overflow:visible">
<path
id="path4910"
d="m 4.578125,-2.765625 c 0.265625,0 0.28125,0 0.28125,-0.234375 0,-1.203125 -0.640625,-2.328125 -2.09375,-2.328125 -1.359375,0 -2.40625,1.234375 -2.40625,2.703125 0,1.578125 1.21875,2.75 2.546875,2.75 1.421875,0 1.953125,-1.296875 1.953125,-1.546875 0,-0.078125 -0.046875,-0.125 -0.125,-0.125 -0.09375,0 -0.125,0.0625 -0.140625,0.125 -0.3125,1 -1.109375,1.28125 -1.625,1.28125 -0.5,0 -1.703125,-0.34375 -1.703125,-2.40625 v -0.21875 z M 1.28125,-3 c 0.09375,-1.875 1.140625,-2.09375 1.484375,-2.09375 1.28125,0 1.34375,1.6875 1.359375,2.09375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-7"
overflow="visible"
style="overflow:visible">
<path
id="path4913"
d="m 5.3125,-2.90625 c 0,-1.109375 0,-1.4375 -0.265625,-1.828125 -0.34375,-0.46875 -0.90625,-0.53125 -1.3125,-0.53125 -1.171875,0 -1.625,0.984375 -1.71875,1.21875 v -1.21875 l -1.640625,0.125 v 0.34375 c 0.8125,0 0.921875,0.09375 0.921875,0.671875 v 3.234375 c 0,0.546875 -0.140625,0.546875 -0.921875,0.546875 V 0 c 0.3125,-0.03125 0.96875,-0.03125 1.296875,-0.03125 0.34375,0 1,0 1.296875,0.03125 v -0.34375 c -0.75,0 -0.90625,0 -0.90625,-0.546875 v -2.21875 c 0,-1.25 0.828125,-1.921875 1.578125,-1.921875 0.734375,0 0.90625,0.609375 0.90625,1.34375 v 2.796875 c 0,0.546875 -0.140625,0.546875 -0.90625,0.546875 V 0 c 0.296875,-0.03125 0.953125,-0.03125 1.28125,-0.03125 0.34375,0 1,0 1.3125,0.03125 v -0.34375 c -0.609375,0 -0.90625,0 -0.921875,-0.359375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-8"
overflow="visible"
style="overflow:visible">
<path
id="path4916"
d="M 3.578125,-8.15625 V -7.8125 C 4.40625,-7.8125 4.5,-7.734375 4.5,-7.140625 V -4.5 C 4.25,-4.859375 3.734375,-5.265625 3,-5.265625 c -1.390625,0 -2.578125,1.171875 -2.578125,2.703125 0,1.515625 1.125,2.6875 2.453125,2.6875 0.90625,0 1.421875,-0.609375 1.59375,-0.828125 V 0.125 L 6.15625,0 V -0.34375 C 5.34375,-0.34375 5.25,-0.4375 5.25,-1.015625 v -7.28125 z m 0.890625,6.75 c 0,0.21875 0,0.265625 -0.171875,0.515625 -0.28125,0.421875 -0.765625,0.765625 -1.375,0.765625 -0.296875,0 -1.59375,-0.109375 -1.59375,-2.4375 0,-0.859375 0.140625,-1.328125 0.40625,-1.734375 0.234375,-0.359375 0.71875,-0.734375 1.3125,-0.734375 0.75,0 1.15625,0.53125 1.28125,0.734375 0.140625,0.203125 0.140625,0.21875 0.140625,0.4375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="lx-text4864-glyph0-9"
overflow="visible"
style="overflow:visible">
<path
id="path4919"
d="m 2,-2.78125 c 0,-1.15625 0.46875,-2.25 1.390625,-2.25 0.09375,0 0.125,0 0.171875,0.015625 -0.09375,0.046875 -0.28125,0.109375 -0.28125,0.4375 0,0.34375 0.265625,0.484375 0.453125,0.484375 0.25,0 0.484375,-0.15625 0.484375,-0.484375 0,-0.359375 -0.328125,-0.6875 -0.84375,-0.6875 -1.015625,0 -1.359375,1.09375 -1.421875,1.328125 H 1.9375 v -1.328125 l -1.609375,0.125 v 0.34375 c 0.8125,0 0.921875,0.09375 0.921875,0.671875 v 3.234375 c 0,0.546875 -0.140625,0.546875 -0.921875,0.546875 V 0 c 0.34375,-0.03125 1,-0.03125 1.359375,-0.03125 0.328125,0 1.171875,0 1.4375,0.03125 V -0.34375 H 2.890625 C 2.015625,-0.34375 2,-0.484375 2,-0.90625 Z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
</g>
</defs>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
sodipodi:insensitive="true"
style="display:inline"
transform="translate(0,-267.00004)"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1">
<rect
ry="4.8109269"
y="267.27731"
x="0.27727795"
height="29.445444"
width="29.445444"
id="rect863"
style="fill:url(#linearGradient4833);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient4806);stroke-width:0.55500001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
style="display:inline"
inkscape:label="GDS"
id="layer2"
inkscape:groupmode="layer"
sodipodi:insensitive="true">
<g
transform="matrix(1.1803494,0,0,1.1803494,-3.0934521,2.5343859)"
id="g4860">
<rect
style="fill:#5c3566;fill-opacity:1;fill-rule:nonzero;stroke:#5c3566;stroke-width:0.03089017;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4722-9"
width="7.315506"
height="2.6185424"
x="17.855755"
y="2.8206506" />
<rect
style="fill:#5c3566;fill-opacity:1;fill-rule:nonzero;stroke:#5c3566;stroke-width:0.03089017;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4722"
width="7.315506"
height="2.6185424"
x="5.0017018"
y="2.8206506" />
<rect
style="fill:#729fcf;fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.18781857;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4647"
width="21.451309"
height="5.3823962"
x="4.4756289"
y="5.5161438"
ry="0.57490903" />
<path
style="fill:#5c3566;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.4249042;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.647111,2.1885173 c 1.371044,1.5346563 7.602828,2.1172607 8.900202,0 V 5.445367 h -8.900202 z"
id="rect4673"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:0.09766429;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 10.743177,2.1889465 v 1.1220392 l 1.692999,1.126e-4 0.846062,1.2390311 h 1.693 2.051725 l 0.826813,-1.2343732 h 1.693537 V 2.1885173 H 17.515176 L 16.669114,3.4240551 H 14.975238 13.620839 L 12.7949,2.1885173 Z"
id="path4655"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccc" />
<path
style="fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:0.12909999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 10.444636,4.7267469 9.7322177,4.2143924 8.4348855,4.2137428 7.1896962,2.1729032 H 4.4609914 v 1.1220392 h 1.6548333 l 0.8269886,2.1548987 h 1.6548343 l 1.8914814,0.011475 z"
id="path4655-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
<rect
style="fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:#cc0000;stroke-width:0.03570647;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4703"
width="2.6473525"
height="0.67746186"
x="13.879735"
y="4.5986104"
ry="0" />
<path
style="fill:#f57900;fill-opacity:1;stroke:#ce5c00;stroke-width:0.13003762;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 19.828607,4.7038749 0.722805,-0.5123545 1.316244,-6.495e-4 1.263343,-2.0408398 h 2.768485 v 1.1220392 h -1.678958 l -0.839046,2.154899 h -1.678958 l -1.919057,0.011474 z"
id="path4655-6-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
<path
style="fill:#4e9a06;fill-opacity:1;fill-rule:nonzero;stroke:#73d216;stroke-width:0.06713366;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 6.5082658,5.4557442 v 1.4172746 1.225227 l 0.038859,0.1943268 v 0 c 0.128985,0.3512949 0.5947729,0.6114739 1.1565142,0.6114739 h 5.351728 c 0.561743,0 1.063373,-0.2021525 1.192356,-0.5534475 l 0.0031,-0.058026 V 8.0982458 6.8730188 5.4557442 Z"
id="rect4739"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccsscccccc" />
<path
style="fill:#4e9a06;fill-opacity:1;fill-rule:nonzero;stroke:#73d216;stroke-width:0.0674862;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 16.02714,5.4330487 v 1.4171297 1.2251018 l 0.03927,0.1943069 v 0 c 0.13036,0.3512589 0.601098,0.6114113 1.168812,0.6114113 h 5.408637 c 0.567714,0 1.074679,-0.2021319 1.205035,-0.5533908 l 0.0031,-0.05802 V 8.0752802 6.8501784 5.4330487 Z"
id="rect4739-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccsscccccc" />
</g>
<g
id="lx-text4864"
transform="matrix(0.38106292,0,0,0.38106292,2.3851025,22.428875)">
<defs
id="defs4924">
<g
id="g5236">
<symbol
id="symbol5198"
overflow="visible"
style="overflow:visible">
<path
id="path5196"
d=""
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5202"
overflow="visible"
style="overflow:visible">
<path
id="path5200"
d="m 7.78125,-2.359375 c 0,-0.46875 0.046875,-0.53125 0.8125,-0.53125 v -0.34375 c -0.3125,0.015625 -1.140625,0.015625 -1.5,0.015625 -0.375,0 -1.421875,0 -1.734375,-0.015625 v 0.34375 H 5.71875 c 1.0625,0 1.09375,0.140625 1.09375,0.578125 v 0.765625 c 0,1.359375 -1.5625,1.453125 -1.875,1.453125 -0.9375,0 -3.1875,-0.578125 -3.1875,-4 0,-3.453125 2.265625,-3.96875 3.109375,-3.96875 1.03125,0 2.28125,0.75 2.59375,2.859375 0.015625,0.140625 0.015625,0.171875 0.15625,0.171875 0.171875,0 0.171875,-0.03125 0.171875,-0.28125 v -2.828125 c 0,-0.21875 0,-0.28125 -0.125,-0.28125 -0.0625,0 -0.078125,0.03125 -0.15625,0.15625 l -0.578125,0.9375 C 6.578125,-7.75 5.84375,-8.421875 4.703125,-8.421875 c -2.15625,0 -4.0625,1.890625 -4.0625,4.328125 0,2.484375 1.90625,4.34375 4.078125,4.34375 0.84375,0 1.8125,-0.28125 2.265625,-1.03125 0.21875,0.375 0.609375,0.765625 0.703125,0.765625 0.09375,0 0.09375,-0.0625 0.09375,-0.265625 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5206"
overflow="visible"
style="overflow:visible">
<path
id="path5204"
d="m 0.5,-8.15625 v 0.34375 h 0.234375 c 0.875,0 0.90625,0.109375 0.90625,0.5625 v 6.34375 c 0,0.4375 -0.03125,0.5625 -0.90625,0.5625 H 0.5 V 0 h 4.1875 c 2,0 3.59375,-1.796875 3.59375,-4 0,-2.3125 -1.609375,-4.15625 -3.59375,-4.15625 z m 2.625,7.8125 c -0.515625,0 -0.546875,-0.09375 -0.546875,-0.484375 V -7.34375 c 0,-0.390625 0.03125,-0.46875 0.546875,-0.46875 h 1.265625 c 0.984375,0 1.78125,0.46875 2.265625,1.265625 0.546875,0.84375 0.546875,2.046875 0.546875,2.53125 0,0.671875 -0.015625,1.796875 -0.703125,2.671875 -0.390625,0.5 -1.109375,1 -2.109375,1 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5210"
overflow="visible"
style="overflow:visible">
<path
id="path5208"
d="M 2.484375,-4.984375 C 1.875,-5.140625 1.34375,-5.734375 1.34375,-6.5 c 0,-0.84375 0.671875,-1.59375 1.59375,-1.59375 1.96875,0 2.21875,1.9375 2.296875,2.453125 0.03125,0.140625 0.03125,0.1875 0.140625,0.1875 0.140625,0 0.140625,-0.0625 0.140625,-0.265625 v -2.421875 c 0,-0.21875 0,-0.28125 -0.125,-0.28125 -0.03125,0 -0.078125,0 -0.171875,0.15625 L 4.828125,-7.53125 C 4.25,-8.265625 3.46875,-8.421875 2.9375,-8.421875 c -1.328125,0 -2.296875,1.078125 -2.296875,2.296875 0,0.5625 0.203125,1.09375 0.65625,1.578125 0.40625,0.453125 0.828125,0.5625 1.671875,0.78125 0.421875,0.09375 1.078125,0.265625 1.25,0.328125 0.5625,0.28125 0.9375,0.921875 0.9375,1.59375 0,0.90625 -0.640625,1.75 -1.625,1.75 -0.546875,0 -1.28125,-0.140625 -1.875,-0.640625 -0.6875,-0.625 -0.734375,-1.484375 -0.75,-1.890625 -0.015625,-0.09375 -0.109375,-0.09375 -0.125,-0.09375 -0.140625,0 -0.140625,0.0625 -0.140625,0.28125 v 2.40625 c 0,0.21875 0,0.28125 0.125,0.28125 C 0.84375,0.25 0.84375,0.234375 0.9375,0.078125 0.984375,-0.015625 1.234375,-0.453125 1.328125,-0.640625 1.75,-0.15625 2.515625,0.25 3.53125,0.25 4.875,0.25 5.84375,-0.890625 5.84375,-2.203125 5.84375,-2.921875 5.5625,-3.46875 5.25,-3.859375 4.8125,-4.40625 4.265625,-4.53125 3.796875,-4.65625 Z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5214"
overflow="visible"
style="overflow:visible">
<path
id="path5212"
d="M 3.234375,-2.265625 V -2.90625 H 0.125 v 0.640625 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5218"
overflow="visible"
style="overflow:visible">
<path
id="path5216"
d="m 5.046875,-4.0625 c 1.1875,-0.28125 2.09375,-1.03125 2.09375,-1.953125 0,-1.15625 -1.34375,-2.140625 -3.0625,-2.140625 H 0.5 v 0.34375 h 0.234375 c 0.875,0 0.90625,0.109375 0.90625,0.5625 v 6.34375 c 0,0.4375 -0.03125,0.5625 -0.90625,0.5625 H 0.5 V 0 c 0.28125,-0.03125 1.25,-0.03125 1.609375,-0.03125 0.34375,0 1.328125,0 1.609375,0.03125 V -0.34375 H 3.484375 c -0.859375,0 -0.90625,-0.125 -0.90625,-0.5625 v -3.0625 H 3.96875 c 0.46875,0 0.90625,0.125 1.234375,0.46875 0.40625,0.453125 0.40625,0.703125 0.40625,1.53125 0,0.9375 0,1.25 0.515625,1.765625 C 6.3125,-0.03125 6.8125,0.25 7.484375,0.25 c 0.9375,0 1.09375,-1.03125 1.09375,-1.296875 0,-0.0625 0,-0.171875 -0.140625,-0.171875 -0.125,0 -0.125,0.078125 -0.125,0.1875 C 8.25,-0.3125 7.90625,0.015625 7.515625,0.015625 6.96875,0.015625 6.84375,-0.546875 6.75,-1.1875 6.734375,-1.265625 6.671875,-1.78125 6.640625,-2.078125 6.546875,-2.671875 6.5,-3.0625 6.140625,-3.4375 c -0.125,-0.125 -0.4375,-0.453125 -1.09375,-0.625 z m -1.125,-0.140625 H 2.578125 V -7.34375 c 0,-0.265625 0,-0.40625 0.25,-0.46875 0.109375,0 0.46875,0 0.703125,0 0.96875,0 2.5,0 2.5,1.796875 0,1.046875 -0.5625,1.8125 -2.109375,1.8125 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5222"
overflow="visible"
style="overflow:visible">
<path
id="path5220"
d="m 4.578125,-2.765625 c 0.265625,0 0.28125,0 0.28125,-0.234375 0,-1.203125 -0.640625,-2.328125 -2.09375,-2.328125 -1.359375,0 -2.40625,1.234375 -2.40625,2.703125 0,1.578125 1.21875,2.75 2.546875,2.75 1.421875,0 1.953125,-1.296875 1.953125,-1.546875 0,-0.078125 -0.046875,-0.125 -0.125,-0.125 -0.09375,0 -0.125,0.0625 -0.140625,0.125 -0.3125,1 -1.109375,1.28125 -1.625,1.28125 -0.5,0 -1.703125,-0.34375 -1.703125,-2.40625 v -0.21875 z M 1.28125,-3 c 0.09375,-1.875 1.140625,-2.09375 1.484375,-2.09375 1.28125,0 1.34375,1.6875 1.359375,2.09375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5226"
overflow="visible"
style="overflow:visible">
<path
id="path5224"
d="m 5.3125,-2.90625 c 0,-1.109375 0,-1.4375 -0.265625,-1.828125 -0.34375,-0.46875 -0.90625,-0.53125 -1.3125,-0.53125 -1.171875,0 -1.625,0.984375 -1.71875,1.21875 v -1.21875 l -1.640625,0.125 v 0.34375 c 0.8125,0 0.921875,0.09375 0.921875,0.671875 v 3.234375 c 0,0.546875 -0.140625,0.546875 -0.921875,0.546875 V 0 c 0.3125,-0.03125 0.96875,-0.03125 1.296875,-0.03125 0.34375,0 1,0 1.296875,0.03125 v -0.34375 c -0.75,0 -0.90625,0 -0.90625,-0.546875 v -2.21875 c 0,-1.25 0.828125,-1.921875 1.578125,-1.921875 0.734375,0 0.90625,0.609375 0.90625,1.34375 v 2.796875 c 0,0.546875 -0.140625,0.546875 -0.90625,0.546875 V 0 c 0.296875,-0.03125 0.953125,-0.03125 1.28125,-0.03125 0.34375,0 1,0 1.3125,0.03125 v -0.34375 c -0.609375,0 -0.90625,0 -0.921875,-0.359375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5230"
overflow="visible"
style="overflow:visible">
<path
id="path5228"
d="M 3.578125,-8.15625 V -7.8125 C 4.40625,-7.8125 4.5,-7.734375 4.5,-7.140625 V -4.5 C 4.25,-4.859375 3.734375,-5.265625 3,-5.265625 c -1.390625,0 -2.578125,1.171875 -2.578125,2.703125 0,1.515625 1.125,2.6875 2.453125,2.6875 0.90625,0 1.421875,-0.609375 1.59375,-0.828125 V 0.125 L 6.15625,0 V -0.34375 C 5.34375,-0.34375 5.25,-0.4375 5.25,-1.015625 v -7.28125 z m 0.890625,6.75 c 0,0.21875 0,0.265625 -0.171875,0.515625 -0.28125,0.421875 -0.765625,0.765625 -1.375,0.765625 -0.296875,0 -1.59375,-0.109375 -1.59375,-2.4375 0,-0.859375 0.140625,-1.328125 0.40625,-1.734375 0.234375,-0.359375 0.71875,-0.734375 1.3125,-0.734375 0.75,0 1.15625,0.53125 1.28125,0.734375 0.140625,0.203125 0.140625,0.21875 0.140625,0.4375 z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
<symbol
id="symbol5234"
overflow="visible"
style="overflow:visible">
<path
id="path5232"
d="m 2,-2.78125 c 0,-1.15625 0.46875,-2.25 1.390625,-2.25 0.09375,0 0.125,0 0.171875,0.015625 -0.09375,0.046875 -0.28125,0.109375 -0.28125,0.4375 0,0.34375 0.265625,0.484375 0.453125,0.484375 0.25,0 0.484375,-0.15625 0.484375,-0.484375 0,-0.359375 -0.328125,-0.6875 -0.84375,-0.6875 -1.015625,0 -1.359375,1.09375 -1.421875,1.328125 H 1.9375 v -1.328125 l -1.609375,0.125 v 0.34375 c 0.8125,0 0.921875,0.09375 0.921875,0.671875 v 3.234375 c 0,0.546875 -0.140625,0.546875 -0.921875,0.546875 V 0 c 0.34375,-0.03125 1,-0.03125 1.359375,-0.03125 0.328125,0 1.171875,0 1.4375,0.03125 V -0.34375 H 2.890625 C 2.015625,-0.34375 2,-0.484375 2,-0.90625 Z m 0,0"
style="stroke:none"
inkscape:connector-curvature="0" />
</symbol>
</g>
</defs>
<g
id="lx-text4864-surface1">
<g
id="g4946"
style="fill:#000000;fill-opacity:1">
<use
id="use4926"
y="0"
x="0"
xlink:href="#lx-text4864-glyph0-1"
width="100%"
height="100%" />
<use
id="use4928"
y="0"
x="9.1851797"
xlink:href="#lx-text4864-glyph0-2"
width="100%"
height="100%" />
<use
id="use4930"
y="0"
x="18.125278"
xlink:href="#lx-text4864-glyph0-3"
width="100%"
height="100%" />
<use
id="use4932"
y="0"
x="24.628908"
xlink:href="#lx-text4864-glyph0-4"
width="100%"
height="100%" />
<use
id="use4934"
y="0"
x="28.531084"
xlink:href="#lx-text4864-glyph0-5"
width="100%"
height="100%" />
<use
id="use4936"
y="0"
x="37.146004"
xlink:href="#lx-text4864-glyph0-6"
width="100%"
height="100%" />
<use
id="use4938"
y="0"
x="42.348904"
xlink:href="#lx-text4864-glyph0-7"
width="100%"
height="100%" />
<use
id="use4940"
y="0"
x="48.852535"
xlink:href="#lx-text4864-glyph0-8"
width="100%"
height="100%" />
<use
id="use4942"
y="0"
x="55.356163"
xlink:href="#lx-text4864-glyph0-6"
width="100%"
height="100%" />
<use
id="use4944"
y="0"
x="60.559067"
xlink:href="#lx-text4864-glyph0-9"
width="100%"
height="100%" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -17,11 +17,35 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file latex-output.c
* @brief LaTeX output renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#include "latex-output.h" #include "latex-output.h"
#include <math.h> #include <math.h>
/**
* @addtogroup LaTeX-Renderer
* @{
*/
/** @brief Writes a GString \p buffer to the fixed file tex_file */
#define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file) #define WRITEOUT_BUFFER(buff) fwrite((buff)->str, sizeof(char), (buff)->len, tex_file)
/**
* @brief Write the layer declarration to TeX file
*
* This writes the declaration of the layers and the mapping in which order
* the layers shall be rendered by TikZ. Layers are written in the order they are
* positioned inside the \p layer_infos list.
*
* @param tex_file TeX-File to write to
* @param layer_infos List containing layer_info structs.
* @param buffer
* @note The field layer_info::stacked_position is ignored. Stack depends on list order.
*/
static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString *buffer) static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString *buffer)
{ {
GList *list; GList *list;
@ -53,11 +77,30 @@ static void write_layer_definitions(FILE *tex_file, GList *layer_infos, GString
} }
/** /**
* @brief write_layer_env * @brief Write layer Envirmonment
* @param tex_file *
* @param layer * If the requested layer shall be rendered, this code writes the necessary code
* @param buffer * to open the layer. It also returns the color the layer shall be rendered in.
* @return TRUE if layer is placeable *
* The followingenvironments are generated:
*
* @code{.tex}
* \begin{pgfonlayer}{<layer>}
* % If pdf layers shall be used also this is enabled:
* \begin{scope}[ocg={ref=<layer>, status=visible,name={<Layer Name>}}]
* @endcode
*
*
* If the layer shall not be rendered, FALSE is returned and the color is not filled in and
* the cod eis not written to the file.
*
* @param tex_file TeX file to write to
* @param color Return of the layer's color
* @param layer Requested layer number
* @param linfo Layer information list containing layer_info structs
* @param buffer Some working buffer
* @return TRUE, if the layer shall be rendered.
* @note The opened environments have to be closed afterwards
*/ */
static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList *linfo, GString *buffer) static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList *linfo, GString *buffer)
{ {
@ -71,7 +114,7 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
color->red = inf->color.red; color->red = inf->color.red;
color->green = inf->color.green; color->green = inf->color.green;
color->blue = inf->color.blue; 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); layer, layer, inf->name);
WRITEOUT_BUFFER(buffer); WRITEOUT_BUFFER(buffer);
return TRUE; return TRUE;
@ -80,7 +123,17 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
return FALSE; return FALSE;
} }
/**
* @brief Writes a graphics object to the specified tex_file
*
* This function opens the layer, writes a graphics object and closes the layer
*
* @param tex_file File to write to
* @param graphics Object to render
* @param linfo Layer information
* @param buffer Working buffer
* @param scale Scale abject down by this value
*/
static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GString *buffer, double scale) static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GString *buffer, double scale)
{ {
GList *temp; GList *temp;
@ -144,7 +197,14 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
} /* For graphics */ } /* For graphics */
} }
/**
* @brief Render cell to file
* @param cell Cell to render
* @param layer_infos Layer information
* @param tex_file File to write to
* @param buffer Working buffer
* @param scale Scale output down by this value
*/
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale) static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale)
{ {
@ -238,3 +298,5 @@ void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *
fflush(tex_file); fflush(tex_file);
g_string_free(working_line, TRUE); g_string_free(working_line, TRUE);
} }
/** @} */

View File

@ -17,17 +17,39 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file latex-output.h
* @brief LaTeX output renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __LATEX_OUTPUT_H__ #ifndef __LATEX_OUTPUT_H__
#define __LATEX_OUTPUT_H__ #define __LATEX_OUTPUT_H__
/**
* @addtogroup LaTeX-Renderer
* @{
*/
#include "../gds-parser/gds-types.h" #include "../gds-parser/gds-types.h"
#include <glib.h> #include <glib.h>
#include <stdio.h> #include <stdio.h>
#include "../layer-selector.h" #include "../mapping-parser.h"
#define LATEX_LINE_BUFFER_KB (10) #define LATEX_LINE_BUFFER_KB (10) /**< @brief Buffer for LaTeX Code line in KiB */
/**
* @brief Render \p cell to LateX/TikZ code
* @param cell Cell to render
* @param layer_infos Layer information
* @param tex_file Already opened file to write data in
* @param scale Scale image down by this value
* @param create_pdf_layers Optional content groups used
* @param standalone_document document can be compiled standalone
*/
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale, void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale,
gboolean create_pdf_layers, gboolean standalone_document); gboolean create_pdf_layers, gboolean standalone_document);
/** @} */
#endif /* __LATEX_OUTPUT_H__ */ #endif /* __LATEX_OUTPUT_H__ */

View File

@ -17,6 +17,17 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file layer-selector.c
* @brief Implementation of the layer selector
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup MainApplication
* @{
*/
#include "layer-selector.h" #include "layer-selector.h"
#include "gds-parser/gds-parser.h" #include "gds-parser/gds-parser.h"
#include "widgets/layer-element.h" #include "widgets/layer-element.h"
@ -89,6 +100,11 @@ void clear_list_box_widgets(GtkListBox *box)
gtk_widget_set_sensitive(global_save_button, FALSE); gtk_widget_set_sensitive(global_save_button, FALSE);
} }
/**
* @brief Check if specific layer number is present in list box
* @param layer Layer nu,ber
* @return TRUE if present
*/
static gboolean check_if_layer_widget_exists(int layer) { static gboolean check_if_layer_widget_exists(int layer) {
GList *list; GList *list;
GList *temp; GList *temp;
@ -110,6 +126,11 @@ static gboolean check_if_layer_widget_exists(int layer) {
return ret; return ret;
} }
/**
* @brief Analyze \p cell and append used layers to list box
* @param listbox listbox to add layer
* @param cell Cell to analyze
*/
static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell) static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell)
{ {
GList *graphics; GList *graphics;
@ -129,7 +150,15 @@ static void analyze_cell_layers(GtkListBox *listbox, struct gds_cell *cell)
} }
} }
gint sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused) /**
* @brief sort_func Sort callback for list box
* @param row1
* @param row2
* @param unused
* @note Do not use this function
* @return
*/
static gint sort_func(GtkListBoxRow *row1, GtkListBoxRow *row2, gpointer unused)
{ {
LayerElement *le1, *le2; LayerElement *le1, *le2;
gint ret; gint ret;
@ -170,6 +199,12 @@ void generate_layer_widgets(GtkListBox *listbox, GList *libs)
gtk_widget_set_sensitive(global_save_button, TRUE); gtk_widget_set_sensitive(global_save_button, TRUE);
} }
/**
* @brief Find LayerElement in list with specified layer number
* @param el_list List with elements of type LayerElement
* @param layer Layer number
* @return Found LayerElement. If nothing is found, NULL.
*/
static LayerElement *find_layer_element_in_list(GList *el_list, int layer) static LayerElement *find_layer_element_in_list(GList *el_list, int layer)
{ {
LayerElement *ret = NULL; LayerElement *ret = NULL;
@ -182,6 +217,10 @@ static LayerElement *find_layer_element_in_list(GList *el_list, int layer)
return ret; return ret;
} }
/**
* @brief Load file and apply layer definitions to listbox
* @param file_name CSV Layer Mapping File
*/
static void load_layer_mapping_from_file(gchar *file_name) static void load_layer_mapping_from_file(gchar *file_name)
{ {
GFile *file; GFile *file;
@ -252,6 +291,11 @@ destroy_file:
g_object_unref(file); g_object_unref(file);
} }
/**
* @brief Callback for Load Mapping Button
* @param button
* @param user_data
*/
static void load_mapping_clicked(GtkWidget *button, gpointer user_data) static void load_mapping_clicked(GtkWidget *button, gpointer user_data)
{ {
GtkWidget *dialog; GtkWidget *dialog;
@ -269,6 +313,12 @@ static void load_mapping_clicked(GtkWidget *button, gpointer user_data)
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);
} }
/**
* @brief Create Line for LayerMapping file with supplied information
* @param layer_element information
* @param line_buffer buffer to write to
* @param max_len Maximum length that cna be used in \p line_buffer
*/
static void create_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len) static void create_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len)
{ {
GString *string; GString *string;
@ -304,6 +354,11 @@ static void create_csv_line(LayerElement *layer_element, char *line_buffer, size
g_string_free(string, TRUE); g_string_free(string, TRUE);
} }
/**
* @brief Save layer mapping of whole list box into file
* @param file_name layer mapping file
* @param list_box listbox
*/
static void save_layer_mapping_data(const gchar *file_name, GtkListBox *list_box) static void save_layer_mapping_data(const gchar *file_name, GtkListBox *list_box)
{ {
FILE *file; FILE *file;
@ -331,6 +386,11 @@ static void save_layer_mapping_data(const gchar *file_name, GtkListBox *list_box
fclose(file); fclose(file);
} }
/**
* @brief Callback for Save Layer Mapping Button
* @param button
* @param user_data
*/
static void save_mapping_clicked(GtkWidget *button, gpointer user_data) static void save_mapping_clicked(GtkWidget *button, gpointer user_data)
{ {
GtkWidget *dialog; GtkWidget *dialog;
@ -339,6 +399,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, 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); "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)); res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) { if (res == GTK_RESPONSE_ACCEPT) {
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@ -361,3 +423,5 @@ void setup_save_mapping_callback(GtkWidget *button, GtkWindow *main_window)
global_save_button = button; global_save_button = button;
g_signal_connect(button, "clicked", G_CALLBACK(save_mapping_clicked), main_window); g_signal_connect(button, "clicked", G_CALLBACK(save_mapping_clicked), main_window);
} }
/** @} */

View File

@ -17,6 +17,12 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file layer-selector.h
* @brief Implementation of the Layer selection list
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __LAYER_SELECTOR_H__ #ifndef __LAYER_SELECTOR_H__
#define __LAYER_SELECTOR_H__ #define __LAYER_SELECTOR_H__
@ -24,10 +30,38 @@
#include <glib.h> #include <glib.h>
#include "mapping-parser.h" #include "mapping-parser.h"
/**
* @brief Generate layer widgets in \p listbox
* @note This clears all previously inserted elements
* @param listbox
* @param libs The library to add
*/
void generate_layer_widgets(GtkListBox *listbox, GList *libs); void generate_layer_widgets(GtkListBox *listbox, GList *libs);
void setup_load_mapping_callback(GtkWidget *button, GtkWindow *main_window);
void setup_save_mapping_callback(GtkWidget *button, GtkWindow *main_window);
GList *export_rendered_layer_info();
void delete_layer_info_struct(struct layer_info *info);
/**
* @brief Supply button for loading the layer mapping
* @param button
* @param main_window Parent window for dialogs
*/
void setup_load_mapping_callback(GtkWidget *button, GtkWindow *main_window);
/**
* @brief Supply button for saving the layer mapping
* @param button
* @param main_window
*/
void setup_save_mapping_callback(GtkWidget *button, GtkWindow *main_window);
/**
* @brief get the layer information present in the listbox of the selector
* @return List with layer_info elements
*/
GList *export_rendered_layer_info();
/**
* @brief Delete a layer_info struct
* @param info Struct to be deleted.
* @note The layer_info::name Element has to be freed manually
*/
void delete_layer_info_struct(struct layer_info *info);
#endif /* __LAYER_SELECTOR_H__ */ #endif /* __LAYER_SELECTOR_H__ */

View File

@ -17,6 +17,16 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file main-window.c
* @brief Handling of GUI
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/** @addtogroup MainApplication
* @{
*/
#include "main-window.h" #include "main-window.h"
#include <stdio.h> #include <stdio.h>
#include "gds-parser/gds-parser.h" #include "gds-parser/gds-parser.h"
@ -27,6 +37,9 @@
#include "widgets/conv-settings-dialog.h" #include "widgets/conv-settings-dialog.h"
#include "cairo-output/cairo-output.h" #include "cairo-output/cairo-output.h"
/**
* @brief User data supplied to callback function of the open button
*/
struct open_button_data { struct open_button_data {
GtkWindow *main_window; GtkWindow *main_window;
GList **list_ptr; GList **list_ptr;
@ -34,17 +47,33 @@ struct open_button_data {
GtkListBox *layer_box; GtkListBox *layer_box;
}; };
/**
* @brief User data supplied to callback function of the convert button
*/
struct convert_button_data { struct convert_button_data {
GtkTreeView *tree_view; GtkTreeView *tree_view;
GtkWindow *main_window; GtkWindow *main_window;
}; };
/**
* @brief Window close event of main window
*
* Closes the main window. This leads to the termination of the whole application
* @param window main window
* @param user not used
* @return TRUE. This indicates that the event has been fully handled
*/
static gboolean on_window_close(gpointer window, gpointer user) static gboolean on_window_close(gpointer window, gpointer user)
{ {
gtk_widget_destroy(GTK_WIDGET(window)); gtk_widget_destroy(GTK_WIDGET(window));
return TRUE; return TRUE;
} }
/**
* @brief generate string from gds_time_field
* @param date Date to convert
* @return String with date
*/
static GString *generate_string_from_date(struct gds_time_field *date) static GString *generate_string_from_date(struct gds_time_field *date)
{ {
GString *str; GString *str;
@ -59,7 +88,11 @@ static GString *generate_string_from_date(struct gds_time_field *date)
return str; return str;
} }
/**
* @brief Callback function of Load GDS button
* @param button
* @param user Necessary Data
*/
static void on_load_gds(gpointer button, gpointer user) static void on_load_gds(gpointer button, gpointer user)
{ {
GList *cell; GList *cell;
@ -161,6 +194,11 @@ end_destroy:
gtk_widget_destroy(open_dialog); gtk_widget_destroy(open_dialog);
} }
/**
* @brief Convert button callback
* @param button
* @param user
*/
static void on_convert_clicked(gpointer button, gpointer user) static void on_convert_clicked(gpointer button, gpointer user)
{ {
static struct render_settings sett = { static struct render_settings sett = {
@ -213,15 +251,25 @@ static void on_convert_clicked(gpointer button, gpointer user)
"Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL); "Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
/* Set file filter according to settings */ /* Set file filter according to settings */
filter = gtk_file_filter_new(); 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_add_pattern(filter, "*.tex");
gtk_file_filter_set_name(filter, "LaTeX-Files"); gtk_file_filter_set_name(filter, "LaTeX-Files");
} else { break;
case RENDERER_CAIROGRAPHICS_PDF:
gtk_file_filter_add_pattern(filter, "*.pdf"); gtk_file_filter_add_pattern(filter, "*.pdf");
gtk_file_filter_set_name(filter, "PDF-Files"); 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_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)); res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) { if (res == GTK_RESPONSE_ACCEPT) {
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
@ -234,8 +282,12 @@ static void on_convert_clicked(gpointer button, gpointer user)
sett.tex_pdf_layers, sett.tex_standalone); sett.tex_pdf_layers, sett.tex_standalone);
fclose(output_file); fclose(output_file);
break; break;
case RENDERER_CAIROGRAPHICS: case RENDERER_CAIROGRAPHICS_SVG:
cairo_render_cell_to_pdf(cell_to_render, layer_list, file_name, sett.scale); 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; break;
} }
g_free(file_name); g_free(file_name);
@ -247,8 +299,15 @@ ret_layer_destroy:
g_list_free_full(layer_list, (GDestroyNotify)delete_layer_info_struct); g_list_free_full(layer_list, (GDestroyNotify)delete_layer_info_struct);
} }
/* This function activates/deactivates the convert button depending on whether
* a cell is selected for conversion or not */ /**
* @brief Callback for cell-selection change event
*
* This function activates/deactivates the convert button depending on whether
* a cell is selected for conversion or not
* @param sel
* @param convert_button
*/
static void cell_selection_changed(GtkTreeSelection *sel, GtkWidget *convert_button) static void cell_selection_changed(GtkTreeSelection *sel, GtkWidget *convert_button)
{ {
GtkTreeModel *model = NULL; GtkTreeModel *model = NULL;
@ -314,3 +373,5 @@ GtkWindow *create_main_window()
return (conv_data.main_window); return (conv_data.main_window);
} }
/** @} */

View File

@ -17,11 +17,30 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file main-window.h
* @brief Header for main-window
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef _MAIN_WINDOW_H_ #ifndef _MAIN_WINDOW_H_
#define _MAIN_WINDOW_H_ #define _MAIN_WINDOW_H_
/**
* @addtogroup MainApplication
* @{
*/
#include <gtk/gtk.h> #include <gtk/gtk.h>
/**
* @brief Create main window
*
* This function creates the main window and sets the necessary callback routines.
* @return
*/
GtkWindow *create_main_window(); GtkWindow *create_main_window();
/** @} */
#endif /* _MAIN_WINDOW_H_ */ #endif /* _MAIN_WINDOW_H_ */

78
main.c
View File

@ -22,16 +22,19 @@
#include <glib.h> #include <glib.h>
#include "main-window.h" #include "main-window.h"
#include "command-line.h" #include "command-line.h"
#include "external-renderer.h"
struct application_data { struct application_data {
GtkApplication *app; GtkApplication *app;
GtkWindow *main_window; GtkWindow *main_window;
}; };
static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data) static void app_quit(GSimpleAction *action, GVariant *parameter, gpointer user_data)
{ {
struct application_data *appdata = (struct application_data *)user_data; struct application_data *appdata = (struct application_data *)user_data;
(void)action;
(void)parameter;
gtk_widget_destroy(GTK_WIDGET(appdata->main_window)); gtk_widget_destroy(GTK_WIDGET(appdata->main_window));
} }
@ -40,6 +43,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
GtkBuilder *builder; GtkBuilder *builder;
GtkDialog *dialog; GtkDialog *dialog;
struct application_data *appdata = (struct application_data *)user_data; struct application_data *appdata = (struct application_data *)user_data;
(void)action;
(void)parameter;
builder = gtk_builder_new_from_resource("/about.glade"); builder = gtk_builder_new_from_resource("/about.glade");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog")); 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); g_object_unref(builder);
} }
const GActionEntry app_actions[] = { const static GActionEntry app_actions[] = {
{ "quit", app_quit }, { "quit", app_quit },
{ "about", app_about } { "about", app_about }
}; };
@ -78,8 +83,7 @@ static int start_gui(int argc, char **argv)
gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE); gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE);
g_application_register(G_APPLICATION(gapp), NULL, NULL); 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);
@ -90,7 +94,8 @@ static int start_gui(int argc, char **argv)
g_menu_append(m_about, "About", "app.about"); 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_about));
g_menu_append_section(menu, NULL, G_MENU_MODEL(m_quit)); 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)); gtk_application_set_app_menu(GTK_APPLICATION(gapp), G_MENU_MODEL(menu));
g_object_unref(m_quit); g_object_unref(m_quit);
@ -98,8 +103,8 @@ static int start_gui(int argc, char **argv)
g_object_unref(menu); g_object_unref(menu);
app_status = g_application_run (G_APPLICATION(gapp), argc, argv); app_status = g_application_run(G_APPLICATION(gapp), argc, argv);
g_object_unref (gapp); g_object_unref(gapp);
return app_status; return app_status;
} }
@ -110,33 +115,38 @@ int main(int argc, char **argv)
GOptionContext *context; GOptionContext *context;
gchar *gds_name; gchar *gds_name;
gchar *basename; gchar *basename;
gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL; gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE; 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 scale = 1000;
int app_status; int app_status;
GOptionEntry entries[] = GOptionEntry entries[] = {
{ {"tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
{ "tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL }, {"pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", 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 putput coordinates by <SCALE>", "<SCALE>" }, {"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" }, {"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" }, {"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" }, //{"svg-output", 0, 0, G_OPTION_ARG_FILENAME, &svgname, "Optional path for PDF file", "PATH"},
{ "cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" }, {"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
{ "tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL }, {"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
{ "tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create standalone PDF", NULL }, {"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 } { NULL }
}; };
context = g_option_context_new(" FILE - Convert GDS file <FILE> to graphic"); 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_main_entries(context, entries, NULL);
g_option_context_add_group(context, gtk_get_option_group(TRUE)); g_option_context_add_group(context, gtk_get_option_group(TRUE));
if (!g_option_context_parse (context, &argc, &argv, &error))
{ if (!g_option_context_parse(context, &argc, &argv, &error)) {
g_print ("Option parsing failed: %s\n", error->message); g_print("Option parsing failed: %s\n", error->message);
exit (1); exit(1);
} }
if (argc >= 2) { if (argc >= 2) {
@ -146,9 +156,8 @@ int main(int argc, char **argv)
} }
/* No format selected */ /* No format selected */
if (!(tikz || pdf)) { if (!(tikz || pdf || svg))
tikz = TRUE; tikz = TRUE;
}
/* Get gds name */ /* Get gds name */
gds_name = argv[1]; gds_name = argv[1];
@ -156,19 +165,24 @@ int main(int argc, char **argv)
/* Check if PDF/TeX names are supplied. if not generate */ /* Check if PDF/TeX names are supplied. if not generate */
basename = g_path_get_basename(gds_name); basename = g_path_get_basename(gds_name);
if (!texname) { if (!texname)
texname = g_strdup_printf("./%s.tex", basename); texname = g_strdup_printf("./%s.tex", basename);
}
if (!pdfname) { if (!pdfname)
pdfname = g_strdup_printf("./%s.pdf", basename); pdfname = g_strdup_printf("./%s.pdf", basename);
}
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz, mappingname, cellname, if (!pdfname)
(double)scale, pdf_layers, pdf_standalone); 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 */ /* Clean up */
g_free(pdfname); g_free(pdfname);
g_free(texname); g_free(texname);
g_free(svgname);
g_free(basename);
if (mappingname) if (mappingname)
g_free(mappingname); g_free(mappingname);
if (cellname) if (cellname)

View File

@ -18,18 +18,19 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "mapping-parser.h" /**
* @file mapping-parser.c
* @brief Function to read a mapping file line and parse it.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/** /**
* @brief load_csv_line * @addtogroup MainApplication
* @param file * @{
* @param export
* @param name
* @param layer
* @param color
* @param opacity
* @return 0 if succesfull, 1 if line was malformatted or parameters are broken, -1 if file end
*/ */
#include "mapping-parser.h"
int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color) int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color)
{ {
int ret; int ret;
@ -93,3 +94,5 @@ ret_direct:
} }
/** @} */

View File

@ -17,19 +17,46 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/ */
/**
* @file mapping-parser.h
* @brief Function to read a mapping file line and parse it.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __MAPPING_PARSER_H__ #ifndef __MAPPING_PARSER_H__
#define __MAPPING_PARSER_H__ #define __MAPPING_PARSER_H__
/**
* @addtogroup MainApplication
* @{
*/
#include <gtk/gtk.h> #include <gtk/gtk.h>
/**
* @brief Layer information.
*
* This structs contains information on how to render a layer
*/
struct layer_info struct layer_info
{ {
int layer; int layer; /**< @brief Layer number */
char *name; char *name; /**< @brief Layer name */
int stacked_position; ///< Lower is bottom, higher is top int stacked_position; ///< @brief Position of layer in output @warning This parameter is not used by any renderer so far @note Lower is bottom, higher is top
GdkRGBA color; GdkRGBA color; /**< @brief RGBA color used to render this layer */
}; };
/**
* @brief Load a line from \p stream and parse try to parse it as layer information
* @param stream Input data stream
* @param export Layer shall be exported
* @param name Layer name. Free returned pointer after using.
* @param layer Layer number
* @param color RGBA color.
* @return 1 if malformatted line, 0 if parsing was successful and parameters are valid, -1 if file end
*/
int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color); int load_csv_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color);
/** @} */
#endif /* __MAPPING_PARSER_H__ */ #endif /* __MAPPING_PARSER_H__ */

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 "tree-store.h"
#include "lib-cell-renderer.h" #include "lib-cell-renderer.h"
#include "../gds-parser/gds-types.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, static gboolean tree_sel_func(GtkTreeSelection *selection,
GtkTreeModel *model, GtkTreeModel *model,
GtkTreePath *path, GtkTreePath *path,
@ -21,6 +60,11 @@ static gboolean tree_sel_func(GtkTreeSelection *selection,
return FALSE; return FALSE;
} }
/**
* @brief Setup a GtkTreeView with the necessary columns
* @param view Tree view to set up
* @return TreeStore for storing data inside the GtkTreeView
*/
GtkTreeStore *setup_cell_selector(GtkTreeView* view) GtkTreeStore *setup_cell_selector(GtkTreeView* view)
{ {
GtkTreeStore *cell_store; GtkTreeStore *cell_store;
@ -77,3 +121,4 @@ GtkTreeStore *setup_cell_selector(GtkTreeView* view)
return cell_store; return cell_store;
} }
/** @} */

View File

@ -1,16 +1,49 @@
/*
* 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__ #ifndef __TREE_STORE_H__
#define __TREE_STORE_H__ #define __TREE_STORE_H__
#include <gtk/gtk.h> #include <gtk/gtk.h>
/** @brief Columns of selection tree view */
enum cell_store_columns { enum cell_store_columns {
CELL_SEL_LIBRARY = 0, CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL, CELL_SEL_CELL,
CELL_SEL_MODDATE, CELL_SEL_MODDATE,
CELL_SEL_ACCESSDATE, 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); GtkTreeStore *setup_cell_selector(GtkTreeView* view);
#endif /* __TREE_STORE_H__ */ #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/>. * 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" #include "conv-settings-dialog.h"
struct _RendererSettingsDialog { struct _RendererSettingsDialog {
GtkDialog parent; GtkDialog parent;
/* Private loot */ /* Private loot */
GtkWidget *radio_latex; GtkWidget *radio_latex;
GtkWidget *radio_cairo; GtkWidget *radio_cairo_pdf;
GtkWidget *radio_cairo_svg;
GtkWidget *scale; GtkWidget *scale;
GtkWidget *layer_check; GtkWidget *layer_check;
GtkWidget *standalone_check; GtkWidget *standalone_check;
@ -72,7 +84,8 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self)
builder = gtk_builder_new_from_resource("/dialog.glade"); builder = gtk_builder_new_from_resource("/dialog.glade");
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box")); box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio")); 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->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale"));
self->standalone_check = GTK_WIDGET(gtk_builder_get_object(builder, "standalone-check")); self->standalone_check = GTK_WIDGET(gtk_builder_get_object(builder, "standalone-check"));
self->layer_check = GTK_WIDGET(gtk_builder_get_object(builder, "layer-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) 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) if (!settings || !dialog)
return; return;
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale)); 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_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)); 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) void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
{ {
if (!settings || !dialog) 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); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_latex), TRUE);
show_tex_options(dialog); show_tex_options(dialog);
break; break;
case RENDERER_CAIROGRAPHICS: case RENDERER_CAIROGRAPHICS_PDF:
hide_tex_options(dialog); 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; 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/>. * 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__ #ifndef __CONV_SETTINGS_DIALOG_H__
#define __CONV_SETTINGS_DIALOG_H__ #define __CONV_SETTINGS_DIALOG_H__
@ -24,25 +35,46 @@
G_BEGIN_DECLS 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) 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); RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent);
#define RENDERER_TYPE_SETTINGS_DIALOG (renderer_settings_dialog_get_type()) #define RENDERER_TYPE_SETTINGS_DIALOG (renderer_settings_dialog_get_type())
/**
* @brief This struct holds the renderer configuration
*/
struct render_settings { struct render_settings {
double scale; double scale; /**< @brief Scale image down by this factor. @note Used to keep image in bound of maximum coordinate limit */
enum output_renderer renderer; enum output_renderer renderer; /**< The renderer to use */
gboolean tex_pdf_layers; gboolean tex_pdf_layers; /**< Create OCG layers when rendering with TikZ */
gboolean tex_standalone; gboolean tex_standalone; /**< Create a standalone compile TeX file */
}; };
G_END_DECLS G_END_DECLS
/**
* @brief Apply settings to dialog
* @param dialog
* @param settings
*/
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *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); void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
#endif /* __CONV_SETTINGS_DIALOG_H__ */ #endif /* __CONV_SETTINGS_DIALOG_H__ */
/** @} */

View File

@ -17,6 +17,17 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>. * 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" #include "layer-element.h"
G_DEFINE_TYPE(LayerElement, layer_element, GTK_TYPE_LIST_BOX_ROW) 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); 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/>. * 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__ #ifndef __LAYER_ELEMENT_H__
#define __LAYER_ELEMENT_H__ #define __LAYER_ELEMENT_H__
@ -45,17 +56,70 @@ struct _LayerElement {
LayerElementPriv priv; LayerElementPriv priv;
}; };
/**
* @brief Create new layer element object
* @return new object
*/
GtkWidget *layer_element_new(void); 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); 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); 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); 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); 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); 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); 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); 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); void layer_element_set_color(LayerElement *elem, GdkRGBA *rgba);
G_END_DECLS G_END_DECLS
#endif /* __LAYER_ELEMENT_H__ */ #endif /* __LAYER_ELEMENT_H__ */
/** @} */