Compare commits
3 Commits
4c04ce3614
...
3167da4648
Author | SHA1 | Date | |
---|---|---|---|
3167da4648 | |||
b72466957c | |||
d9f0f3cdd5 |
@ -17,6 +17,7 @@ aux_source_directory("widgets" LAYER_SOURCES)
|
||||
aux_source_directory("tree-renderer" RENDERER_SOURCES)
|
||||
aux_source_directory("gds-parser" PARSER_SOURCES)
|
||||
aux_source_directory("latex-output" LATEX_SOURCES)
|
||||
aux_source_directory("cairo-output" CAIRO_SOURCES)
|
||||
set(SOURCE "main.c" "layer-selector.c")
|
||||
|
||||
|
||||
@ -26,6 +27,7 @@ set(SOURCE
|
||||
${RENDERER_SOURCES}
|
||||
${PARSER_SOURCES}
|
||||
${LATEX_SOURCES}
|
||||
${CAIRO_SOURCES}
|
||||
)
|
||||
|
||||
add_compile_options(-Wall)
|
||||
|
76
cairo-output/cairo-output.c
Normal file
76
cairo-output/cairo-output.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "cairo-output.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <cairo.h>
|
||||
#include <cairo-pdf.h>
|
||||
|
||||
struct cairo_layer {
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *rec;
|
||||
struct layer_info *linfo;
|
||||
};
|
||||
|
||||
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
struct layer_info *linfo;
|
||||
struct cairo_layer *layers;
|
||||
struct cairo_layer *lay;
|
||||
GList *info_list;
|
||||
int i;
|
||||
|
||||
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
|
||||
|
||||
/* Clear layers */
|
||||
for (i = 0; i < MAX_LAYERS; i++) {
|
||||
layers[i].cr = NULL;
|
||||
layers[i].rec = NULL;
|
||||
}
|
||||
|
||||
/* Create recording surface for each layer */
|
||||
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
|
||||
linfo = (struct layer_info *)info_list->data;
|
||||
if (linfo->layer < MAX_LAYERS) {
|
||||
lay = &(layers[(unsigned int)linfo->layer]);
|
||||
lay->linfo = linfo;
|
||||
lay->rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA,
|
||||
NULL);
|
||||
lay->cr = cairo_create(layers[(unsigned int)linfo->layer].rec);
|
||||
cairo_scale(lay->cr, 1/scale, 1/scale);
|
||||
} else {
|
||||
printf("Layer number (%d) too high!\n", linfo->layer);
|
||||
goto ret_clear_layers;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ret_clear_layers:
|
||||
for (i = 0; i < MAX_LAYERS; i++) {
|
||||
lay = &layers[i];
|
||||
cairo_destroy(lay->cr);
|
||||
cairo_surface_destroy(lay->rec);
|
||||
}
|
||||
free(layers);
|
||||
|
||||
printf("cairo export not yet implemented!\n");
|
||||
}
|
30
cairo-output/cairo-output.h
Normal file
30
cairo-output/cairo-output.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef __CAIRO_OUTPUT_H__
|
||||
#define __CAIRO_OUTPUT_H__
|
||||
|
||||
#include "../layer-selector.h"
|
||||
#include "../gds-parser/gds-types.h"
|
||||
|
||||
#define MAX_LAYERS (2048)
|
||||
|
||||
void cairo_render_cell_to_pdf(struct gds_cell *cell, GList *layer_infos, char *pdf_file, double scale);
|
||||
|
||||
#endif /* __CAIRO_OUTPUT_H__ */
|
@ -81,7 +81,7 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
|
||||
}
|
||||
|
||||
|
||||
static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GString *buffer)
|
||||
static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GString *buffer, double scale)
|
||||
{
|
||||
GList *temp;
|
||||
GList *temp_vertex;
|
||||
@ -102,7 +102,7 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
||||
/* Append vertices */
|
||||
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
|
||||
pt = (struct gds_point *)temp_vertex->data;
|
||||
g_string_printf(buffer, "(%lf pt, %lf pt) -- ", ((double)pt->x)/1000.0, ((double)pt->y)/1000.0);
|
||||
g_string_printf(buffer, "(%lf pt, %lf pt) -- ", ((double)pt->x)/scale, ((double)pt->y)/scale);
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
}
|
||||
g_string_printf(buffer, "cycle;\n");
|
||||
@ -120,7 +120,7 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
||||
}
|
||||
|
||||
g_string_printf(buffer, "\\draw[line width=%lf pt, draw={c%d}, opacity={%lf}, cap=%s] ",
|
||||
gfx->width_absolute/1000.0, gfx->layer, color.alpha,
|
||||
gfx->width_absolute/scale, gfx->layer, color.alpha,
|
||||
line_caps[gfx->path_render_type]);
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
|
||||
@ -128,8 +128,8 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
||||
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
|
||||
pt = (struct gds_point *)temp_vertex->data;
|
||||
g_string_printf(buffer, "(%lf pt, %lf pt)%s",
|
||||
((double)pt->x)/1000.0,
|
||||
((double)pt->y)/1000.0,
|
||||
((double)pt->x)/scale,
|
||||
((double)pt->y)/scale,
|
||||
(temp_vertex->next ? " -- " : ""));
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
}
|
||||
@ -145,14 +145,14 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
|
||||
}
|
||||
|
||||
|
||||
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer)
|
||||
static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, GString *buffer, double scale)
|
||||
{
|
||||
|
||||
GList *list_child;
|
||||
struct gds_cell_instance *inst;
|
||||
|
||||
/* Draw polygons of current cell */
|
||||
generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer);
|
||||
generate_graphics(tex_file, cell->graphic_objs, layer_infos, buffer, scale);
|
||||
|
||||
/* Draw polygons of childs */
|
||||
for (list_child = cell->child_cells; list_child != NULL; list_child = list_child->next) {
|
||||
@ -164,7 +164,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
||||
|
||||
/* generate translation scope */
|
||||
g_string_printf(buffer, "\\begin{scope}[shift={(%lf pt,%lf pt)}]\n",
|
||||
((double)inst->origin.x)/1000.0,((double)inst->origin.y)/1000.0);
|
||||
((double)inst->origin.x)/scale,((double)inst->origin.y)/scale);
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
|
||||
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
|
||||
@ -174,7 +174,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
||||
inst->magnification);
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
|
||||
render_cell(inst->cell_ref, layer_infos, tex_file, buffer);
|
||||
render_cell(inst->cell_ref, layer_infos, tex_file, buffer, scale);
|
||||
|
||||
g_string_printf(buffer, "\\end{scope}\n");
|
||||
WRITEOUT_BUFFER(buffer);
|
||||
@ -188,7 +188,7 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
|
||||
|
||||
}
|
||||
|
||||
void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file)
|
||||
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale)
|
||||
{
|
||||
GString *working_line;
|
||||
|
||||
@ -219,7 +219,7 @@ void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_fi
|
||||
WRITEOUT_BUFFER(working_line);
|
||||
|
||||
/* Generate graphics output */
|
||||
render_cell(cell, layer_infos, tex_file, working_line);
|
||||
render_cell(cell, layer_infos, tex_file, working_line, scale);
|
||||
|
||||
|
||||
g_string_printf(working_line, "\\end{tikzpicture}\n");
|
||||
|
@ -27,6 +27,6 @@
|
||||
|
||||
#define LATEX_LINE_BUFFER_KB (10)
|
||||
|
||||
void render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file);
|
||||
void latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos, FILE *tex_file, double scale);
|
||||
|
||||
#endif /* __LATEX_OUTPUT_H__ */
|
||||
|
59
main.c
59
main.c
@ -24,6 +24,7 @@
|
||||
#include "tree-renderer/tree-store.h"
|
||||
#include "latex-output/latex-output.h"
|
||||
#include "widgets/conv-settings-dialog.h"
|
||||
#include "cairo-output/cairo-output.h"
|
||||
|
||||
struct open_button_data {
|
||||
GtkWindow *main_window;
|
||||
@ -161,22 +162,23 @@ end_destroy:
|
||||
|
||||
static void on_convert_clicked(gpointer button, gpointer user)
|
||||
{
|
||||
static struct render_settings sett = {
|
||||
.scale = 1000.0f,
|
||||
.renderer = RENDERER_LATEX_TIKZ,
|
||||
};
|
||||
struct convert_button_data *data = (struct convert_button_data *)user;
|
||||
GtkTreeSelection *selection;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel *model;
|
||||
GList *layer_list;
|
||||
struct gds_cell *cell_to_render;
|
||||
FILE *tex_file;
|
||||
FILE *output_file;
|
||||
GtkWidget *dialog;
|
||||
RendererSettingsDialog *settings;
|
||||
GtkFileFilter *filter;
|
||||
gint res;
|
||||
char *file_name;
|
||||
|
||||
settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window));
|
||||
gtk_dialog_run(GTK_DIALOG(settings));
|
||||
gtk_widget_destroy(GTK_WIDGET(settings));
|
||||
|
||||
/* Get selected cell */
|
||||
selection = gtk_tree_view_get_selection(data->tree_view);
|
||||
if (gtk_tree_selection_get_selected(selection, &model, &iter) == FALSE)
|
||||
@ -190,21 +192,56 @@ static void on_convert_clicked(gpointer button, gpointer user)
|
||||
/* Get layers that are rendered */
|
||||
layer_list = export_rendered_layer_info();
|
||||
|
||||
settings = renderer_settings_dialog_new(GTK_WINDOW(data->main_window));
|
||||
renderer_settings_dialog_set_settings(settings, &sett);
|
||||
res = gtk_dialog_run(GTK_DIALOG(settings));
|
||||
if (res == GTK_RESPONSE_OK) {
|
||||
renderer_settings_dialog_get_settings(settings, &sett);
|
||||
gtk_widget_destroy(GTK_WIDGET(settings));
|
||||
} else {
|
||||
gtk_widget_destroy(GTK_WIDGET(settings));
|
||||
goto ret_layer_destroy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* save file dialog */
|
||||
dialog = gtk_file_chooser_dialog_new("Save TeX File", GTK_WINDOW(data->main_window), GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
dialog = gtk_file_chooser_dialog_new((sett.renderer == RENDERER_LATEX_TIKZ
|
||||
? "Save LaTeX File" : "Save PDF"),
|
||||
GTK_WINDOW(data->main_window), GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"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) {
|
||||
gtk_file_filter_add_pattern(filter, "*.tex");
|
||||
gtk_file_filter_set_name(filter, "LaTeX-Files");
|
||||
} else {
|
||||
gtk_file_filter_add_pattern(filter, "*.pdf");
|
||||
gtk_file_filter_set_name(filter, "PDF-Files");
|
||||
}
|
||||
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter);
|
||||
|
||||
res = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
if (res == GTK_RESPONSE_ACCEPT) {
|
||||
file_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
tex_file = fopen(file_name, "w");
|
||||
g_free(file_name);
|
||||
gtk_widget_destroy(dialog);
|
||||
render_cell_to_code(cell_to_render, layer_list, tex_file);
|
||||
fclose(tex_file);
|
||||
|
||||
switch (sett.renderer) {
|
||||
case RENDERER_LATEX_TIKZ:
|
||||
output_file = fopen(file_name, "w");
|
||||
latex_render_cell_to_code(cell_to_render, layer_list, output_file, sett.scale);
|
||||
fclose(output_file);
|
||||
break;
|
||||
case RENDERER_CAIROGRAPHICS:
|
||||
cairo_render_cell_to_pdf(cell_to_render, layer_list, file_name, sett.scale);
|
||||
break;
|
||||
}
|
||||
g_free(file_name);
|
||||
|
||||
} else {
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
ret_layer_destroy:
|
||||
g_list_free_full(layer_list, (GDestroyNotify)delete_layer_info_struct);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@
|
||||
struct _RendererSettingsDialog {
|
||||
GtkDialog parent;
|
||||
/* Private loot */
|
||||
GtkWidget *radio_latex; // Only Latex-radio. Other one is implicit
|
||||
GtkWidget *radio_latex;
|
||||
GtkWidget *radio_cairo;
|
||||
GtkWidget *scale;
|
||||
};
|
||||
|
||||
@ -48,9 +49,12 @@ 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->scale = GTK_WIDGET(gtk_builder_get_object(builder, "dialog-scale"));
|
||||
gtk_dialog_add_buttons(dialog, "Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL);
|
||||
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dialog)), box);
|
||||
gtk_window_set_title(GTK_WINDOW(self), "Renderer Settings");
|
||||
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
@ -65,11 +69,25 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
|
||||
return res;
|
||||
}
|
||||
|
||||
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
|
||||
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
|
||||
{
|
||||
if (!settings)
|
||||
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);
|
||||
}
|
||||
void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struct render_settings *settings);
|
||||
void renderer_settings_dialog_set_settings(RendererSettingsDialog *dialog, struct render_settings *settings)
|
||||
{
|
||||
if (!settings || !dialog)
|
||||
return;
|
||||
gtk_range_set_value(GTK_RANGE(dialog->scale), settings->scale);
|
||||
|
||||
switch (settings->renderer) {
|
||||
case RENDERER_LATEX_TIKZ:
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_latex), TRUE);
|
||||
break;
|
||||
case RENDERER_CAIROGRAPHICS:
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo), TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user