diff --git a/cairo-output/cairo-output.c b/cairo-output/cairo-output.c
index 062c0fd..9db1b8e 100644
--- a/cairo-output/cairo-output.c
+++ b/cairo-output/cairo-output.c
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see .
*/
- /**
+/**
* @file cairo-output.c
* @brief Output renderer for Cairo PDF export
* @author Mario Hüttel
@@ -31,15 +31,16 @@
#include
#include
#include
+#include
/**
* @brief The cairo_layer struct
* Each rendered layer is represented by this struct.
*/
struct cairo_layer {
- cairo_t *cr; /**< @brief cairo context for layer*/
- cairo_surface_t *rec; /**< @brief Recording surface to hold the layer */
- struct layer_info *linfo; /**< @brief Reference to layer information */
+ cairo_t *cr; /**< @brief cairo context for layer*/
+ cairo_surface_t *rec; /**< @brief Recording surface to hold the layer */
+ struct layer_info *linfo; /**< @brief Reference to layer information */
};
/**
@@ -177,10 +178,10 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
}
-void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale)
+void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale)
{
- cairo_surface_t *pdf_surface;
- cairo_t *pdf_cr;
+ cairo_surface_t *pdf_surface, *svg_surface;
+ cairo_t *pdf_cr, *svg_cr;
struct layer_info *linfo;
struct cairo_layer *layers;
struct cairo_layer *lay;
@@ -189,6 +190,11 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
double rec_x0, rec_y0, rec_width, rec_height;
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
+ if (pdf_file == NULL && svg_file == NULL) {
+ /* No output specified */
+ return;
+ }
+
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
/* Clear layers */
@@ -246,8 +252,15 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
printf("Bounding box: (%lf,%lf) -- (%lf,%lf)\n", xmin, ymin, xmax, ymax);
- pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
- pdf_cr = cairo_create(pdf_surface);
+ if (pdf_file) {
+ pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
+ pdf_cr = cairo_create(pdf_surface);
+ }
+
+ if (svg_file) {
+ svg_surface = cairo_svg_surface_create(svg_file, xmax-xmin, ymax-ymin);
+ svg_cr = cairo_create(svg_surface);
+ }
/* Write layers to PDF */
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
@@ -258,13 +271,29 @@ void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *p
continue;
}
- cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
- cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);
+ if (pdf_file) {
+ cairo_set_source_surface(pdf_cr, layers[linfo->layer].rec, -xmin, -ymin);
+ cairo_paint_with_alpha(pdf_cr, linfo->color.alpha);
+ }
+
+ if (svg_file) {
+ cairo_set_source_surface(svg_cr, layers[linfo->layer].rec, -xmin, -ymin);
+ cairo_paint_with_alpha(svg_cr, linfo->color.alpha);
+ }
+
}
- cairo_show_page(pdf_cr);
- cairo_destroy(pdf_cr);
- cairo_surface_destroy(pdf_surface);
+ if (pdf_file) {
+ cairo_show_page(pdf_cr);
+ cairo_destroy(pdf_cr);
+ cairo_surface_destroy(pdf_surface);
+ }
+
+ if (svg_file) {
+ cairo_show_page(svg_cr);
+ cairo_destroy(svg_cr);
+ cairo_surface_destroy(svg_surface);
+ }
ret_clear_layers:
for (i = 0; i < MAX_LAYERS; i++) {
diff --git a/cairo-output/cairo-output.h b/cairo-output/cairo-output.h
index 069372c..091b704 100644
--- a/cairo-output/cairo-output.h
+++ b/cairo-output/cairo-output.h
@@ -37,10 +37,11 @@
* @brief Render \p cell to a PDF file specified by \p pdf_file
* @param cell Toplevel cell to render
* @param layer_infos List of layer information. Specifies color and layer stacking
- * @param pdf_file Output file
+ * @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated
+ * @param svg_file SVG output file. Set to NULL if no SVG file has to be generated
* @param scale Scale the output image down by \p scale
*/
-void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale);
+void cairo_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, char *pdf_file, char *svg_file, double scale);
/** @} */
diff --git a/command-line.c b/command-line.c
index ceb90f6..dad5671 100644
--- a/command-line.c
+++ b/command-line.c
@@ -50,21 +50,9 @@ static void delete_layer_info_with_name(struct layer_info *info)
}
}
-/**
- * @brief Convert GDS according to supplied parameters
- * @param gds_name GDS File path
- * @param pdf_name Cairo-PDF path
- * @param tex_name TeX/TikZ path
- * @param pdf Render Cairo
- * @param tex Render LaTeX
- * @param layer_file Layer mapping file
- * @param cell_name Cell name to render
- * @param scale Scale image down by this value
- * @param pdf_layers TikZ creates OCG layers
- * @param pdf_standalone LaTeX document is standalone
- */
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
- char *layer_file, char *cell_name, double scale, gboolean pdf_layers, gboolean pdf_standalone)
+ char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
+ gboolean pdf_standalone, gboolean svg, char *svg_name)
{
GList *libs = NULL;
FILE *tex_file;
@@ -143,8 +131,9 @@ void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gb
}
/* Render outputs */
- if (pdf == TRUE) {
- cairo_render_cell_to_pdf(toplevel_cell, layer_info_list, pdf_name, scale);
+ if (pdf == TRUE || svg == TRUE) {
+ cairo_render_cell_to_vector_file(toplevel_cell, layer_info_list, (pdf == TRUE ? pdf_name : NULL),
+ (svg == TRUE ? svg_name : NULL), scale);
}
if (tex == TRUE) {
diff --git a/command-line.h b/command-line.h
index eaa9de8..3c36360 100644
--- a/command-line.h
+++ b/command-line.h
@@ -32,8 +32,24 @@
#define _COMMAND_LINE_H_
#include
+/**
+ * @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 svg_name SVG file name
+ */
void command_line_convert_gds(char *gds_name, char *pdf_name, char *tex_name, gboolean pdf, gboolean tex,
- char *layer_file, char *cell_name, double scale, gboolean pdf_layers, gboolean pdf_standalone);
+ char *layer_file, char *cell_name, double scale, gboolean pdf_layers,
+ gboolean pdf_standalone, gboolean svg, char *svg_name);
#endif /* _COMMAND_LINE_H_ */
diff --git a/doxygen/Doxyconfig b/doxygen/Doxyconfig
index d4eb6f7..28ecff4 100644
--- a/doxygen/Doxyconfig
+++ b/doxygen/Doxyconfig
@@ -51,7 +51,7 @@ PROJECT_BRIEF =
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
-PROJECT_LOGO = /home/mari/projects/cpp/gds-render/icon/gds-render.svg
+PROJECT_LOGO = ../icon/gds-render.svg
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
diff --git a/glade/dialog.glade b/glade/dialog.glade
index 7186456..90b1ea5 100644
--- a/glade/dialog.glade
+++ b/glade/dialog.glade
@@ -16,6 +16,7 @@
-
+
+
+ Render SVG using Cairographics (too buggy at the moment)
+ True
+ True
+ False
+ True
+ False
+ True
+ True
+ latex-radio
+
+
+ False
+ True
+ 2
+
+
True
@@ -55,7 +75,7 @@
False
True
- 2
+ 3
@@ -69,7 +89,7 @@
False
True
- 3
+ 4
@@ -83,7 +103,7 @@
False
True
- 4
+ 5
diff --git a/main-window.c b/main-window.c
index 931bac9..d687875 100644
--- a/main-window.c
+++ b/main-window.c
@@ -251,13 +251,21 @@ static void on_convert_clicked(gpointer button, gpointer user)
"Cancel", GTK_RESPONSE_CANCEL, "Save", GTK_RESPONSE_ACCEPT, NULL);
/* Set file filter according to settings */
filter = gtk_file_filter_new();
- if (sett.renderer == RENDERER_LATEX_TIKZ) {
+ switch (sett.renderer) {
+ case RENDERER_LATEX_TIKZ:
gtk_file_filter_add_pattern(filter, "*.tex");
gtk_file_filter_set_name(filter, "LaTeX-Files");
- } else {
+ break;
+ case RENDERER_CAIROGRAPHICS_PDF:
gtk_file_filter_add_pattern(filter, "*.pdf");
gtk_file_filter_set_name(filter, "PDF-Files");
+ break;
+ case RENDERER_CAIROGRAPHICS_SVG:
+ gtk_file_filter_add_pattern(filter, "*.svg");
+ gtk_file_filter_set_name(filter, "SVG-Files");
+ break;
}
+
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
@@ -274,8 +282,12 @@ static void on_convert_clicked(gpointer button, gpointer user)
sett.tex_pdf_layers, sett.tex_standalone);
fclose(output_file);
break;
- case RENDERER_CAIROGRAPHICS:
- cairo_render_cell_to_pdf(cell_to_render, layer_list, file_name, sett.scale);
+ case RENDERER_CAIROGRAPHICS_SVG:
+ case RENDERER_CAIROGRAPHICS_PDF:
+ cairo_render_cell_to_vector_file(cell_to_render, layer_list,
+ (sett.renderer == RENDERER_CAIROGRAPHICS_PDF ? file_name : NULL),
+ (sett.renderer == RENDERER_CAIROGRAPHICS_SVG ? file_name : NULL),
+ sett.scale);
break;
}
g_free(file_name);
diff --git a/main.c b/main.c
index bdfe858..5a0e9b9 100644
--- a/main.c
+++ b/main.c
@@ -110,8 +110,8 @@ int main(int argc, char **argv)
GOptionContext *context;
gchar *gds_name;
gchar *basename;
- gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL;
- gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE;
+ gchar *pdfname = NULL, *texname = NULL, *mappingname = NULL, *cellname = NULL, *svgname = NULL;
+ gboolean tikz = FALSE, pdf = FALSE, pdf_layers = FALSE, pdf_standalone = FALSE, svg = FALSE;
int scale = 1000;
int app_status;
@@ -120,9 +120,11 @@ int main(int argc, char **argv)
{
{ "tikz", 't', 0, G_OPTION_ARG_NONE, &tikz, "Output TikZ code", NULL },
{ "pdf", 'p', 0, G_OPTION_ARG_NONE, &pdf, "Output PDF document", NULL },
+ //{ "svg", 'S', 0, G_OPTION_ARG_NONE, &svg, "Output SVG image", NULL },
{ "scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by ", "" },
{ "tex-output", 'o', 0, G_OPTION_ARG_FILENAME, &texname, "Optional path for TeX file", "PATH" },
{ "pdf-output", 'O', 0, G_OPTION_ARG_FILENAME, &pdfname, "Optional path for PDF file", "PATH" },
+ //{ "svg-output", 0, 0, G_OPTION_ARG_FILENAME, &svgname, "Optional path for PDF file", "PATH"},
{ "mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
{ "cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
{ "tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
@@ -146,7 +148,7 @@ int main(int argc, char **argv)
}
/* No format selected */
- if (!(tikz || pdf)) {
+ if (!(tikz || pdf || svg)) {
tikz = TRUE;
}
@@ -164,11 +166,18 @@ int main(int argc, char **argv)
pdfname = g_strdup_printf("./%s.pdf", basename);
}
+ if (!pdfname) {
+ pdfname = g_strdup_printf("./%s.svg", basename);
+ }
+
+
command_line_convert_gds(gds_name, pdfname, texname, pdf, tikz, mappingname, cellname,
- (double)scale, pdf_layers, pdf_standalone);
+ (double)scale, pdf_layers, pdf_standalone, svg, svgname);
/* Clean up */
g_free(pdfname);
g_free(texname);
+ g_free(svgname);
+ g_free(basename);
if (mappingname)
g_free(mappingname);
if (cellname)
diff --git a/trigonometric/vector-operations.c b/trigonometric/vector-operations.c
index 6796687..bb741e5 100644
--- a/trigonometric/vector-operations.c
+++ b/trigonometric/vector-operations.c
@@ -52,6 +52,9 @@ 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);
diff --git a/widgets/conv-settings-dialog.c b/widgets/conv-settings-dialog.c
index c553684..648d1b9 100644
--- a/widgets/conv-settings-dialog.c
+++ b/widgets/conv-settings-dialog.c
@@ -34,7 +34,8 @@ struct _RendererSettingsDialog {
GtkDialog parent;
/* Private loot */
GtkWidget *radio_latex;
- GtkWidget *radio_cairo;
+ GtkWidget *radio_cairo_pdf;
+ GtkWidget *radio_cairo_svg;
GtkWidget *scale;
GtkWidget *layer_check;
GtkWidget *standalone_check;
@@ -83,7 +84,8 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self)
builder = gtk_builder_new_from_resource("/dialog.glade");
box = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-box"));
self->radio_latex = GTK_WIDGET(gtk_builder_get_object(builder, "latex-radio"));
- self->radio_cairo = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-radio"));
+ self->radio_cairo_pdf = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-pdf-radio"));
+ self->radio_cairo_svg = GTK_WIDGET(gtk_builder_get_object(builder, "cairo-svg-radio"));
self->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale"));
self->standalone_check = GTK_WIDGET(gtk_builder_get_object(builder, "standalone-check"));
self->layer_check = GTK_WIDGET(gtk_builder_get_object(builder, "layer-check"));
@@ -110,13 +112,27 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
{
+ GList *radio_buttons;
+ GList *temp_button_list;
+ GtkToggleButton *temp_button = NULL;
+
if (!settings || !dialog)
return;
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
- settings->renderer = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE ? RENDERER_LATEX_TIKZ : RENDERER_CAIROGRAPHICS);
+
+ /* Get active radio button selection */
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE) {
+ settings->renderer = RENDERER_LATEX_TIKZ;
+ } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE) {
+ settings->renderer = RENDERER_CAIROGRAPHICS_PDF;
+ } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE) {
+ settings->renderer = RENDERER_CAIROGRAPHICS_SVG;
+ }
+
settings->tex_pdf_layers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->layer_check));
settings->tex_standalone = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->standalone_check));
}
+
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
{
if (!settings || !dialog)
@@ -131,10 +147,16 @@ void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struc
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_latex), TRUE);
show_tex_options(dialog);
break;
- case RENDERER_CAIROGRAPHICS:
+ case RENDERER_CAIROGRAPHICS_PDF:
hide_tex_options(dialog);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo), TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf), TRUE);
break;
+ case RENDERER_CAIROGRAPHICS_SVG:
+ hide_tex_options(dialog);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg), TRUE);
+ break;
+
+
}
}
diff --git a/widgets/conv-settings-dialog.h b/widgets/conv-settings-dialog.h
index ef5f6f0..909ceaa 100644
--- a/widgets/conv-settings-dialog.h
+++ b/widgets/conv-settings-dialog.h
@@ -36,7 +36,7 @@
G_BEGIN_DECLS
/** @brief return type of the RedererSettingsDialog */
-enum output_renderer {RENDERER_LATEX_TIKZ, RENDERER_CAIROGRAPHICS};
+enum output_renderer {RENDERER_LATEX_TIKZ, RENDERER_CAIROGRAPHICS_PDF, RENDERER_CAIROGRAPHICS_SVG};
G_DECLARE_FINAL_TYPE(RendererSettingsDialog, renderer_settings_dialog, RENDERER, SETTINGS_DIALOG, GtkDialog)